diff --git a/tests/customgenesis/merge.json b/tests/customgenesis/merge.json new file mode 100644 index 000000000..07f82c2ef --- /dev/null +++ b/tests/customgenesis/merge.json @@ -0,0 +1,66 @@ +{ + "config": { + "chainId": 7, + "homesteadBlock": 0, + "eip150Block": 0, + "eip150Hash": "0x5de1ee4135274003348e80b788e5afa4b18b18d320a5622218d5c493fedf5689", + "eip155Block": 0, + "eip158Block": 0, + "byzantiumBlock": 0, + "constantinopleBlock": 0, + "petersburgBlock": 0, + "istanbulBlock": 0, + "muirGlacierBlock": 0, + "berlinBlock": 0, + "londonBlock": 0, + "clique": { + "epoch": 3000, + "period": 1 + } + }, + "genesis": { + "coinbase": "0x0000000000000000000000000000000000000000", + "difficulty": "0x30000", + "extraData": "0x0000000000000000000000000000000000000000000000000000000000000000658bdf435d810c91414ec09147daa6db624063790000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "gasLimit": "0x2fefd8", + "nonce": "0x0000000000000000", + "timestamp": "0x1234", + "alloc": { + "cf49fda3be353c69b41ed96333cd24302da4556f": { + "balance": "0x123450000000000000000" + }, + "0161e041aad467a890839d5b08b138c1e6373072": { + "balance": "0x123450000000000000000" + }, + "87da6a8c6e9eff15d703fc2773e32f6af8dbe301": { + "balance": "0x123450000000000000000" + }, + "b97de4b8c857e4f6bc354f226dc3249aaee49209": { + "balance": "0x123450000000000000000" + }, + "c5065c9eeebe6df2c2284d046bfc906501846c51": { + "balance": "0x123450000000000000000" + }, + "0000000000000000000000000000000000000314": { + "balance": "0x0", + "code": "0x60606040526000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff168063a223e05d1461006a578063abd1a0cf1461008d578063abfced1d146100d4578063e05c914a14610110578063e6768b451461014c575b610000565b346100005761007761019d565b6040518082815260200191505060405180910390f35b34610000576100be600480803573ffffffffffffffffffffffffffffffffffffffff169060200190919050506101a3565b6040518082815260200191505060405180910390f35b346100005761010e600480803573ffffffffffffffffffffffffffffffffffffffff169060200190919080359060200190919050506101ed565b005b346100005761014a600480803590602001909190803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050610236565b005b346100005761017960048080359060200190919080359060200190919080359060200190919050506103c4565b60405180848152602001838152602001828152602001935050505060405180910390f35b60005481565b6000600160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205490505b919050565b80600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055505b5050565b7f6031a8d62d7c95988fa262657cd92107d90ed96e08d8f867d32f26edfe85502260405180905060405180910390a17f47e2689743f14e97f7dcfa5eec10ba1dff02f83b3d1d4b9c07b206cbbda66450826040518082815260200191505060405180910390a1817fa48a6b249a5084126c3da369fbc9b16827ead8cb5cdc094b717d3f1dcd995e2960405180905060405180910390a27f7890603b316f3509577afd111710f9ebeefa15e12f72347d9dffd0d65ae3bade81604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a18073ffffffffffffffffffffffffffffffffffffffff167f7efef9ea3f60ddc038e50cccec621f86a0195894dc0520482abf8b5c6b659e4160405180905060405180910390a28181604051808381526020018273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019250505060405180910390a05b5050565b6000600060008585859250925092505b935093509390505600a165627a7a72305820aaf842d0d0c35c45622c5263cbb54813d2974d3999c8c38551d7c613ea2bc1170029", + "storage": { + "0x0000000000000000000000000000000000000000000000000000000000000000": "0x1234", + "0x6661e9d6d8b923d5bbaab1b96e1dd51ff6ea2a93520fdc9eb75d059238b8c5e9": "0x01" + } + }, + "0000000000000000000000000000000000000315": { + "balance": "0x9999999999999999999999999999999", + "code": "0x60606040526000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff168063ef2769ca1461003e575b610000565b3461000057610078600480803573ffffffffffffffffffffffffffffffffffffffff1690602001909190803590602001909190505061007a565b005b8173ffffffffffffffffffffffffffffffffffffffff166108fc829081150290604051809050600060405180830381858888f1935050505015610106578173ffffffffffffffffffffffffffffffffffffffff167f30a3c50752f2552dcc2b93f5b96866280816a986c0c0408cb6778b9fa198288f826040518082815260200191505060405180910390a25b5b50505600a165627a7a72305820637991fabcc8abad4294bf2bb615db78fbec4edff1635a2647d3894e2daf6a610029" + }, + "0000000000000000000000000000000000000316": { + "balance": "0x0", + "code": "0x444355" + }, + "0000000000000000000000000000000000000317": { + "balance": "0x0", + "code": "0x600160003555" + } + } + } +} diff --git a/tests/test_txpool.nim b/tests/test_txpool.nim index 880a4eebe..209c9e5f1 100644 --- a/tests/test_txpool.nim +++ b/tests/test_txpool.nim @@ -14,6 +14,7 @@ import ../nimbus/p2p/[chain, clique, executor], ../nimbus/utils/[tx_pool, tx_pool/tx_item], ./test_txpool/[helpers, setup, sign_helper], + ./test_txpool2, chronos, eth/[common, keys, p2p], stew/[keyed_queue, sorted_set], @@ -922,6 +923,8 @@ proc txPoolMain*(noisy = defined(debug)) = noisy.runTxLoader noisy.runTxPoolTests noisy.runTxPackerTests + test_txpool2.runTxPoolCliqueTest() + test_txpool2.runTxPoolPosTest() when isMainModule: const diff --git a/tests/test_txpool2.nim b/tests/test_txpool2.nim new file mode 100644 index 000000000..f4cd91849 --- /dev/null +++ b/tests/test_txpool2.nim @@ -0,0 +1,224 @@ +import + std/[os, strutils, math, tables, options], + eth/[trie/db, keys, common, trie/hexary], + stew/byteutils, nimcrypto, unittest2, + ../nimbus/db/[db_chain, state_db], + ../nimbus/p2p/chain, + ../nimbus/p2p/clique/[clique_sealer, clique_desc], + ../nimbus/[chain_config, config, genesis, transaction, constants], + ../nimbus/utils/[tx_pool], + ./test_txpool/helpers, + ./macro_assembler + +const + baseFolder = "tests" / "customgenesis" + genesisFile = baseFolder / "merge.json" + +type + TestEnv = object + nonce : uint64 + chainId : ChainId + vaultKey: PrivateKey + conf : NimbusConf + chainDB : BaseChainDB + chain : Chain + xp : TxPoolRef + +const + signerKeyHex = "9c647b8b7c4e7c3490668fb6c11473619db80c93704c70893d3813af4090c39c" + vaultKeyHex = "63b508a03c3b5937ceb903af8b1b0c191012ef6eb7e9c3fb7afa94e5d214d376" + recipient = hexToByteArray[20]("0000000000000000000000000000000000000318") + contractCode = evmByteCode: + PrevRandao # VAL + Push1 "0x11" # KEY + Sstore # OP + Stop + +proc privKey(keyHex: string): PrivateKey = + let kRes = PrivateKey.fromHex(keyHex) + if kRes.isErr: + echo kRes.error + quit(QuitFailure) + + kRes.get() + +func gwei(n: uint64): GasInt {.compileTime.} = + GasInt(n * (10'u64 ^ 9'u64)) + +proc makeTx*(t: var TestEnv, recipient: EthAddress, amount: UInt256, payload: openArray[byte] = []): Transaction = + const + gasLimit = 75000.GasInt + gasPrice = 30.gwei + + let tx = Transaction( + txType : TxLegacy, + chainId : t.chainId, + nonce : AccountNonce(t.nonce), + gasPrice: gasPrice, + gasLimit: gasLimit, + to : some(recipient), + value : amount, + payload : @payload + ) + + inc t.nonce + signTransaction(tx, t.vaultKey, t.chainId, eip155 = true) + +proc initEnv(ttd: Option[UInt256] = none(UInt256)): TestEnv = + var + conf = makeConfig(@[ + "--engine-signer:658bdf435d810c91414ec09147daa6db62406379", + "--custom-network:" & genesisFile + ]) + + conf.networkParams.genesis.alloc[recipient] = GenesisAccount( + code: contractCode + ) + + if ttd.isSome: + conf.networkParams.config.terminalTotalDifficulty = ttd + + let + chainDB = newBaseChainDB( + newMemoryDb(), + conf.pruneMode == PruneMode.Full, + conf.networkId, + conf.networkParams + ) + chain = newChain(chainDB) + + initializeEmptyDb(chainDB) + + result = TestEnv( + conf: conf, + chainDB: chainDB, + chain: chain, + xp: TxPoolRef.new(chainDB, conf.engineSigner), + vaultKey: privKey(vaultKeyHex), + chainId: conf.networkParams.config.chainId, + nonce: 0'u64 + ) + +const + amount = 1000.u256 + slot = 0x11.u256 + prevRandao = EMPTY_UNCLE_HASH # it can be any valid hash + +proc runTxPoolCliqueTest*() = + var + env = initEnv() + + var + tx = env.makeTx(recipient, amount) + xp = env.xp + conf = env.conf + chainDB = env.chainDB + chain = env.chain + clique = env.chain.clique + body: BlockBody + blk: EthBlock + + let signerKey = privKey(signerKeyHex) + proc signerFunc(signer: EthAddress, msg: openArray[byte]): + Result[RawSignature, cstring] {.gcsafe.} = + doAssert(signer == conf.engineSigner) + let + data = keccak256.digest(msg) + rawSign = sign(signerKey, SkMessage(data.data)).toRaw + + ok(rawSign) + + suite "Test TxPool with Clique sealer": + test "TxPool addLocal": + let res = xp.addLocal(tx, force = true) + check res.isOk + if res.isErr: + debugEcho res.error + return + + test "TxPool jobCommit": + xp.jobCommit() + check xp.nItems.total == 1 + + test "TxPool ethBlock": + xp.prevRandao = EMPTY_UNCLE_HASH + blk = xp.ethBlock() + + blk.header.prevRandao = EMPTY_UNCLE_HASH + body = BlockBody( + transactions: blk.txs, + uncles: blk.uncles + ) + check blk.txs.len == 1 + + test "Clique prepare and seal": + clique.authorize(conf.engineSigner, signerFunc) + let parent = chainDB.getBlockHeader(blk.header.parentHash) + let ry = chain.clique.prepare(parent, blk.header) + check ry.isOk + if ry.isErr: + debugEcho ry.error + return + + let rx = clique.seal(blk) + check rx.isOk + if rx.isErr: + debugEcho rx.error + return + + test "Clique persistBlocks": + let rr = chain.persistBlocks([blk.header], [body]) + check rr == ValidationResult.OK + +proc runTxPoolPosTest*() = + var + env = initEnv(some(100.u256)) + + var + tx = env.makeTx(recipient, amount) + xp = env.xp + chainDB = env.chainDB + chain = env.chain + body: BlockBody + blk: EthBlock + + suite "Test TxPool with PoS block": + test "TxPool addLocal": + let res = xp.addLocal(tx, force = true) + check res.isOk + if res.isErr: + debugEcho res.error + return + + test "TxPool jobCommit": + xp.jobCommit() + check xp.nItems.total == 1 + + test "TxPool ethBlock": + xp.prevRandao = prevRandao + blk = xp.ethBlock() + + check chain.isBlockAfterTtd(blk.header) + + blk.header.difficulty = DifficultyInt.zero + blk.header.prevRandao = prevRandao + blk.header.nonce = default(BlockNonce) + blk.header.extraData = @[] + + body = BlockBody( + transactions: blk.txs, + uncles: blk.uncles + ) + check blk.txs.len == 1 + + test "PoS persistBlocks": + let rr = chain.persistBlocks([blk.header], [body]) + check rr == ValidationResult.OK + + test "validate TxPool prevRandao setter": + var sdb = newAccountStateDB(chainDB.db, blk.header.stateRoot, pruneTrie = false) + let (val, ok) = sdb.getStorage(recipient, slot) + let randao = Hash256(data: val.toBytesBE) + check ok + check randao == prevRandao +