implement account code encoding and decoding

This commit is contained in:
andri lim 2020-04-28 16:58:16 +07:00
parent 2ae02fd629
commit 4de8eaa81d
No known key found for this signature in database
GPG Key ID: 31702AE10541E6B9
3 changed files with 43 additions and 33 deletions

View File

@ -1,9 +1,12 @@
import import
randutils, stew/byteutils, random, randutils, stew/byteutils, random,
eth/[common, rlp], eth/trie/[hexary, db], eth/[common, rlp], eth/trie/[hexary, db, trie_defs],
faststreams/input_stream, nimcrypto/[utils, sysrand], faststreams/input_stream, nimcrypto/[utils, sysrand],
../stateless/[witness_from_tree, tree_from_witness] ../stateless/[witness_from_tree, tree_from_witness]
type
DB = TrieDatabaseRef
proc randU256(): UInt256 = proc randU256(): UInt256 =
var bytes: array[32, byte] var bytes: array[32, byte]
discard randomBytes(bytes[0].addr, sizeof(result)) discard randomBytes(bytes[0].addr, sizeof(result))
@ -12,56 +15,53 @@ proc randU256(): UInt256 =
proc randNonce(): AccountNonce = proc randNonce(): AccountNonce =
discard randomBytes(result.addr, sizeof(result)) discard randomBytes(result.addr, sizeof(result))
proc randCode(db: DB): Hash256 =
if rand(0..1) == 0:
result = blankStringHash
else:
let codeLen = rand(1..150)
let code = randList(byte, rng(0, 255), codeLen, unique = false)
result = hexary.keccak(code)
db.put(result.data, code)
proc randHash(): Hash256 = proc randHash(): Hash256 =
discard randomBytes(result.data[0].addr, sizeof(result)) discard randomBytes(result.data[0].addr, sizeof(result))
proc randAccount(): Account = proc randAccount(db: DB): Account =
result.nonce = randNonce() result.nonce = randNonce()
result.balance = randU256() result.balance = randU256()
result.codeHash = randHash() result.codeHash = randCode(db)
result.storageRoot = randHash() result.storageRoot = randHash()
proc runTest(keyBytes: int, valBytes: int, numPairs: int) = proc runTest(numPairs: int) =
var memDB = newMemoryDB() var memDB = newMemoryDB()
var trie = initHexaryTrie(memDB) var trie = initSecureHexaryTrie(memDB)
var addrs = newSeq[Bytes](numPairs)
var
keys = newSeq[Bytes](numPairs)
vals = newSeq[Bytes](numPairs)
for i in 0..<numPairs: for i in 0..<numPairs:
keys[i] = randList(byte, rng(0, 255), keyBytes, unique = false) addrs[i] = randList(byte, rng(0, 255), 20, unique = false)
vals[i] = randList(byte, rng(0, 255), valBytes, unique = false) let acc = randAccount(memDB)
trie.put(keys[i], vals[i]) trie.put(addrs[i], rlp.encode(acc))
let rootHash = trie.rootHash let rootHash = trie.rootHash
var wb = initWitnessBuilder(memDB, rootHash) var wb = initWitnessBuilder(memDB, rootHash)
var witness = wb.getBranchRecurse(keys[0]) var witness = wb.getBranchRecurse(addrs[0])
var input = memoryInput(witness)
var db = newMemoryDB() var db = newMemoryDB()
var tb = initTreeBuilder(input, db) when defined(useInputStream):
var input = memoryInput(witness)
var tb = initTreeBuilder(input, db)
else:
var tb = initTreeBuilder(witness, db)
var root = tb.treeNode() var root = tb.treeNode()
debugEcho "root: ", root.data.toHex debugEcho "root: ", root.data.toHex
debugEcho "rootHash: ", rootHash.data.toHex debugEcho "rootHash: ", rootHash.data.toHex
doAssert root.data == rootHash.data doAssert root.data == rootHash.data
proc main() = proc main() =
runTest(7, 100, 50)
runTest(1, 1, 1)
runTest(5, 5, 1)
runTest(6, 7, 3)
runTest(7, 10, 7)
runTest(8, 15, 11)
runTest(9, 30, 13)
runTest(11, 40, 10)
runTest(20, 1, 15)
runTest(25, 10, 20)
randomize() randomize()
for i in 0..<30:
runTest(rand(1..30), rand(1..50), rand(1..30))
for i in 0..<30:
runTest(rand(1..30))
main() main()

View File

@ -213,8 +213,10 @@ proc extensionNode(t: var TreeBuilder, depth: int): NodeKey =
proc accountNode(t: var TreeBuilder, depth: int): NodeKey = proc accountNode(t: var TreeBuilder, depth: int): NodeKey =
assert(depth < 65) assert(depth < 65)
let len = t.readU32().int
result = toNodeKey(t.read(len)) when defined(debugHash):
let len = t.readU32().int
let nodeKey = toNodeKey(t.read(len))
when defined(debugDepth): when defined(debugDepth):
let readDepth = t.readByte.int let readDepth = t.readByte.int
@ -247,6 +249,12 @@ proc accountNode(t: var TreeBuilder, depth: int): NodeKey =
doAssert(storageRoot.usedBytes == 32) doAssert(storageRoot.usedBytes == 32)
acc.storageRoot.data = storageRoot.data acc.storageRoot.data = storageRoot.data
r.append rlp.encode(acc)
result = toNodeKey(r.finish)
when defined(debugHash):
doAssert(result == nodeKey, "account node parsing error")
proc accountStorageLeafNode(t: var TreeBuilder, depth: int): NodeKey = proc accountStorageLeafNode(t: var TreeBuilder, depth: int): NodeKey =
assert(depth < 65) assert(depth < 65)
let nibblesLen = 64 - depth let nibblesLen = 64 - depth

View File

@ -95,8 +95,10 @@ proc writeHashNode(wb: var WitnessBuilder, node: openArray[byte]) =
proc writeAccountNode(wb: var WitnessBuilder, acc: Account, nibbles: NibblesSeq, node: openArray[byte], depth: int) = proc writeAccountNode(wb: var WitnessBuilder, acc: Account, nibbles: NibblesSeq, node: openArray[byte], depth: int) =
# write type # write type
wb.output.append(AccountNodeType.byte) wb.output.append(AccountNodeType.byte)
wb.writeU32(node.len.uint32)
wb.output.append(node) when defined(debugHash):
wb.writeU32(node.len.uint32)
wb.output.append(node)
when defined(debugDepth): when defined(debugDepth):
wb.output.append(depth.byte) wb.output.append(depth.byte)