Prototype an example fork subclass
This commit is contained in:
parent
84ccfc5966
commit
637b56fa4c
|
@ -8,3 +8,4 @@ type
|
||||||
Block* = ref object of RootObj
|
Block* = ref object of RootObj
|
||||||
header*: Header
|
header*: Header
|
||||||
uncles*: CountableList[Header]
|
uncles*: CountableList[Header]
|
||||||
|
blockNumber*: Int256
|
||||||
|
|
|
@ -173,14 +173,14 @@ const
|
||||||
GASLIMITADJUSTMENTFACTOR = 1024
|
GASLIMITADJUSTMENTFACTOR = 1024
|
||||||
GASLIMITMINIMUM = 5000
|
GASLIMITMINIMUM = 5000
|
||||||
# GASLIMITMAXIMUM = 2 ^ 63 - 1
|
# GASLIMITMAXIMUM = 2 ^ 63 - 1
|
||||||
GASLIMITUSAGEADJUSTMENTNUMERATOR = 3
|
GAS_LIMIT_USAGE_ADJUSTMENT_NUMERATOR* = 3.Int256
|
||||||
GASLIMITUSAGEADJUSTMENTDENOMINATOR = 2
|
GAS_LIMIT_USAGE_ADJUSTMENT_DENOMINATOR* = 2.Int256
|
||||||
DIFFICULTYADJUSTMENTDENOMINATOR = 2048
|
DIFFICULTY_ADJUSTMENT_DENOMINATOR* = 2_048.Int256
|
||||||
DIFFICULTYMINIMUM = 131072
|
DIFFICULTY_MINIMUM* = 131_072.Int256
|
||||||
BOMBEXPONENTIALPERIOD = 100000
|
BOMB_EXPONENTIAL_PERIOD* = 100_000.Int256
|
||||||
# BOMBEXPONENTIALFREEPERIODS = 2
|
BOMB_EXPONENTIAL_FREE_PERIODS* = 2.Int256
|
||||||
# BLOCKREWARD = 5 * denoms.ether
|
BLOCK_REWARD* = 5.Int256 * 2.Int256 # denoms.ether
|
||||||
UNCLEDEPTHPENALTYFACTOR = 8
|
UNCLE_DEPTH_PENALTY_FACTOR* = 8.Int256
|
||||||
MAXUNCLEDEPTH = 6
|
MAXUNCLEDEPTH = 6
|
||||||
MAXUNCLES = 2
|
MAXUNCLES = 2
|
||||||
# SECPK1P = 2 ^ 256 - 2 ^ 32 - 977
|
# SECPK1P = 2 ^ 256 - 2 ^ 32 - 977
|
||||||
|
@ -192,8 +192,8 @@ const
|
||||||
SECPK1G = (SECPK1Gx, SECPK1Gy)
|
SECPK1G = (SECPK1Gx, SECPK1Gy)
|
||||||
EMPTYUNCLEHASH = cstring"\x1d\xccM\xe8\xde\xc7]z\xab\x85\xb5g\xb6\xcc\xd4\x1a\xd3\x12E\x1b\x94\x8at\x13\xf0\xa1B\xfd@\xd4\x93G"
|
EMPTYUNCLEHASH = cstring"\x1d\xccM\xe8\xde\xc7]z\xab\x85\xb5g\xb6\xcc\xd4\x1a\xd3\x12E\x1b\x94\x8at\x13\xf0\xa1B\xfd@\xd4\x93G"
|
||||||
GENESIS_BLOCK_NUMBER* = 0.Int256
|
GENESIS_BLOCK_NUMBER* = 0.Int256
|
||||||
GENESIS_DIFFICULTY* = 131072.Int256
|
GENESIS_DIFFICULTY* = 131_072.Int256
|
||||||
GENESIS_GAS_LIMIT* = 3141592.Int256
|
GENESIS_GAS_LIMIT* = 3_141_592.Int256
|
||||||
GENESIS_PARENT_HASH* = ZERO_HASH32
|
GENESIS_PARENT_HASH* = ZERO_HASH32
|
||||||
GENESIS_COINBASE* = ZERO_ADDRESS
|
GENESIS_COINBASE* = ZERO_ADDRESS
|
||||||
GENESIS_NONCE* = cstring"\x00\x00\x00\x00\x00\x00\x00B"
|
GENESIS_NONCE* = cstring"\x00\x00\x00\x00\x00\x00\x00B"
|
||||||
|
|
|
@ -30,3 +30,7 @@ proc validate*(t: BaseTransaction) =
|
||||||
if t.intrinsic_gas() > t.gas:
|
if t.intrinsic_gas() > t.gas:
|
||||||
raise newException(ValidationError, "Insufficient gas")
|
raise newException(ValidationError, "Insufficient gas")
|
||||||
# self.check_signature_validity()
|
# self.check_signature_validity()
|
||||||
|
|
||||||
|
proc sender*(t: BaseTransaction): cstring =
|
||||||
|
# TODO
|
||||||
|
cstring""
|
|
@ -1,5 +1,10 @@
|
||||||
|
import ../constants
|
||||||
|
|
||||||
type
|
type
|
||||||
Header* = ref object
|
Header* = ref object
|
||||||
|
timestamp*: int
|
||||||
|
difficulty*: Int256
|
||||||
|
blockNumber*: Int256
|
||||||
# TODO
|
# TODO
|
||||||
|
|
||||||
proc generateHeaderFromParentHeader*(
|
proc generateHeaderFromParentHeader*(
|
||||||
|
@ -35,3 +40,15 @@ proc generateHeaderFromParentHeader*(
|
||||||
# )
|
# )
|
||||||
|
|
||||||
# return header
|
# return header
|
||||||
|
|
||||||
|
proc computeGasLimit*(header: Header, gasLimitFloor: Int256): Int256 =
|
||||||
|
# TODO
|
||||||
|
gasLimitFloor
|
||||||
|
|
||||||
|
proc gasUsed*(header: Header): Int256 =
|
||||||
|
# TODO
|
||||||
|
0.Int256
|
||||||
|
|
||||||
|
proc gasLimit*(header: Header): Int256 =
|
||||||
|
# TODO
|
||||||
|
0.Int256
|
||||||
|
|
|
@ -13,6 +13,16 @@ proc validateCanonicalAddress*(value: cstring, title: string = "Value") =
|
||||||
|
|
||||||
|
|
||||||
proc validateGte*(value: Int256, minimum: int, title: string = "Value") =
|
proc validateGte*(value: Int256, minimum: int, title: string = "Value") =
|
||||||
|
if value <= minimum.Int256:
|
||||||
|
raise newException(ValidationError,
|
||||||
|
fmt"{title} {value} is not greater than or equal to {minimum}")
|
||||||
|
|
||||||
|
proc validateGt*(value: Int256, minimum: int, title: string = "Value") =
|
||||||
if value < minimum.Int256:
|
if value < minimum.Int256:
|
||||||
raise newException(ValidationError,
|
raise newException(ValidationError,
|
||||||
fmt"{title} {value} is not greater than or equal to {minimum}")
|
fmt"{title} {value} is not greater than or equal to {minimum}")
|
||||||
|
|
||||||
|
proc validateGt*(value: int, minimum: int, title: string = "Value") =
|
||||||
|
if value < minimum:
|
||||||
|
raise newException(ValidationError,
|
||||||
|
fmt"{title} {value} is not greater than or equal to {minimum}")
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import
|
import
|
||||||
../logging, ../constants, ../errors, ../transaction, ../computation, "../block", ../vm_state, ../db/chain, ../utils/db, ../utils/header
|
../logging, ../constants, ../errors, ../transaction, ../computation, "../block", ../vm_state, ../vm_state_transactions, ../db/chain, ../utils/header
|
||||||
|
|
||||||
type
|
type
|
||||||
VM* = ref object of RootObj
|
VM* = ref object of RootObj
|
||||||
|
@ -11,38 +11,26 @@ type
|
||||||
chainDB*: BaseChainDB
|
chainDB*: BaseChainDB
|
||||||
isStateless*: bool
|
isStateless*: bool
|
||||||
state*: BaseVMState
|
state*: BaseVMState
|
||||||
|
`block`*: Block
|
||||||
|
|
||||||
proc newVM*(header: Header, chainDB: BaseChainDB): VM =
|
proc newVM*(header: Header, chainDB: BaseChainDB): VM =
|
||||||
new(result)
|
new(result)
|
||||||
result.chainDB = chainDB
|
result.chainDB = chainDB
|
||||||
|
|
||||||
|
method name*(vm: VM): string =
|
||||||
|
"VM"
|
||||||
|
|
||||||
method addTransaction*(vm: var VM, transaction: BaseTransaction, computation: BaseComputation): Block =
|
method addTransaction*(vm: var VM, transaction: BaseTransaction, computation: BaseComputation): Block =
|
||||||
# Add a transaction to the given block and save the block data into chaindb
|
# Add a transaction to the given block and save the block data into chaindb
|
||||||
var receipt = self.state.makeReceipt(transaction, computation)
|
# var receipt = vm.state.makeReceipt(transaction, computation)
|
||||||
var transactionIdx = len(vm.`block`.transactions)
|
# var transactionIdx = len(vm.`block`.transactions)
|
||||||
|
# TODO
|
||||||
return Block()
|
return Block()
|
||||||
# var indexKey = rlp.encode(transaction_idx, sedes=rlp.sedes.big_endian_int)
|
|
||||||
|
|
||||||
# self.block.transactions.append(transaction)
|
|
||||||
|
|
||||||
# tx_root_hash = self.chaindb.add_transaction(self.block.header, index_key, transaction)
|
|
||||||
# receipt_root_hash = self.chaindb.add_receipt(self.block.header, index_key, receipt)
|
|
||||||
|
|
||||||
# self.block.bloom_filter |= receipt.bloom
|
|
||||||
|
|
||||||
# self.block.header.transaction_root = tx_root_hash
|
|
||||||
# self.block.header.receipt_root = receipt_root_hash
|
|
||||||
# self.block.header.bloom = int(self.block.bloom_filter)
|
|
||||||
# self.block.header.gas_used = receipt.gas_used
|
|
||||||
|
|
||||||
# return self.block
|
|
||||||
|
|
||||||
method applyTransaction*(vm: var VM, transaction: BaseTransaction): (BaseComputation, Block) =
|
method applyTransaction*(vm: var VM, transaction: BaseTransaction): (BaseComputation, Block) =
|
||||||
# Apply the transaction to the vm in the current block
|
# Apply the transaction to the vm in the current block
|
||||||
if vm.isStateless:
|
if vm.isStateless:
|
||||||
var (computation, b, trieData) = vm.state.applyTransaction(
|
var (computation, b, trieData) = vm.state.applyTransaction(
|
||||||
vm.state,
|
|
||||||
transaction,
|
transaction,
|
||||||
vm.`block`,
|
vm.`block`,
|
||||||
isStateless=true)
|
isStateless=true)
|
||||||
|
@ -51,11 +39,10 @@ method applyTransaction*(vm: var VM, transaction: BaseTransaction): (BaseComputa
|
||||||
# Persist changed transaction and receipt key-values to self.chaindb.
|
# Persist changed transaction and receipt key-values to self.chaindb.
|
||||||
else:
|
else:
|
||||||
var (computation, _, _) = vm.state.applyTransaction(
|
var (computation, _, _) = vm.state.applyTransaction(
|
||||||
vm.state,
|
|
||||||
transaction,
|
transaction,
|
||||||
vm.`block`,
|
vm.`block`,
|
||||||
isStateless=false)
|
isStateless=false)
|
||||||
vm.addTransaction(transaction, computation)
|
discard vm.addTransaction(transaction, computation)
|
||||||
|
|
||||||
result = (computation, vm.`block`)
|
result = (computation, vm.`block`)
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,54 @@
|
||||||
|
import
|
||||||
|
logging, constants, errors, transaction, "block", utils/header
|
||||||
|
|
||||||
|
type
|
||||||
|
FrontierBlock* = object of Block
|
||||||
|
# bloomFilter*: BloomFilter
|
||||||
|
# header*: BlockHeader
|
||||||
|
transactions*: seq[BaseTransaction]
|
||||||
|
# transactionClass*: Any
|
||||||
|
stateRoot*: cstring
|
||||||
|
# fields*: seq[(string, Function)]
|
||||||
|
# cachedRlp: cstring
|
||||||
|
# uncles*: void
|
||||||
|
|
||||||
|
# import
|
||||||
|
# rlp, rlp.sedes, eth_bloom, evm.constants, evm.rlp.receipts, evm.rlp.blocks,
|
||||||
|
# evm.rlp.headers, evm.utils.keccak, transactions
|
||||||
|
|
||||||
|
# method makeFrontierBlock*(header: auto; transactions: auto; uncles: void): auto =
|
||||||
|
# if transactions is None:
|
||||||
|
# transactions = @[]
|
||||||
|
# if uncles is None:
|
||||||
|
# uncles = @[]
|
||||||
|
# result.bloomFilter = BloomFilter(header.bloom)
|
||||||
|
# super(FrontierBlock, result).__init__()
|
||||||
|
|
||||||
|
# method number*(self: FrontierBlock): int =
|
||||||
|
# return self.header.blockNumber
|
||||||
|
|
||||||
|
# method hash*(self: FrontierBlock): cstring =
|
||||||
|
# return self.header.hash
|
||||||
|
|
||||||
|
# method getTransactionClass*(cls: typedesc): typedesc =
|
||||||
|
# return cls.transactionClass
|
||||||
|
|
||||||
|
# method getReceipts*(self: FrontierBlock; chaindb: BaseChainDB): seq[Receipt] =
|
||||||
|
# return chaindb.getReceipts(self.header, Receipt)
|
||||||
|
|
||||||
|
# method fromHeader*(cls: typedesc; header: BlockHeader; chaindb: BaseChainDB): FrontierBlock =
|
||||||
|
# ## Returns the block denoted by the given block header.
|
||||||
|
# if header.unclesHash == EMPTYUNCLEHASH:
|
||||||
|
# var uncles = @[]
|
||||||
|
# else:
|
||||||
|
# uncles = chaindb.getBlockUncles(header.unclesHash)
|
||||||
|
# var transactions = chaindb.getBlockTransactions(header, cls.getTransactionClass())
|
||||||
|
# return cls()
|
||||||
|
|
||||||
|
# proc makeFrontierBlock*(): FrontierBlock =
|
||||||
|
# result.transactionClass = FrontierTransaction
|
||||||
|
# result.fields = @[("header", BlockHeader),
|
||||||
|
# ("transactions", CountableList(transactionClass)),
|
||||||
|
# ("uncles", CountableList(BlockHeader))]
|
||||||
|
# result.bloomFilter = nil
|
||||||
|
|
|
@ -0,0 +1,21 @@
|
||||||
|
import
|
||||||
|
logging, constants, errors, validation, utils/header, vm / forks / frontier / vm
|
||||||
|
|
||||||
|
method computeDifficulty*(parentHeader: Header, timestamp: int): Int256 =
|
||||||
|
validateGt(timestamp, parentHeader.timestamp, title="Header timestamp")
|
||||||
|
let offset = parentHeader.difficulty div DIFFICULTY_ADJUSTMENT_DENOMINATOR
|
||||||
|
# We set the minimum to the lowest of the protocol minimum and the parent
|
||||||
|
# minimum to allow for the initial frontier *warming* period during which
|
||||||
|
# the difficulty begins lower than the protocol minimum
|
||||||
|
let difficultyMinimum = min(parentHeader.difficulty, DIFFICULTY_MINIMUM)
|
||||||
|
# let test = (timestamp - parentHeader.timestamp).Int256 < FRONTIER_DIFFICULTY_ADJUSTMENT_CUTOFF
|
||||||
|
# let baseDifficulty = max(parent.Header.difficulty + (if test: offset else: -offset), difficultyMinimum)
|
||||||
|
# # Adjust for difficulty bomb
|
||||||
|
# let numBombPeriods = ((parentHeader.blockNumber + 1) div BOMB_EXPONENTIAL_PERIOD) - BOMB_EXPONENTIAL_FREE_PERIODS
|
||||||
|
# result = if numBombPeriods >= 0: max(baseDifficulty + 2.Int256 ^ numBombPeriods, DIFFICULTY_MINIMUM) else: baseDifficulty
|
||||||
|
result = 0.Int256
|
||||||
|
|
||||||
|
method createHeaderFromParent*(parentHeader: Header): Header =
|
||||||
|
# TODO
|
||||||
|
result = Header()
|
||||||
|
|
|
@ -0,0 +1,24 @@
|
||||||
|
import
|
||||||
|
strformat,
|
||||||
|
constants, errors, vm_state, transaction, utils/header
|
||||||
|
|
||||||
|
proc validateFrontierTransaction*(vmState: BaseVmState, transaction: BaseTransaction) =
|
||||||
|
let gasCost = transaction.gas * transaction.gasPrice
|
||||||
|
var senderBalance: Int256
|
||||||
|
# inDB(vmState.stateDB(readOnly=true):
|
||||||
|
# senderBalance = db.getBalance(transaction.sender)
|
||||||
|
senderBalance = gasCost # TODO
|
||||||
|
if senderBalance < gasCost:
|
||||||
|
raise newException(ValidationError, %"Sender account balance cannot afford txn gas: {transaction.sender}")
|
||||||
|
|
||||||
|
let totalCost = transaction.value + gasCost
|
||||||
|
|
||||||
|
if senderBalance < totalCost:
|
||||||
|
raise newException(ValidationError, "Sender account balance cannot afford txn")
|
||||||
|
|
||||||
|
if vmState.blockHeader.gasUsed + transaction.gas > vmState.blockHeader.gasLimit:
|
||||||
|
raise newException(ValidationError, "Transaction exceeds gas limit")
|
||||||
|
|
||||||
|
# inDB(vmState.stateDb(readOnly=true):
|
||||||
|
# if db.getNonce(transaction.sender) != transaction.nonce:
|
||||||
|
# raise newException(ValidationError, "Invalid transaction nonce")
|
|
@ -0,0 +1,155 @@
|
||||||
|
import
|
||||||
|
logging, constants, errors, vm_state, utils/header, db/chain
|
||||||
|
|
||||||
|
type
|
||||||
|
FrontierVMState* = object of BaseVMState
|
||||||
|
# receipts*:
|
||||||
|
# computationClass*: Any
|
||||||
|
# accessLogs*: AccessLogs
|
||||||
|
|
||||||
|
# import
|
||||||
|
# py2nim_helpers, __future__, rlp, evm, evm.constants, evm.exceptions, evm.rlp.logs,
|
||||||
|
# evm.rlp.receipts, evm.vm.message, evm.vm_state, evm.utils.address,
|
||||||
|
# evm.utils.hexadecimal, evm.utils.keccak, evm.validation, computation, constants,
|
||||||
|
# validation
|
||||||
|
|
||||||
|
# type
|
||||||
|
# FrontierVMState* = object of Function
|
||||||
|
# prevHeaders*: seq[BlockHeader]
|
||||||
|
# receipts*: void
|
||||||
|
# computationClass*: Any
|
||||||
|
# _chaindb*: BaseChainDB
|
||||||
|
# accessLogs*: AccessLogs
|
||||||
|
# blockHeader*: BlockHeader
|
||||||
|
|
||||||
|
# proc _executeFrontierTransaction*(vmState: FrontierVMState;
|
||||||
|
# transaction: FrontierTransaction): FrontierComputation =
|
||||||
|
# transaction.validate()
|
||||||
|
# validateFrontierTransaction(vmState, transaction)
|
||||||
|
# var gasFee = transaction.gas * transaction.gasPrice
|
||||||
|
# with vmState.stateDb(),
|
||||||
|
# stateDb.deltaBalance(transaction.sender, -1 * gasFee)
|
||||||
|
# stateDb.incrementNonce(transaction.sender)
|
||||||
|
# var messageGas = transaction.gas - transaction.intrinsicGas
|
||||||
|
# if transaction.to == constants.CREATECONTRACTADDRESS:
|
||||||
|
# var
|
||||||
|
# contractAddress = generateContractAddress(transaction.sender,
|
||||||
|
# stateDb.getNonce(transaction.sender) - 1)
|
||||||
|
# data = cstring""
|
||||||
|
# code = transaction.data
|
||||||
|
# else:
|
||||||
|
# contractAddress = None
|
||||||
|
# data = transaction.data
|
||||||
|
# code = stateDb.getCode(transaction.to)
|
||||||
|
# vmState.logger.info("TRANSACTION: sender: %s | to: %s | value: %s | gas: %s | gas-price: %s | s: %s | r: %s | v: %s | data-hash: %s",
|
||||||
|
# encodeHex(transaction.sender), encodeHex(transaction.to),
|
||||||
|
# transaction.value, transaction.gas, transaction.gasPrice,
|
||||||
|
# transaction.s, transaction.r, transaction.v,
|
||||||
|
# encodeHex(keccak(transaction.data)))
|
||||||
|
# var message = Message()
|
||||||
|
# if message.isCreate:
|
||||||
|
# with vmState.stateDb(),
|
||||||
|
# var isCollision = stateDb.accountHasCodeOrNonce(contractAddress)
|
||||||
|
# if isCollision:
|
||||||
|
# var computation = vmState.getComputation(message)
|
||||||
|
# computation._error = ContractCreationCollision("Address collision while creating contract: {0}".format(
|
||||||
|
# encodeHex(contractAddress)))
|
||||||
|
# vmState.logger.debug("Address collision while creating contract: %s",
|
||||||
|
# encodeHex(contractAddress))
|
||||||
|
# else:
|
||||||
|
# computation = vmState.getComputation(message).applyCreateMessage()
|
||||||
|
# else:
|
||||||
|
# computation = vmState.getComputation(message).applyMessage()
|
||||||
|
# var numDeletions = len(computation.getAccountsForDeletion())
|
||||||
|
# if numDeletions:
|
||||||
|
# computation.gasMeter.refundGas(REFUNDSELFDESTRUCT * numDeletions)
|
||||||
|
# var
|
||||||
|
# gasRemaining = computation.getGasRemaining()
|
||||||
|
# gasRefunded = computation.getGasRefund()
|
||||||
|
# gasUsed = transaction.gas - gasRemaining
|
||||||
|
# gasRefund = min(gasRefunded, gasUsed div 2)
|
||||||
|
# gasRefundAmount = gasRefund + gasRemaining * transaction.gasPrice
|
||||||
|
# if gasRefundAmount:
|
||||||
|
# vmState.logger.debug("TRANSACTION REFUND: %s -> %s", gasRefundAmount,
|
||||||
|
# encodeHex(message.sender))
|
||||||
|
# with vmState.stateDb(),
|
||||||
|
# stateDb.deltaBalance(message.sender, gasRefundAmount)
|
||||||
|
# var transactionFee = transaction.gas - gasRemaining - gasRefund *
|
||||||
|
# transaction.gasPrice
|
||||||
|
# vmState.logger.debug("TRANSACTION FEE: %s -> %s", transactionFee,
|
||||||
|
# encodeHex(vmState.coinbase))
|
||||||
|
# with vmState.stateDb(),
|
||||||
|
# stateDb.deltaBalance(vmState.coinbase, transactionFee)
|
||||||
|
# with vmState.stateDb(),
|
||||||
|
# for account, beneficiary in computation.getAccountsForDeletion():
|
||||||
|
# vmState.logger.debug("DELETING ACCOUNT: %s", encodeHex(account))
|
||||||
|
# stateDb.setBalance(account, 0)
|
||||||
|
# stateDb.deleteAccount(account)
|
||||||
|
# return computation
|
||||||
|
|
||||||
|
# proc _makeFrontierReceipt*(vmState: FrontierVMState;
|
||||||
|
# transaction: FrontierTransaction;
|
||||||
|
# computation: FrontierComputation): Receipt =
|
||||||
|
# var
|
||||||
|
# logs = ## py2nim can't generate code for
|
||||||
|
# ## Log(address, topics, data)
|
||||||
|
# gasRemaining = computation.getGasRemaining()
|
||||||
|
# gasRefund = computation.getGasRefund()
|
||||||
|
# txGasUsed = transaction.gas - gasRemaining -
|
||||||
|
# min(gasRefund, transaction.gas - gasRemaining div 2)
|
||||||
|
# gasUsed = vmState.blockHeader.gasUsed + txGasUsed
|
||||||
|
# receipt = Receipt()
|
||||||
|
# return receipt
|
||||||
|
|
||||||
|
# method executeTransaction*(self: FrontierVMState; transaction: FrontierTransaction): (
|
||||||
|
# , ) =
|
||||||
|
# var computation = _executeFrontierTransaction(self, transaction)
|
||||||
|
# return (computation, self.blockHeader)
|
||||||
|
|
||||||
|
# method makeReceipt*(self: FrontierVMState; transaction: FrontierTransaction;
|
||||||
|
# computation: FrontierComputation): Receipt =
|
||||||
|
# var receipt = _makeFrontierReceipt(self, transaction, computation)
|
||||||
|
# return receipt
|
||||||
|
|
||||||
|
# method validateBlock*(self: FrontierVMState; block: FrontierBlock): void =
|
||||||
|
# if notblock.isGenesis:
|
||||||
|
# var parentHeader = self.parentHeader
|
||||||
|
# self._validateGasLimit(block)
|
||||||
|
# validateLengthLte(block.header.extraData, 32)
|
||||||
|
# if block.header.timestamp < parentHeader.timestamp:
|
||||||
|
# raise newException(ValidationError, "`timestamp` is before the parent block\'s timestamp.\\n- block : {0}\\n- parent : {1}. ".format(
|
||||||
|
# block.header.timestamp, parentHeader.timestamp))
|
||||||
|
# elif block.header.timestamp == parentHeader.timestamp:
|
||||||
|
# raise ValidationError("`timestamp` is equal to the parent block\'s timestamp\\n- block : {0}\\n- parent: {1}. ".format(
|
||||||
|
# block.header.timestamp, parentHeader.timestamp))
|
||||||
|
# if len(block.uncles) > MAXUNCLES:
|
||||||
|
# raise newException(ValidationError, "Blocks may have a maximum of {0} uncles. Found {1}.".format(
|
||||||
|
# MAXUNCLES, len(block.uncles)))
|
||||||
|
# for uncle in block.uncles:
|
||||||
|
# self.validateUncle(block, uncle)
|
||||||
|
# if notself.isKeyExists(block.header.stateRoot):
|
||||||
|
# raise newException(ValidationError, "`state_root` was not found in the db.\\n- state_root: {0}".format(
|
||||||
|
# block.header.stateRoot))
|
||||||
|
# var localUncleHash = keccak(rlp.encode(block.uncles))
|
||||||
|
# if localUncleHash != block.header.unclesHash:
|
||||||
|
# raise newException(ValidationError, "`uncles_hash` and block `uncles` do not match.\\n - num_uncles : {0}\\n - block uncle_hash : {1}\\n - header uncle_hash: {2}".format(
|
||||||
|
# len(block.uncles), localUncleHash, block.header.uncleHash))
|
||||||
|
|
||||||
|
# method _validateGasLimit*(self: FrontierVMState; block: FrontierBlock): void =
|
||||||
|
# var gasLimit = block.header.gasLimit
|
||||||
|
# if gasLimit < GASLIMITMINIMUM:
|
||||||
|
# raise newException(ValidationError, "Gas limit {0} is below minimum {1}".format(
|
||||||
|
# gasLimit, GASLIMITMINIMUM))
|
||||||
|
# if gasLimit > GASLIMITMAXIMUM:
|
||||||
|
# raise newException(ValidationError, "Gas limit {0} is above maximum {1}".format(
|
||||||
|
# gasLimit, GASLIMITMAXIMUM))
|
||||||
|
# var
|
||||||
|
# parentGasLimit = self.parentHeader.gasLimit
|
||||||
|
# diff = gasLimit - parentGasLimit
|
||||||
|
# if diff > parentGasLimit // GASLIMITADJUSTMENTFACTOR:
|
||||||
|
# raise newException(ValidationError, "Gas limit {0} difference to parent {1} is too big {2}".format(
|
||||||
|
# gasLimit, parentGasLimit, diff))
|
||||||
|
|
||||||
|
# proc makeFrontierVMState*(): FrontierVMState =
|
||||||
|
# result.computationClass = FrontierComputation
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
p:"../../../"
|
|
@ -0,0 +1,25 @@
|
||||||
|
import
|
||||||
|
logging, constants, errors, "block", vm / [base, stack], db / chain, utils / header,
|
||||||
|
frontier_block, frontier_vm_state, frontier_validation
|
||||||
|
|
||||||
|
|
||||||
|
type
|
||||||
|
FrontierVM* = ref object of VM
|
||||||
|
|
||||||
|
method name*(vm: FrontierVM): string =
|
||||||
|
"FrontierVM"
|
||||||
|
|
||||||
|
method getBlockReward(vm: FrontierVM): Int256 =
|
||||||
|
BLOCK_REWARD
|
||||||
|
|
||||||
|
method getetUncleReward(vm: FrontierVM, blockNumber: Int256, uncle: Block): Int256 =
|
||||||
|
BLOCK_REWARD * (UNCLE_DEPTH_PENALTY_FACTOR + uncle.blockNumber - blockNumber) div UNCLE_DEPTH_PENALTY_FACTOR
|
||||||
|
|
||||||
|
|
||||||
|
method getNephewReward(vm: FrontierVM): Int256 =
|
||||||
|
vm.getBlockReward() div 32
|
||||||
|
|
||||||
|
proc newFrontierVM*(header: Header, chainDB: BaseChainDB): FrontierVM =
|
||||||
|
new(result)
|
||||||
|
result.chainDB = chainDB
|
||||||
|
result.isStateless = true
|
Loading…
Reference in New Issue