diff --git a/nimbus/transaction/call_evm.nim b/nimbus/transaction/call_evm.nim index 1a16ff94b..54aec2cf2 100644 --- a/nimbus/transaction/call_evm.nim +++ b/nimbus/transaction/call_evm.nim @@ -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, diff --git a/tests/macro_assembler.nim b/tests/macro_assembler.nim index b0072dcf2..15e5b2e10 100644 --- a/tests/macro_assembler.nim +++ b/tests/macro_assembler.nim @@ -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 diff --git a/tests/test_op_arith.nim b/tests/test_op_arith.nim index 517858e84..00ba21fc0 100644 --- a/tests/test_op_arith.nim +++ b/tests/test_op_arith.nim @@ -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() diff --git a/tests/test_op_bit.nim b/tests/test_op_bit.nim index ce3229a7d..264034bce 100644 --- a/tests/test_op_bit.nim +++ b/tests/test_op_bit.nim @@ -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() + diff --git a/tests/test_op_custom.nim b/tests/test_op_custom.nim index 29e4e73eb..793b45318 100644 --- a/tests/test_op_custom.nim +++ b/tests/test_op_custom.nim @@ -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" diff --git a/tests/test_op_env.nim b/tests/test_op_env.nim index abc041724..12678e50d 100644 --- a/tests/test_op_env.nim +++ b/tests/test_op_env.nim @@ -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) - code = hexToSeqByte("0x0102030405060708090A0B0C0D0E0F" & - "611234600054615566602054603E6000602073471FD3AD3E9EEADEEC4608B92D" & - "16CE6B500704CC3C6000605f556014600054601e60205463abcddcba6040545b" & - "51602001600a5254516040016014525451606001601e52545160800160285254" & - "60a052546016604860003960166000f26000603f556103e756600054600053602002351234") + 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" diff --git a/tests/test_op_memory.nim b/tests/test_op_memory.nim index 26a43909d..325484d92 100644 --- a/tests/test_op_memory.nim +++ b/tests/test_op_memory.nim @@ -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" diff --git a/tests/test_op_misc.nim b/tests/test_op_misc.nim index 734545730..04ef481d0 100644 --- a/tests/test_op_misc.nim +++ b/tests/test_op_misc.nim @@ -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" )