implement account code encoding and decoding
This commit is contained in:
parent
2ae02fd629
commit
4de8eaa81d
|
@ -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()
|
||||||
|
when defined(useInputStream):
|
||||||
|
var input = memoryInput(witness)
|
||||||
var tb = initTreeBuilder(input, db)
|
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()
|
||||||
|
|
|
@ -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)
|
||||||
|
|
||||||
|
when defined(debugHash):
|
||||||
let len = t.readU32().int
|
let len = t.readU32().int
|
||||||
result = toNodeKey(t.read(len))
|
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
|
||||||
|
|
|
@ -95,6 +95,8 @@ 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)
|
||||||
|
|
||||||
|
when defined(debugHash):
|
||||||
wb.writeU32(node.len.uint32)
|
wb.writeU32(node.len.uint32)
|
||||||
wb.output.append(node)
|
wb.output.append(node)
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue