diff --git a/BlockchainTests.md b/BlockchainTests.md new file mode 100644 index 000000000..1223ac9d1 --- /dev/null +++ b/BlockchainTests.md @@ -0,0 +1,407 @@ +BlockchainTests +=== +## BlockchainTests +```diff ++ randomStatetest391.json OK +``` +OK: 1/1 Fail: 0/1 Skip: 0/1 +## bcBlockGasLimitTest +```diff ++ BlockGasLimit2p63m1.json OK ++ GasUsedHigherThanBlockGasLimitButNotWithRefundsSuicideFirst.jsonOK ++ GasUsedHigherThanBlockGasLimitButNotWithRefundsSuicideLast.json OK ++ SuicideTransaction.json OK ++ TransactionGasHigherThanLimit2p63m1.json OK ++ TransactionGasHigherThanLimit2p63m1_2.json OK +``` +OK: 6/6 Fail: 0/6 Skip: 0/6 +## bcByzantiumToConstantinopleFix +```diff ++ ConstantinopleFixTransition.json OK +``` +OK: 1/1 Fail: 0/1 Skip: 0/1 +## bcEIP158ToByzantium +```diff ++ ByzantiumTransition.json OK +``` +OK: 1/1 Fail: 0/1 Skip: 0/1 +## bcExploitTest +```diff ++ DelegateCallSpam.json OK ++ ShanghaiLove.json OK ++ StrangeContractCreation.json OK + SuicideIssue.json Skip +``` +OK: 3/4 Fail: 0/4 Skip: 1/4 +## bcForgedTest +```diff ++ bcForkBlockTest.json OK ++ bcForkUncle.json OK ++ bcInvalidRLPTest.json OK +``` +OK: 3/3 Fail: 0/3 Skip: 0/3 +## bcForkStressTest +```diff ++ AmIOnEIP150.json OK ++ ForkStressTest.json OK +``` +OK: 2/2 Fail: 0/2 Skip: 0/2 +## bcFrontierToHomestead +```diff ++ CallContractThatCreateContractBeforeAndAfterSwitchover.json OK ++ ContractCreationFailsOnHomestead.json OK ++ HomesteadOverrideFrontier.json OK ++ UncleFromFrontierInHomestead.json OK ++ UnclePopulation.json OK ++ blockChainFrontierWithLargerTDvsHomesteadBlockchain.json OK ++ blockChainFrontierWithLargerTDvsHomesteadBlockchain2.json OK +``` +OK: 7/7 Fail: 0/7 Skip: 0/7 +## bcGasPricerTest +```diff ++ RPC_API_Test.json OK ++ highGasUsage.json OK ++ notxs.json OK +``` +OK: 3/3 Fail: 0/3 Skip: 0/3 +## bcHomesteadToDao +```diff ++ DaoTransactions.json OK ++ DaoTransactions_EmptyTransactionAndForkBlocksAhead.json OK ++ DaoTransactions_UncleExtradata.json OK ++ DaoTransactions_XBlockm1.json OK +``` +OK: 4/4 Fail: 0/4 Skip: 0/4 +## bcHomesteadToEIP150 +```diff ++ EIP150Transition.json OK +``` +OK: 1/1 Fail: 0/1 Skip: 0/1 +## bcInvalidHeaderTest +```diff ++ DifferentExtraData1025.json OK ++ DifficultyIsZero.json OK ++ ExtraData1024.json OK ++ ExtraData33.json OK ++ GasLimitHigherThan2p63m1.json OK ++ GasLimitIsZero.json OK ++ log1_wrongBlockNumber.json OK ++ log1_wrongBloom.json OK ++ timeDiff0.json OK ++ wrongCoinbase.json OK ++ wrongDifficulty.json OK ++ wrongGasLimit.json OK ++ wrongGasUsed.json OK ++ wrongMixHash.json OK ++ wrongNonce.json OK ++ wrongNumber.json OK ++ wrongParentHash.json OK ++ wrongParentHash2.json OK ++ wrongReceiptTrie.json OK ++ wrongStateRoot.json OK ++ wrongTimestamp.json OK ++ wrongTransactionsTrie.json OK ++ wrongUncleHash.json OK +``` +OK: 23/23 Fail: 0/23 Skip: 0/23 +## bcMultiChainTest +```diff ++ CallContractFromNotBestBlock.json OK ++ ChainAtoChainB.json OK ++ ChainAtoChainBCallContractFormA.json OK ++ ChainAtoChainB_BlockHash.json OK ++ ChainAtoChainB_difficultyB.json OK ++ ChainAtoChainBtoChainA.json OK ++ ChainAtoChainBtoChainAtoChainB.json OK ++ UncleFromSideChain.json OK +``` +OK: 8/8 Fail: 0/8 Skip: 0/8 +## bcRandomBlockhashTest +```diff ++ randomStatetest109BC.json OK ++ randomStatetest113BC.json OK ++ randomStatetest127BC.json OK ++ randomStatetest128BC.json OK ++ randomStatetest132BC.json OK ++ randomStatetest140BC.json OK ++ randomStatetest141BC.json OK ++ randomStatetest152BC.json OK ++ randomStatetest165BC.json OK ++ randomStatetest168BC.json OK ++ randomStatetest181BC.json OK ++ randomStatetest182BC.json OK ++ randomStatetest186BC.json OK ++ randomStatetest193BC.json OK ++ randomStatetest203BC.json OK ++ randomStatetest213BC.json OK ++ randomStatetest218BC.json OK ++ randomStatetest21BC.json OK ++ randomStatetest224BC.json OK ++ randomStatetest234BC.json OK ++ randomStatetest235BC.json OK ++ randomStatetest239BC.json OK ++ randomStatetest240BC.json OK ++ randomStatetest253BC.json OK ++ randomStatetest255BC.json OK ++ randomStatetest256BC.json OK ++ randomStatetest258BC.json OK ++ randomStatetest262BC.json OK ++ randomStatetest272BC.json OK ++ randomStatetest277BC.json OK ++ randomStatetest284BC.json OK ++ randomStatetest289BC.json OK ++ randomStatetest314BC.json OK ++ randomStatetest317BC.json OK ++ randomStatetest319BC.json OK ++ randomStatetest330BC.json OK ++ randomStatetest331BC.json OK ++ randomStatetest344BC.json OK ++ randomStatetest34BC.json OK ++ randomStatetest35BC.json OK ++ randomStatetest373BC.json OK ++ randomStatetest374BC.json OK ++ randomStatetest390BC.json OK ++ randomStatetest392BC.json OK ++ randomStatetest394BC.json OK ++ randomStatetest400BC.json OK ++ randomStatetest403BC.json OK ++ randomStatetest40BC.json OK ++ randomStatetest427BC.json OK ++ randomStatetest431BC.json OK ++ randomStatetest432BC.json OK ++ randomStatetest434BC.json OK ++ randomStatetest44BC.json OK ++ randomStatetest453BC.json OK ++ randomStatetest459BC.json OK ++ randomStatetest463BC.json OK ++ randomStatetest479BC.json OK ++ randomStatetest486BC.json OK ++ randomStatetest490BC.json OK ++ randomStatetest492BC.json OK ++ randomStatetest515BC.json OK ++ randomStatetest522BC.json OK ++ randomStatetest529BC.json OK ++ randomStatetest530BC.json OK ++ randomStatetest540BC.json OK ++ randomStatetest551BC.json OK ++ randomStatetest557BC.json OK ++ randomStatetest561BC.json OK ++ randomStatetest568BC.json OK ++ randomStatetest56BC.json OK ++ randomStatetest570BC.json OK ++ randomStatetest590BC.json OK ++ randomStatetest591BC.json OK ++ randomStatetest593BC.json OK ++ randomStatetest595BC.json OK ++ randomStatetest598BC.json OK ++ randomStatetest606BC.json OK ++ randomStatetest613BC.json OK ++ randomStatetest614BC.json OK ++ randomStatetest617BC.json OK ++ randomStatetest61BC.json OK ++ randomStatetest622BC.json OK ++ randomStatetest623BC.json OK ++ randomStatetest631BC.json OK ++ randomStatetest634BC.json OK ++ randomStatetest65BC.json OK ++ randomStatetest68BC.json OK ++ randomStatetest70BC.json OK ++ randomStatetest71BC.json OK ++ randomStatetest76BC.json OK ++ randomStatetest79BC.json OK ++ randomStatetest86BC.json OK ++ randomStatetest8BC.json OK ++ randomStatetest91BC.json OK ++ randomStatetest93BC.json OK ++ randomStatetest99BC.json OK +``` +OK: 96/96 Fail: 0/96 Skip: 0/96 +## bcStateTests +```diff ++ BLOCKHASH_Bounds.json OK ++ BadStateRootTxBC.json OK ++ CreateTransactionReverted.json OK ++ EmptyTransaction.json OK ++ EmptyTransaction2.json OK ++ NotEnoughCashContractCreation.json OK ++ OOGStateCopyContainingDeletedContract.json OK ++ OverflowGasRequire.json OK ++ RefundOverflow.json OK ++ RefundOverflow2.json OK ++ SuicidesMixingCoinbase.json OK ++ TransactionFromCoinbaseHittingBlockGasLimit1.json OK ++ TransactionFromCoinbaseNotEnoughFounds.json OK ++ TransactionNonceCheck.json OK ++ TransactionNonceCheck2.json OK ++ TransactionToItselfNotEnoughFounds.json OK ++ UserTransactionGasLimitIsTooLowWhenZeroCost.json OK ++ UserTransactionZeroCost.json OK ++ UserTransactionZeroCost2.json OK ++ UserTransactionZeroCostWithData.json OK ++ ZeroValue_TransactionCALL_OOGRevert.json OK ++ ZeroValue_TransactionCALL_ToEmpty_OOGRevert.json OK ++ ZeroValue_TransactionCALL_ToNonZeroBalance_OOGRevert.json OK ++ ZeroValue_TransactionCALL_ToOneStorageKey_OOGRevert.json OK ++ ZeroValue_TransactionCALLwithData_OOGRevert.json OK ++ ZeroValue_TransactionCALLwithData_ToEmpty_OOGRevert.json OK ++ ZeroValue_TransactionCALLwithData_ToNonZeroBalance_OOGRevert.jsonOK ++ ZeroValue_TransactionCALLwithData_ToOneStorageKey_OOGRevert.jsonOK ++ blockhashNonConstArg.json OK ++ blockhashTests.json OK ++ callcodeOutput1.json OK ++ callcodeOutput2.json OK ++ callcodeOutput3partial.json OK ++ create2collisionwithSelfdestructSameBlock.json OK ++ createNameRegistratorPerTxsNotEnoughGasAfter.json OK ++ createNameRegistratorPerTxsNotEnoughGasAt.json OK ++ createNameRegistratorPerTxsNotEnoughGasBefore.json OK ++ extCodeHashOfDeletedAccount.json OK ++ extCodeHashOfDeletedAccountDynamic.json OK ++ multimpleBalanceInstruction.json OK ++ randomStatetest123.json OK ++ randomStatetest136.json OK ++ randomStatetest160.json OK ++ randomStatetest170.json OK ++ randomStatetest223.json OK ++ randomStatetest229.json OK ++ randomStatetest241.json OK ++ randomStatetest324.json OK ++ randomStatetest328.json OK ++ randomStatetest375.json OK ++ randomStatetest377.json OK ++ randomStatetest38.json OK ++ randomStatetest441.json OK ++ randomStatetest46.json OK ++ randomStatetest549.json OK ++ randomStatetest594.json OK ++ randomStatetest619.json OK ++ randomStatetest94.json OK ++ simpleSuicide.json OK ++ suicideCoinbase.json OK ++ suicideCoinbaseState.json OK ++ suicideStorageCheck.json OK ++ suicideStorageCheckVCreate.json OK ++ suicideStorageCheckVCreate2.json OK ++ suicideThenCheckBalance.json OK ++ transactionFromNotExistingAccount.json OK ++ txCost-sec73.json OK +``` +OK: 67/67 Fail: 0/67 Skip: 0/67 +## bcTotalDifficultyTest +```diff ++ lotsOfBranchesOverrideAtTheEnd.json OK ++ lotsOfBranchesOverrideAtTheMiddle.json OK ++ lotsOfLeafs.json OK ++ newChainFrom4Block.json OK ++ newChainFrom5Block.json OK ++ newChainFrom6Block.json OK ++ sideChainWithMoreTransactions.json OK ++ sideChainWithMoreTransactions2.json OK ++ sideChainWithNewMaxDifficultyStartingFromBlock3AfterBlock4.json OK ++ uncleBlockAtBlock3AfterBlock3.json OK ++ uncleBlockAtBlock3afterBlock4.json OK +``` +OK: 11/11 Fail: 0/11 Skip: 0/11 +## bcUncleHeaderValidity +```diff ++ correct.json OK ++ diffTooHigh.json OK ++ diffTooLow.json OK ++ diffTooLow2.json OK ++ gasLimitLTGasUsageUncle.json OK ++ gasLimitTooHigh.json OK ++ gasLimitTooHighExactBound.json OK ++ gasLimitTooLow.json OK ++ gasLimitTooLowExactBound.json OK ++ incorrectUncleNumber0.json OK ++ incorrectUncleNumber1.json OK ++ incorrectUncleNumber500.json OK ++ incorrectUncleTimestamp.json OK ++ incorrectUncleTimestamp2.json OK ++ nonceWrong.json OK ++ pastUncleTimestamp.json OK ++ timestampTooHigh.json OK ++ timestampTooLow.json OK ++ unknownUncleParentHash.json OK ++ wrongMixHash.json OK ++ wrongParentHash.json OK ++ wrongStateRoot.json OK +``` +OK: 22/22 Fail: 0/22 Skip: 0/22 +## bcUncleSpecialTests +```diff ++ futureUncleTimestamp2.json OK ++ futureUncleTimestamp3.json OK ++ futureUncleTimestampDifficultyDrop.json OK ++ futureUncleTimestampDifficultyDrop2.json OK ++ futureUncleTimestampDifficultyDrop3.json OK ++ futureUncleTimestampDifficultyDrop4.json OK ++ uncleBloomNot0.json OK ++ uncleBloomNot0_2.json OK ++ uncleBloomNot0_3.json OK +``` +OK: 9/9 Fail: 0/9 Skip: 0/9 +## bcUncleTest +```diff ++ EqualUncleInTwoDifferentBlocks.json OK ++ InChainUncle.json OK ++ InChainUncleFather.json OK ++ InChainUncleGrandPa.json OK ++ InChainUncleGreatGrandPa.json OK ++ InChainUncleGreatGreatGrandPa.json OK ++ InChainUncleGreatGreatGreatGrandPa.json OK ++ InChainUncleGreatGreatGreatGreatGrandPa.json OK ++ UncleIsBrother.json OK ++ oneUncle.json OK ++ oneUncleGeneration2.json OK ++ oneUncleGeneration3.json OK ++ oneUncleGeneration4.json OK ++ oneUncleGeneration5.json OK ++ oneUncleGeneration6.json OK ++ oneUncleGeneration7.json OK ++ threeUncle.json OK ++ twoEqualUncle.json OK ++ twoUncle.json OK ++ uncleHeaderAtBlock2.json OK ++ uncleHeaderAtBlock2Byzantium.json OK ++ uncleHeaderAtBlock2Constantinople.json OK ++ uncleHeaderWithGeneration0.json OK ++ uncleWithSameBlockNumber.json OK +``` +OK: 24/24 Fail: 0/24 Skip: 0/24 +## bcValidBlockTest +```diff ++ ExtraData32.json OK ++ RecallSuicidedContract.json OK ++ RecallSuicidedContractInOneBlock.json OK ++ SimpleTx.json OK ++ SimpleTx3.json OK ++ SimpleTx3LowS.json OK ++ callRevert.json OK ++ createRevert.json OK ++ dataTx.json OK ++ dataTx2.json OK ++ diff1024.json OK ++ gasLimitTooHigh.json OK ++ gasLimitTooHigh2.json OK ++ gasPrice0.json OK ++ log1_correct.json OK ++ timeDiff12.json OK ++ timeDiff13.json OK ++ timeDiff14.json OK ++ txEqualValue.json OK ++ txOrder.json OK +``` +OK: 20/20 Fail: 0/20 Skip: 0/20 +## bcWalletTest +```diff ++ wallet2outOf3txs.json OK ++ wallet2outOf3txs2.json OK ++ wallet2outOf3txsRevoke.json OK ++ wallet2outOf3txsRevokeAndConfirmAgain.json OK ++ walletReorganizeOwners.json OK +``` +OK: 5/5 Fail: 0/5 Skip: 0/5 + +---TOTAL--- +OK: 317/318 Fail: 0/318 Skip: 1/318 diff --git a/premix/parser.nim b/premix/parser.nim index b0c41ba55..aad83678a 100644 --- a/premix/parser.nim +++ b/premix/parser.nim @@ -31,31 +31,42 @@ proc prefixHex*(x: string): string = "0x" & toLowerAscii(x) type - SomeData = EthAddress | BloomFilter | BlockNonce + SomeData* = EthAddress | BloomFilter | BlockNonce -proc fromJson(n: JsonNode, name: string, x: var SomeData) = +proc fromJson*(n: JsonNode, name: string, x: var SomeData) = hexToByteArray(n[name].getStr(), x) - doAssert(x.prefixHex == toLowerAscii(n[name].getStr())) + if x.prefixHex != toLowerAscii(n[name].getStr()): + debugEcho "name: ", name + debugEcho "A: ", x.prefixHex + debugEcho "B: ", toLowerAscii(n[name].getStr()) + quit(1) -proc fromJson(n: JsonNode, name: string, x: var Hash256) = + doAssert(x.prefixHex == toLowerAscii(n[name].getStr()), name) + +proc fromJson*(n: JsonNode, name: string, x: var Hash256) = hexToByteArray(n[name].getStr(), x.data) - doAssert(x.prefixHex == toLowerAscii(n[name].getStr())) + doAssert(x.prefixHex == toLowerAscii(n[name].getStr()), name) -proc fromJson(n: JsonNode, name: string, x: var Blob) = +proc fromJson*(n: JsonNode, name: string, x: var Blob) = x = hexToSeqByte(n[name].getStr()) - doAssert(x.prefixHex == toLowerAscii(n[name].getStr())) + doAssert(x.prefixHex == toLowerAscii(n[name].getStr()), name) -proc fromJson(n: JsonNode, name: string, x: var UInt256) = +proc fromJson*(n: JsonNode, name: string, x: var UInt256) = x = UInt256.fromHex(n[name].getStr()) - doAssert(x.prefixHex == toLowerAscii(n[name].getStr())) + if x.prefixHex != toLowerAscii(n[name].getStr()): + debugEcho "name: ", name + debugEcho "A: ", x.prefixHex + debugEcho "B: ", toLowerAscii(n[name].getStr()) + quit(1) + doAssert(x.prefixHex == toLowerAscii(n[name].getStr()), name) -proc fromJson(n: JsonNode, name: string, x: var SomeInteger) = +proc fromJson*(n: JsonNode, name: string, x: var SomeInteger) = x = hexToInt(n[name].getStr(), type(x)) - doAssert(x.prefixHex == toLowerAscii(n[name].getStr())) + doAssert(x.prefixHex == toLowerAscii(n[name].getStr()), name) -proc fromJson(n: JsonNode, name: string, x: var EthTime) = +proc fromJson*(n: JsonNode, name: string, x: var EthTime) = x = initTime(hexToInt(n[name].getStr(), int64), 0) - doAssert(x.toUnix.prefixHex == toLowerAscii(n[name].getStr())) + doAssert(x.toUnix.prefixHex == toLowerAscii(n[name].getStr()), name) proc parseBlockHeader*(n: JsonNode): BlockHeader = n.fromJson "parentHash", result.parentHash diff --git a/tests/test_blockchain_json.nim b/tests/test_blockchain_json.nim new file mode 100644 index 000000000..455c51b17 --- /dev/null +++ b/tests/test_blockchain_json.nim @@ -0,0 +1,302 @@ +# Nimbus +# Copyright (c) 2018 Status Research & Development GmbH +# Licensed under either of +# * Apache License, version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or http://www.apache.org/licenses/LICENSE-2.0) +# * MIT license ([LICENSE-MIT](LICENSE-MIT) or http://opensource.org/licenses/MIT) +# at your option. This file may not be copied, modified, or distributed except according to those terms. + +import + unittest, json, os, tables, strutils, sets, strformat, + options, + eth/[common, rlp], eth/trie/[db, trie_defs], + ./test_helpers, ../premix/parser, + ../nimbus/vm/interpreter/vm_forks, + ../nimbus/[vm_state, utils], + ../nimbus/db/[db_chain, state_db] + +type + SealEngine = enum + NoProof + Ethash + + TesterBlock = object + blockHeader: Option[BlockHeader] + rlp: Blob + transactions: seq[Transaction] + uncles: seq[BlockHeader] + blockNumber: Option[int] + chainName: Option[string] + chainNetwork: Option[Fork] + exceptions: seq[(string, string)] + + Tester = object + name: string + lastBlockHash: Hash256 + genesisBlockHeader: BlockHeader + blocks: seq[TesterBlock] + sealEngine: Option[SealEngine] + network: string + +proc testFixture(node: JsonNode, testStatusIMPL: var TestStatus) + +#[var topLevel = initCountTable[string]() + +suite "block chain json tests": + jsonTest("BlockchainTests", testFixture) + topLevel.sort + for k, v in topLevel: + echo k, " ", v + +proc testFixture(node: JsonNode, testStatusIMPL: var TestStatus) = + for name, klm in node: + for k, value in klm: + if k == "blocks": + for bc in value: + for key, val in bc: + if key == "transactions": + for tx in val: + for tk, tv in tx: + topLevel.inc tk +]# + +suite "block chain json tests": + jsonTest("BlockchainTests", testFixture) + +func normalizeNumber(n: JsonNode): JsonNode = + let str = n.getStr + # paranoid checks + doAssert n.kind == Jstring + doAssert str.len > 3 + doAssert str[0] == '0' and str[1] == 'x' + # real normalization + # strip leading 0 + if str == "0x00": + result = newJString("0x0") + elif str[2] == '0': + var i = 2 + while str[i] == '0': + inc i + result = newJString("0x" & str.substr(i)) + else: + result = n + +func normalizeData(n: JsonNode): JsonNode = + if n.getStr() == "": + result = newJString("0x") + else: + result = n + +func normalizeBlockHeader(node: JsonNode): JsonNode = + for k, v in node: + case k + of "bloom": node["logsBloom"] = v + of "coinbase": node["miner"] = v + of "uncleHash": node["sha3Uncles"] = v + of "receiptTrie": node["receiptsRoot"] = v + of "transactionsTrie": node["transactionsRoot"] = v + of "number", "difficulty", "gasUsed", + "gasLimit", "timestamp": + node[k] = normalizeNumber(v) + of "extraData": + node[k] = normalizeData(v) + else: discard + result = node + +proc parseHeader(blockHeader: JsonNode, testStatusIMPL: var TestStatus): BlockHeader = + result = normalizeBlockHeader(blockHeader).parseBlockHeader + var blockHash: Hash256 + blockHeader.fromJson "hash", blockHash + check blockHash == hash(result) + +proc parseTx*(n: JsonNode): Transaction = + + for k, v in n: + case k + of "nonce", "gasPrice", "gasLimit", "value": + n[k] = normalizeNumber(v) + of "to": + let str = v.getStr + if str.len > 2 and str[1] != 'x': + n[k] = newJString("0x" & str) + of "v", "r", "s": + n[k] = normalizeNumber(v) + else: + discard + + n.fromJson "nonce", result.accountNonce + n.fromJson "gasPrice", result.gasPrice + n.fromJson "gasLimit", result.gasLimit + result.isContractCreation = n["to"].getStr == "" + if not result.isContractCreation: + n.fromJson "to", result.to + n.fromJson "value", result.value + n.fromJson "data", result.payload + n.fromJson "v", result.V + n.fromJson "r", result.R + n.fromJson "s", result.S + +proc parseBlocks(blocks: JsonNode, testStatusIMPL: var TestStatus): seq[TesterBlock] = + result = @[] + + for fixture in blocks: + var t: TesterBlock + for key, value in fixture: + case key + of "blockHeader": + t.blockHeader = some(parseHeader(fixture["blockHeader"], testStatusIMPL)) + of "blocknumber": + let numberStr = value.getStr + if numberStr.len >= 2 and numberStr[1] == 'x': + fixture[key] = normalizeNumber(value) + var number: int + fixture.fromJson "blocknumber", number + t.blockNumber = some(number) + else: + t.blockNumber = some(parseInt(numberStr)) + of "chainname": + t.chainName = some(value.getStr) + of "chainnetwork": + t.chainNetWork = some(parseEnum[Fork](value.getStr)) + of "rlp": + # var headerRLP: Blob + # fixture.fromJson "rlp", headerRLP + # check rlp.encode(t.blockHeader.get()) == headerRLP + discard + of "transactions": + for tx in value: + t.transactions.add parseTx(tx) + of "uncleHeaders": + t.uncles = @[] + for uncle in value: + t.uncles.add parseHeader(uncle, testStatusIMPL) + else: + t.exceptions.add( (key, value.getStr) ) + + if t.blockHeader.isSome: + let h = t.blockHeader.get() + check calcTxRoot(t.transactions) == h.txRoot + let enc = rlp.encode(t.uncles) + check keccakHash(enc) == h.ommersHash + + result.add t + +proc runTester(t: Tester, testStatusIMPL: var TestStatus) = + discard + +proc testFixture(node: JsonNode, testStatusIMPL: var TestStatus) = + var t: Tester + for fixtureName, fixture in node: + t.name = fixtureName + echo "TESTING: ", fixtureName + fixture.fromJson "lastblockhash", t.lastBlockHash + t.genesisBlockHeader = parseHeader(fixture["genesisBlockHeader"], testStatusIMPL) + + # none of the fixtures pass this test + #if "genesisRLP" in fixture: + # var genesisRLP: Blob + # fixture.fromJson "genesisRLP", genesisRLP + # check genesisRLP == rlp.encode(t.genesisBlockHeader) + + if "sealEngine" in fixture: + t.sealEngine = some(parseEnum[SealEngine](fixture["sealEngine"].getStr)) + t.network = fixture["network"].getStr + t.blocks = parseBlocks(fixture["blocks"], testStatusIMPL) + + var vmState = newBaseVMState(emptyRlpHash, + t.genesisBlockHeader, newBaseChainDB(newMemoryDb())) + + vmState.mutateStateDB: + setupStateDB(fixture["pre"], db) + + let obtainedHash = $(vmState.readOnlyStateDB.rootHash) + check obtainedHash == $(t.genesisBlockHeader.stateRoot) + + t.runTester(testStatusIMPL) + #verifyStateDB(fixture["postState"], vmState.readOnlyStateDB) + +# lastBlockHash -> every fixture has it, hash of a block header +# genesisRLP -> NOT every fixture has it, rlp bytes of genesis block header +# _info -> every fixture has it, can be omitted +# pre, postState -> every fixture has it, prestate and post state +# genesisBlockHeader -> every fixture has it +# network -> every fixture has it +# # EIP150 247 +# # ConstantinopleFix 286 +# # Homestead 256 +# # Frontier 396 +# # Byzantium 263 +# # EIP158ToByzantiumAt5 1 +# # EIP158 233 +# # HomesteadToDaoAt5 4 +# # Constantinople 285 +# # HomesteadToEIP150At5 1 +# # FrontierToHomesteadAt5 7 +# # ByzantiumToConstantinopleFixAt5 1 + +# sealEngine -> NOT every fixture has it +# # NoProof 1709 +# # Ethash 112 + +# blocks -> every fixture has it, an array of blocks ranging from 1 block to 303 blocks +# # transactions 6230 can be empty +# # # to 6089 -> "" if contractCreation +# # # value 6089 +# # # gasLimit 6089 -> "gas" +# # # s 6089 +# # # r 6089 +# # # gasPrice 6089 +# # # v 6089 +# # # data 6089 -> "input" +# # # nonce 6089 +# # blockHeader 6230 can be not present, e.g. bad rlp +# # uncleHeaders 6230 can be empty + +# # rlp 6810 has rlp but no blockheader, usually has exception +# # blocknumber 2733 +# # chainname 1821 -> 'A' to 'H', and 'AA' to 'DD' +# # chainnetwork 21 -> all values are "Frontier" +# # expectExceptionALL 420 +# # # UncleInChain 55 +# # # InvalidTimestamp 42 +# # # InvalidGasLimit 42 +# # # InvalidNumber 42 +# # # InvalidDifficulty 35 +# # # InvalidBlockNonce 28 +# # # InvalidUncleParentHash 26 +# # # ExtraDataTooBig 21 +# # # InvalidStateRoot 21 +# # # ExtraDataIncorrect 19 +# # # UnknownParent 16 +# # # TooMuchGasUsed 14 +# # # InvalidReceiptsStateRoot 9 +# # # InvalidUnclesHash 7 +# # # UncleIsBrother 7 +# # # UncleTooOld 7 +# # # InvalidTransactionsRoot 7 +# # # InvalidGasUsed 7 +# # # InvalidLogBloom 7 +# # # TooManyUncles 7 +# # # OutOfGasIntrinsic 1 +# # expectExceptionEIP150 17 +# # # TooMuchGasUsed 7 +# # # InvalidReceiptsStateRoot 7 +# # # InvalidStateRoot 3 +# # expectExceptionByzantium 17 +# # # InvalidStateRoot 10 +# # # TooMuchGasUsed 7 +# # expectExceptionHomestead 17 +# # # InvalidReceiptsStateRoot 7 +# # # BlockGasLimitReached 7 +# # # InvalidStateRoot 3 +# # expectExceptionConstantinople 14 +# # # InvalidStateRoot 7 +# # # TooMuchGasUsed 7 +# # expectExceptionEIP158 14 +# # # TooMuchGasUsed 7 +# # # InvalidReceiptsStateRoot 7 +# # expectExceptionFrontier 14 +# # # InvalidReceiptsStateRoot 7 +# # # BlockGasLimitReached 7 +# # expectExceptionConstantinopleFix 14 +# # # InvalidStateRoot 7 +# # # TooMuchGasUsed 7 diff --git a/tests/test_helpers.nim b/tests/test_helpers.nim index 0a00e2275..85532c776 100644 --- a/tests/test_helpers.nim +++ b/tests/test_helpers.nim @@ -107,7 +107,11 @@ func slowTest*(folder: string, name: string): bool = "callcodecallcallcode_ABCB_RECURSIVE.json", "callcodecallcodecall_ABCB_RECURSIVE.json", "callcodecallcodecallcode_ABCB_RECURSIVE.json", - "callcallcallcode_ABCB_RECURSIVE.json"] + "callcallcallcode_ABCB_RECURSIVE.json", + + # BlockChain slow tests + "SuicideIssue.json" + ] func failIn32Bits(folder, name: string): bool = return name in @[