make macro_assembler to use the same testEvmCall
it also allow the macro_assembler to write more test of CALL and CREATE family which previously not possible
This commit is contained in:
parent
71273f2f4c
commit
d93a8bc4a1
|
@ -8,9 +8,9 @@
|
|||
|
||||
import
|
||||
eth/common/eth_types, stint, options, stew/byteutils,
|
||||
".."/[vm_types, vm_state, vm_internals, vm_gas_costs, forks],
|
||||
".."/[vm_types, vm_state, vm_gas_costs, forks],
|
||||
".."/[db/db_chain, db/accounts_cache, transaction], eth/trie/db,
|
||||
".."/[chain_config, utils, rpc/hexstrings],
|
||||
".."/[chain_config, rpc/hexstrings],
|
||||
./call_common
|
||||
|
||||
type
|
||||
|
@ -128,65 +128,6 @@ proc txCallEvm*(tx: Transaction, sender: EthAddress, vmState: BaseVMState, fork:
|
|||
shallowCopy(call.accessList, tx.accessList)
|
||||
return runComputation(call).gasUsed
|
||||
|
||||
type
|
||||
AsmResult* = object
|
||||
isSuccess*: bool
|
||||
gasUsed*: GasInt
|
||||
output*: seq[byte]
|
||||
stack*: Stack
|
||||
memory*: Memory
|
||||
vmState*: BaseVMState
|
||||
contractAddress*: EthAddress
|
||||
|
||||
proc asmCallEvm*(blockNumber: Uint256, chainDB: BaseChainDB, code, data: seq[byte], fork: Fork): AsmResult =
|
||||
let
|
||||
parentNumber = blockNumber - 1
|
||||
parent = chainDB.getBlockHeader(parentNumber)
|
||||
header = chainDB.getBlockHeader(blockNumber)
|
||||
headerHash = header.blockHash
|
||||
body = chainDB.getBlockBody(headerHash)
|
||||
vmState = newBaseVMState(parent.stateRoot, header, chainDB)
|
||||
tx = body.transactions[0]
|
||||
sender = transaction.getSender(tx)
|
||||
gasLimit = 500000000
|
||||
gasUsed = 0 #tx.payload.intrinsicGas.GasInt + gasFees[fork][GasTXCreate]
|
||||
|
||||
# This is an odd sort of test, where some fields are taken from
|
||||
# `body.transactions[0]` but other fields (like `gasLimit`) are not. Also it
|
||||
# creates the new contract using `code` like `CREATE`, but then executes the
|
||||
# contract like it's `CALL`.
|
||||
|
||||
doAssert tx.contractCreation
|
||||
let contractAddress = generateAddress(sender, vmState.readOnlyStateDB.getNonce(sender))
|
||||
vmState.mutateStateDB:
|
||||
db.setCode(contractAddress, code)
|
||||
|
||||
let callResult = runComputation(CallParams(
|
||||
vmState: vmState,
|
||||
forkOverride: some(fork),
|
||||
gasPrice: tx.gasPrice,
|
||||
gasLimit: gasLimit - gasUsed,
|
||||
sender: sender,
|
||||
to: contractAddress,
|
||||
isCreate: false,
|
||||
value: tx.value,
|
||||
input: data,
|
||||
noIntrinsic: true, # Don't charge intrinsic gas.
|
||||
noAccessList: true, # Don't initialise EIP-2929 access list.
|
||||
noGasCharge: true, # Don't charge sender account for gas.
|
||||
noRefund: true # Don't apply gas refund/burn rule.
|
||||
))
|
||||
|
||||
# Some of these are extra returned state, for testing, that a normal EVMC API
|
||||
# computation doesn't return. We'll have to obtain them outside EVMC.
|
||||
result.isSuccess = not callResult.isError
|
||||
result.gasUsed = callResult.gasUsed
|
||||
result.output = callResult.output
|
||||
result.stack = callResult.stack
|
||||
result.memory = callResult.memory
|
||||
result.vmState = vmState
|
||||
result.contractAddress = contractAddress
|
||||
|
||||
proc testCallEvm*(tx: Transaction, sender: EthAddress, vmState: BaseVMState, fork: Fork): CallResult =
|
||||
var call = CallParams(
|
||||
vmState: vmState,
|
||||
|
|
|
@ -1,13 +1,15 @@
|
|||
import
|
||||
macrocache, strutils, sequtils, unittest2,
|
||||
stew/byteutils, chronicles, eth/common,
|
||||
macrocache, strutils, sequtils, unittest2, times,
|
||||
stew/byteutils, chronicles, eth/[common, keys],
|
||||
stew/shims/macros
|
||||
|
||||
import
|
||||
options, json, os, eth/trie/[db, hexary],
|
||||
options, eth/trie/[db, hexary],
|
||||
../nimbus/db/[db_chain, accounts_cache],
|
||||
../nimbus/vm_internals, ../nimbus/forks,
|
||||
../nimbus/transaction/call_evm
|
||||
../nimbus/transaction/call_evm,
|
||||
../nimbus/[transaction, chain_config, genesis, vm_types, vm_state],
|
||||
../nimbus/utils/difficulty
|
||||
|
||||
export byteutils
|
||||
{.experimental: "dynamicBindSym".}
|
||||
|
@ -178,8 +180,8 @@ proc parseGasUsed(gas: NimNode): GasInt =
|
|||
proc generateVMProxy(boa: Assembler): NimNode =
|
||||
let
|
||||
vmProxy = genSym(nskProc, "vmProxy")
|
||||
blockNumber = ident("blockNumber")
|
||||
chainDB = ident("chainDB")
|
||||
vmState = ident("vmState")
|
||||
title = boa.title
|
||||
body = newLitFixed(boa)
|
||||
|
||||
|
@ -187,34 +189,55 @@ proc generateVMProxy(boa: Assembler): NimNode =
|
|||
test `title`:
|
||||
proc `vmProxy`(): bool =
|
||||
let boa = `body`
|
||||
runVM(`blockNumber`, `chainDB`, boa)
|
||||
runVM(`vmState`, `chainDB`, boa)
|
||||
{.gcsafe.}:
|
||||
check `vmProxy`()
|
||||
|
||||
when defined(macro_assembler_debug):
|
||||
echo result.toStrLit.strVal
|
||||
|
||||
const
|
||||
blockFile = "tests" / "fixtures" / "PersistBlockTests" / "block47205.json"
|
||||
proc initDatabase*(networkId = MainNet): (BaseVMState, BaseChainDB) =
|
||||
let db = newBaseChainDB(newMemoryDB(), false, networkId, networkParams(networkId))
|
||||
initializeEmptyDb(db)
|
||||
|
||||
proc initDatabase*(): (Uint256, BaseChainDB) =
|
||||
let
|
||||
node = json.parseFile(blockFile)
|
||||
blockNumber = UInt256.fromHex(node["blockNumber"].getStr())
|
||||
memoryDB = newMemoryDB()
|
||||
state = node["state"]
|
||||
parent = getCanonicalHead(db)
|
||||
coinbase = hexToByteArray[20]("bb7b8287f3f0a933474a79eae42cbca977791171")
|
||||
timestamp = parent.timestamp + initDuration(seconds = 1)
|
||||
header = BlockHeader(
|
||||
blockNumber: 1.u256,
|
||||
stateRoot: parent.stateRoot,
|
||||
parentHash: parent.blockHash,
|
||||
coinbase: coinbase,
|
||||
timestamp: timestamp,
|
||||
difficulty: db.config.calcDifficulty(timestamp, parent),
|
||||
gasLimit: 100_000
|
||||
)
|
||||
vmState = newBaseVMState(parent.stateRoot, header, db)
|
||||
|
||||
for k, v in state:
|
||||
let key = hexToSeqByte(k)
|
||||
let value = hexToSeqByte(v.getStr())
|
||||
memoryDB.put(key, value)
|
||||
(vmState, db)
|
||||
|
||||
result = (blockNumber, newBaseChainDB(memoryDB, false))
|
||||
proc runVM*(vmState: BaseVMState, chainDB: BaseChainDB, boa: Assembler): bool =
|
||||
const codeAddress = hexToByteArray[20]("460121576cc7df020759730751f92bd62fd78dd6")
|
||||
let privateKey = PrivateKey.fromHex("7a28b5ba57c53603b0b07b56bba752f7784bf506fa95edc395f5cf6c7514fe9d")[]
|
||||
|
||||
proc runVM*(blockNumber: Uint256, chainDB: BaseChainDB, boa: Assembler): bool =
|
||||
var asmResult = asmCallEvm(blockNumber, chainDB, boa.code, boa.data, boa.fork)
|
||||
vmState.mutateStateDB:
|
||||
db.setCode(codeAddress, boa.code)
|
||||
db.setBalance(codeAddress, 1_000_000.u256)
|
||||
|
||||
if asmResult.isSuccess:
|
||||
let unsignedTx = Transaction(
|
||||
txType: TxLegacy,
|
||||
nonce: 0,
|
||||
gasPrice: 1.GasInt,
|
||||
gasLimit: 500_000_000.GasInt,
|
||||
to: codeAddress.some,
|
||||
value: 500.u256,
|
||||
payload: boa.data
|
||||
)
|
||||
let tx = signTransaction(unsignedTx, privateKey, chainDB.config.chainId, false)
|
||||
let asmResult = testCallEvm(tx, tx.getSender, vmState, boa.fork)
|
||||
|
||||
if not asmResult.isError:
|
||||
if boa.success == false:
|
||||
error "different success value", expected=boa.success, actual=true
|
||||
return false
|
||||
|
@ -253,11 +276,11 @@ proc runVM*(blockNumber: Uint256, chainDB: BaseChainDB, boa: Assembler): bool =
|
|||
error "different memory value", idx=i, expected=mem, actual=actual
|
||||
return false
|
||||
|
||||
var stateDB = asmResult.vmState.accountDb
|
||||
var stateDB = vmState.accountDb
|
||||
stateDB.persist()
|
||||
|
||||
var
|
||||
storageRoot = stateDB.getStorageRoot(asmResult.contractAddress)
|
||||
storageRoot = stateDB.getStorageRoot(codeAddress)
|
||||
trie = initSecureHexaryTrie(chainDB.db, storageRoot)
|
||||
|
||||
for kv in boa.storage:
|
||||
|
@ -271,7 +294,7 @@ proc runVM*(blockNumber: Uint256, chainDB: BaseChainDB, boa: Assembler): bool =
|
|||
error "storage has different value", key=key, expected=val, actual=value
|
||||
return false
|
||||
|
||||
let logs = asmResult.vmState.logEntries
|
||||
let logs = vmState.logEntries
|
||||
if logs.len != boa.logs.len:
|
||||
error "different logs len", expected=boa.logs.len, actual=logs.len
|
||||
return false
|
||||
|
|
|
@ -2,8 +2,7 @@ import macro_assembler, unittest2
|
|||
|
||||
proc opArithMain*() =
|
||||
suite "Arithmetic Opcodes":
|
||||
setup:
|
||||
let (blockNumber, chainDB) = initDatabase()
|
||||
let (vmState, chainDB) = initDatabase()
|
||||
|
||||
assembler:
|
||||
title: "ADD_1"
|
||||
|
@ -439,3 +438,6 @@ proc opArithMain*() =
|
|||
PUSH1 "0x0F"
|
||||
SIGNEXTEND
|
||||
stack: "0x000000000000000000000000000000003f9b347132d29b62d161117bca8c7307"
|
||||
|
||||
when isMainModule:
|
||||
opArithMain()
|
||||
|
|
|
@ -2,8 +2,7 @@ import macro_assembler, unittest2
|
|||
|
||||
proc opBitMain*() =
|
||||
suite "Bitwise Opcodes":
|
||||
setup:
|
||||
let (blockNumber, chainDB) = initDatabase()
|
||||
let (vmState, chainDB) = initDatabase()
|
||||
|
||||
assembler: # AND OP
|
||||
title: "AND_1"
|
||||
|
@ -655,3 +654,7 @@ proc opBitMain*() =
|
|||
PUSH1 "0x00"
|
||||
NOT
|
||||
stack: "0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
|
||||
|
||||
when isMainModule:
|
||||
opBitMain()
|
||||
|
||||
|
|
|
@ -4,8 +4,7 @@ import
|
|||
|
||||
proc opCustomMain*() =
|
||||
suite "Custom Opcodes Test":
|
||||
setup:
|
||||
let (blockNumber, chainDB) = initDatabase()
|
||||
let (vmState, chainDB) = initDatabase()
|
||||
|
||||
assembler: # CALLDATASIZE OP
|
||||
title: "CALLDATASIZE_1"
|
||||
|
@ -178,41 +177,41 @@ proc opCustomMain*() =
|
|||
title: "ADDRESS_1"
|
||||
code:
|
||||
Address
|
||||
stack: "0x000000000000000000000000c669eaad75042be84daaf9b461b0e868b9ac1871"
|
||||
stack: "0x000000000000000000000000460121576cc7df020759730751f92bd62fd78dd6"
|
||||
|
||||
assembler: # BALANCE OP
|
||||
title: "BALANCE_1"
|
||||
code:
|
||||
Address
|
||||
Balance
|
||||
stack: "0x000000000000000000000000000000000000000000000000cff56a1b273a8000"
|
||||
stack: "0x00000000000000000000000000000000000000000000000000000000000f4434"
|
||||
|
||||
assembler: # EIP2929 BALANCE OP
|
||||
title: "EIP2929 BALANCE_1"
|
||||
code:
|
||||
Address
|
||||
Balance
|
||||
stack: "0x000000000000000000000000000000000000000000000000cff56a1b273a8000"
|
||||
stack: "0x00000000000000000000000000000000000000000000000000000000000f4434"
|
||||
fork: berlin
|
||||
gasused: 2602
|
||||
gasused: 102
|
||||
|
||||
assembler: # ORIGIN OP
|
||||
title: "ORIGIN_1"
|
||||
code:
|
||||
Origin
|
||||
stack: "0x000000000000000000000000fbe0afcd7658ba86be41922059dd879c192d4c73"
|
||||
stack: "0x0000000000000000000000008aeeda4d805471df9b2a5b0f38a0c3bcba786b"
|
||||
|
||||
assembler: # CALLER OP
|
||||
title: "CALLER_1"
|
||||
code:
|
||||
Caller
|
||||
stack: "0x000000000000000000000000fbe0afcd7658ba86be41922059dd879c192d4c73"
|
||||
stack: "0x0000000000000000000000008aeeda4d805471df9b2a5b0f38a0c3bcba786b"
|
||||
|
||||
assembler: # CALLVALUE OP
|
||||
title: "CALLVALUE_1"
|
||||
code:
|
||||
CallValue
|
||||
stack: "0xcff56a1b273a8000"
|
||||
stack: "0x01f4"
|
||||
|
||||
assembler: # SHA3 OP
|
||||
title: "SHA3_1"
|
||||
|
@ -253,9 +252,9 @@ proc opCustomMain*() =
|
|||
assembler: # BLOCKHASH OP
|
||||
title: "BLOCKHASH_1"
|
||||
code:
|
||||
Push2 "0xb864" # 47204, parent header number
|
||||
Push1 "0x00"
|
||||
Blockhash
|
||||
stack: "0xa85842a20755232169db76c5bd4ad4672c1551fca4b07d0bd139cd0e6fef684d"
|
||||
stack: "0xd4e56740f876aef8c010b86a40d5f56745a118d0906a34e69aec8c0db1cb8fa3"
|
||||
|
||||
# current block coinbase/miner
|
||||
assembler: # COINBASE OP
|
||||
|
@ -269,42 +268,42 @@ proc opCustomMain*() =
|
|||
title: "TIMESTAMP_1"
|
||||
code:
|
||||
TimeStamp
|
||||
stack: "0x0000000000000000000000000000000000000000000000000000000055c46bba"
|
||||
stack: "0x0000000000000000000000000000000000000000000000000000000000000001"
|
||||
|
||||
# current block number
|
||||
assembler: # NUMBER OP
|
||||
title: "NUMBER_1"
|
||||
code:
|
||||
Number
|
||||
stack: "0x000000000000000000000000000000000000000000000000000000000000b865"
|
||||
stack: "0x0000000000000000000000000000000000000000000000000000000000000001"
|
||||
|
||||
# current difficulty
|
||||
assembler: # DIFFICULTY OP
|
||||
title: "DIFFICULTY_1"
|
||||
code:
|
||||
Difficulty
|
||||
stack: "0x000000000000000000000000000000000000000000000000000001547c73822d"
|
||||
stack: "0x0000000000000000000000000000000000000000000000000000000400800000"
|
||||
|
||||
# ??
|
||||
# tx gas price
|
||||
assembler: # GASPRICE OP
|
||||
title: "GASPRICE_1"
|
||||
code:
|
||||
GasPrice
|
||||
stack: "0x000000000000000000000000000000000000000000000000000000746a528800"
|
||||
stack: "0x0000000000000000000000000000000000000000000000000000000000000001"
|
||||
|
||||
# ??
|
||||
# gas remaining
|
||||
assembler: # GAS OP
|
||||
title: "GAS_1"
|
||||
code:
|
||||
Gas
|
||||
stack: "0x000000000000000000000000000000000000000000000000000000001dcd64fe"
|
||||
|
||||
# ??
|
||||
# block gas limit
|
||||
assembler: # GASLIMIT OP
|
||||
title: "GASLIMIT_1"
|
||||
code:
|
||||
GasLimit
|
||||
stack: "0x000000000000000000000000000000000000000000000000000000000000a298"
|
||||
stack: "0x00000000000000000000000000000000000000000000000000000000000186a0"
|
||||
|
||||
assembler: # INVALID OP
|
||||
title: "INVALID_1"
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
import
|
||||
macro_assembler, unittest2, macros,
|
||||
stew/byteutils, eth/common, ../nimbus/db/state_db,
|
||||
../nimbus/db/db_chain
|
||||
stew/byteutils, eth/common,
|
||||
../nimbus/vm_state,
|
||||
../nimbus/db/accounts_cache
|
||||
|
||||
proc opEnvMain*() =
|
||||
suite "Environmental Information Opcodes":
|
||||
setup:
|
||||
let (blockNumber, chainDB) = initDatabase()
|
||||
let (vmState, chainDB) = initDatabase()
|
||||
|
||||
assembler: # CODECOPY OP
|
||||
title: "CODECOPY_1"
|
||||
|
@ -178,22 +178,17 @@ proc opEnvMain*() =
|
|||
"0x07"
|
||||
|
||||
suite "Environmental Information Opcodes 2":
|
||||
setup:
|
||||
let (blockNumber, chainDB) = initDatabase()
|
||||
var acc: EthAddress
|
||||
hexToByteArray("0xfbe0afcd7658ba86be41922059dd879c192d4c73", acc)
|
||||
var
|
||||
parent = chainDB.getBlockHeader(blockNumber - 1)
|
||||
stateDB = newAccountStateDB(chainDB.db, parent.stateRoot, false)
|
||||
let
|
||||
(vmState, chainDB) = initDatabase()
|
||||
acc = hexToByteArray[20]("0xfbe0afcd7658ba86be41922059dd879c192d4c73")
|
||||
code = hexToSeqByte("0x0102030405060708090A0B0C0D0E0F" &
|
||||
"611234600054615566602054603E6000602073471FD3AD3E9EEADEEC4608B92D" &
|
||||
"16CE6B500704CC3C6000605f556014600054601e60205463abcddcba6040545b" &
|
||||
"51602001600a5254516040016014525451606001601e52545160800160285254" &
|
||||
"60a052546016604860003960166000f26000603f556103e756600054600053602002351234")
|
||||
|
||||
stateDB.setCode(acc, code)
|
||||
parent.stateRoot = stateDB.rootHash
|
||||
chainDB.setHead(parent, true)
|
||||
vmState.mutateStateDB:
|
||||
db.setCode(acc, code)
|
||||
|
||||
assembler: # EXTCODECOPY OP
|
||||
title: "EXTCODECOPY_1"
|
||||
|
|
|
@ -2,8 +2,7 @@ import macro_assembler, unittest2, macros, strutils
|
|||
|
||||
proc opMemoryMain*() =
|
||||
suite "Memory Opcodes":
|
||||
setup:
|
||||
let (blockNumber, chainDB) = initDatabase()
|
||||
let (vmState, chainDB) = initDatabase()
|
||||
|
||||
assembler: # PUSH1 OP
|
||||
title: "PUSH1"
|
||||
|
@ -662,7 +661,7 @@ proc opMemoryMain*() =
|
|||
code:
|
||||
PUSH1 "0xAA"
|
||||
SLOAD
|
||||
stack: "0x0000000000000000000000000000000000000000000000000000000000000000"
|
||||
stack: "0x0000000000000000000000000000000000000000000000000000000000000022"
|
||||
|
||||
assembler: # SLOAD OP
|
||||
title: "SLOAD_2"
|
||||
|
@ -708,7 +707,7 @@ proc opMemoryMain*() =
|
|||
SLOAD
|
||||
PC
|
||||
stack:
|
||||
"0x00"
|
||||
"0x0000000000000000000000000000000000000000000000000000000000000022"
|
||||
"0x0000000000000000000000000000000000000000000000000000000000000008"
|
||||
memory:
|
||||
"0x00"
|
||||
|
|
|
@ -4,8 +4,7 @@ import
|
|||
|
||||
proc opMiscMain*() =
|
||||
suite "Misc Opcodes":
|
||||
setup:
|
||||
let (blockNumber, chainDB) = initDatabase()
|
||||
let (vmState, chainDB) = initDatabase()
|
||||
|
||||
assembler: # LOG0 OP
|
||||
title: "Log0"
|
||||
|
@ -20,7 +19,7 @@ proc opMiscMain*() =
|
|||
"0x1234"
|
||||
logs:
|
||||
(
|
||||
address: "0xc669eaad75042be84daaf9b461b0e868b9ac1871",
|
||||
address: "0x460121576cc7df020759730751f92bd62fd78dd6",
|
||||
data: "0x0000000000000000000000000000000000000000000000000000000000001234"
|
||||
)
|
||||
|
||||
|
@ -38,7 +37,7 @@ proc opMiscMain*() =
|
|||
"0x1234"
|
||||
logs:
|
||||
(
|
||||
address: "0xc669eaad75042be84daaf9b461b0e868b9ac1871",
|
||||
address: "0x460121576cc7df020759730751f92bd62fd78dd6",
|
||||
topics: ["0x9999"],
|
||||
data: "0x0000000000000000000000000000000000000000000000000000000000001234"
|
||||
)
|
||||
|
@ -58,7 +57,7 @@ proc opMiscMain*() =
|
|||
"0x1234"
|
||||
logs:
|
||||
(
|
||||
address: "0xc669eaad75042be84daaf9b461b0e868b9ac1871",
|
||||
address: "0x460121576cc7df020759730751f92bd62fd78dd6",
|
||||
topics: ["0x6666", "0x9999"],
|
||||
data: "0x0000000000000000000000000000000000000000000000000000000000001234"
|
||||
)
|
||||
|
@ -79,7 +78,7 @@ proc opMiscMain*() =
|
|||
"0x1234"
|
||||
logs:
|
||||
(
|
||||
address: "0xc669eaad75042be84daaf9b461b0e868b9ac1871",
|
||||
address: "0x460121576cc7df020759730751f92bd62fd78dd6",
|
||||
topics: ["0x3333", "0x6666", "0x9999"],
|
||||
data: "0x0000000000000000000000000000000000000000000000000000000000001234"
|
||||
)
|
||||
|
@ -101,7 +100,7 @@ proc opMiscMain*() =
|
|||
"0x1234"
|
||||
logs:
|
||||
(
|
||||
address: "0xc669eaad75042be84daaf9b461b0e868b9ac1871",
|
||||
address: "0x460121576cc7df020759730751f92bd62fd78dd6",
|
||||
topics: ["0x5555", "0x3333", "0x6666", "0x9999"],
|
||||
data: "0x0000000000000000000000000000000000000000000000000000000000001234"
|
||||
)
|
||||
|
|
Loading…
Reference in New Issue