fix t8n tool bug and accounts cache bug

t8n: a silly bug contract address generator, should use original
tx nonce instead of read the nonce from sender address in state db.
Although in EVM contract address generated by reading nonce from state db
is correct, outside EVM that nonce value might have been modified,
thus generating incorrect contract address.

accounts cache: when clearing account storage, the originalValue
cache is not cleared, only the storageRoot set to empty storage root,
this will cause getStorage and getCommitedStorage return wrong value
if the originalValue cache contains old value.
This commit is contained in:
jangko 2023-03-23 09:38:42 +07:00
parent 33023aaf39
commit a31db89e0e
No known key found for this signature in database
GPG Key ID: 31702AE10541E6B9
17 changed files with 338 additions and 18 deletions

View File

@ -474,7 +474,13 @@ proc clearStorage*(ac: AccountsCache, address: EthAddress) =
acc.flags.incl {Alive}
if acc.account.storageRoot != emptyRlpHash:
# there is no point to clone the storage since we want to remove it
ac.makeDirty(address, cloneStorage = false).account.storageRoot = emptyRlpHash
let acc = ac.makeDirty(address, cloneStorage = false)
acc.account.storageRoot = emptyRlpHash
if acc.originalStorage.isNil.not:
# also clear originalStorage cache, otherwise
# both getStorage and getCommittedStorage will
# return wrong value
acc.originalStorage.clear()
proc deleteAccount*(ac: AccountsCache, address: EthAddress) =
# make sure all savepoints already committed
@ -621,13 +627,13 @@ func update(wd: var WitnessData, acc: RefAccount) =
if not acc.originalStorage.isNil:
for k, v in acc.originalStorage:
if v == 0: continue
if v.isZero: continue
wd.storageKeys.incl k
for k, v in acc.overlayStorage:
if v == 0 and k notin wd.storageKeys:
if v.isZero and k notin wd.storageKeys:
continue
if v == 0 and k in wd.storageKeys:
if v.isZero and k in wd.storageKeys:
wd.storageKeys.excl k
continue
wd.storageKeys.incl k

View File

@ -27,7 +27,12 @@ proc initTracer*(tracer: var TransactionTracer, flags: set[TracerFlags] = {}) =
# make appear at the top of json object
tracer.trace["gas"] = %0
tracer.trace["failed"] = %false
if TracerFlags.GethCompatibility in tracer.flags:
tracer.trace["returnData"] = %""
else:
tracer.trace["returnValue"] = %""
tracer.trace["structLogs"] = newJArray()
tracer.flags = flags
tracer.accounts = initHashSet[EthAddress]()
@ -105,7 +110,11 @@ proc traceOpCodeStarted*(tracer: var TransactionTracer, c: Computation, op: Op):
const chunkLen = 32
let numChunks = c.memory.len div chunkLen
for i in 0 ..< numChunks:
mem.add(%c.memory.bytes.toOpenArray(i * chunkLen, (i + 1) * chunkLen - 1).toHex())
let memHex = c.memory.bytes.toOpenArray(i * chunkLen, (i + 1) * chunkLen - 1).toHex()
if TracerFlags.GethCompatibility in tracer.flags:
mem.add(%("0x" & memHex.toLowerAscii))
else:
mem.add(%memHex)
j["memory"] = mem
if TracerFlags.EnableAccount in tracer.flags:
@ -153,6 +162,10 @@ proc traceOpCodeEnded*(tracer: var TransactionTracer, c: Computation, op: Op, la
if op in {Return, Revert} and TracerFlags.DisableReturnData notin tracer.flags:
let returnValue = %("0x" & toHex(c.output, true))
if TracerFlags.GethCompatibility in tracer.flags:
j["returnData"] = returnValue
tracer.trace["returnData"] = returnValue
else:
j["returnValue"] = returnValue
tracer.trace["returnValue"] = returnValue

View File

@ -215,7 +215,7 @@ proc runExecution(ctx: var StateContext, conf: StateConf, pre: JsonNode): StateR
vmState.mutateStateDB:
setupStateDB(pre, db)
db.persist(clearEmptyAccount = false) # settle accounts storage
db.persist(clearEmptyAccount = false, clearCache = false) # settle accounts storage
defer:
ctx.verifyResult(vmState)

View File

@ -421,6 +421,33 @@ const
output: T8nOutput(alloc: true, result: true),
expOut: "exp.json",
),
TestSpec(
name : "Revert In Create In Init Create2",
base : "testdata/00-512",
input : t8nInput(
"alloc.json", "txs.rlp", "env.json", "Berlin", "0"
),
output: T8nOutput(alloc: true, result: true),
expOut: "exp.json",
),
TestSpec(
name : "Revert In Create In Init",
base : "testdata/00-513",
input : t8nInput(
"alloc.json", "txs.rlp", "env.json", "Berlin", "0"
),
output: T8nOutput(alloc: true, result: true),
expOut: "exp.json",
),
TestSpec(
name : "Init collision 3",
base : "testdata/00-514",
input : t8nInput(
"alloc.json", "txs.rlp", "env.json", "Berlin", "0"
),
output: T8nOutput(alloc: true, result: true),
expOut: "exp.json",
),
]
proc main() =

17
tools/t8n/testdata/00-512/alloc.json vendored Normal file
View File

@ -0,0 +1,17 @@
{
"0x6295ee1b4f6dd65047762f924ecd367c17eabf8f" : {
"balance" : "0x00",
"code" : "0x",
"nonce" : "0x00",
"storage" : {
"0x00" : "0x01"
}
},
"0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
"balance" : "0x6400000000",
"code" : "0x",
"nonce" : "0x00",
"storage" : {
}
}
}

13
tools/t8n/testdata/00-512/env.json vendored Normal file
View File

@ -0,0 +1,13 @@
{
"currentCoinbase" : "0x2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
"currentNumber" : "0x01",
"currentTimestamp" : "0x03e8",
"currentGasLimit" : "0x0b00000000",
"previousHash" : "0x2cc639eb8c55bb093f4ff0d92ba81bd90fa97f5dc1ac533e37bdb54a529a10eb",
"parentTimestamp" : "0x00",
"parentDifficulty" : "0x020000",
"parentUncleHash" : "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
"blockHashes" : {
"0" : "0x2cc639eb8c55bb093f4ff0d92ba81bd90fa97f5dc1ac533e37bdb54a529a10eb"
}
}

42
tools/t8n/testdata/00-512/exp.json vendored Normal file
View File

@ -0,0 +1,42 @@
{
"alloc": {
"0x2adc25665018aa1fe0e6bc666dac8fc2697ff9ba": {
"balance": "0x142b84"
},
"0x6295ee1b4f6dd65047762f924ecd367c17eabf8f": {
"storage": {
"0x0000000000000000000000000000000000000000000000000000000000000000": "0x0000000000000000000000000000000000000000000000000000000000000020",
"0x0000000000000000000000000000000000000000000000000000000000000001": "0x0000000000000000000000000000000000000000000000000000000000112233"
},
"balance": "0x0",
"nonce": "0x2"
},
"0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b": {
"balance": "0x63ffebd47c",
"nonce": "0x1"
}
},
"result": {
"stateRoot": "0xe0cfa6916b126d6a08639aa0b928a053b7bba1390535e166c1f5d41068a4fc45",
"txRoot": "0xa9ba46978e16fd6192f2d3f12f1bc7d7a7f92684452c0783378fc17539729c6b",
"receiptsRoot": "0xe385c544fafdddffbf18a71d9c746174b861551d96d534f9d64885158bea37ad",
"logsHash": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
"logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"receipts": [
{
"root": "0x",
"status": "0x1",
"cumulativeGasUsed": "0x2045a",
"logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"logs": null,
"transactionHash": "0xdbb728ec3bb0b37eb49274b839b556865bf27a654f91ef7787ef05e97d1fb15c",
"contractAddress": "0x6295ee1b4f6dd65047762f924ecd367c17eabf8f",
"gasUsed": "0x2045a",
"blockHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
"transactionIndex": "0x0"
}
],
"currentDifficulty": "0x20000",
"gasUsed": "0x2045a"
}
}

1
tools/t8n/testdata/00-512/txs.rlp vendored Normal file
View File

@ -0,0 +1 @@
"0xf886f884800a850a000000008080b630506000600e80602860003960006000f56002553d6000556020600060003e6000516001550000fe6211223360005260206000fd00001ca011b4e962eb5259b1eeb47b3aff0ce65c026d92b840511fecfbec1997ba4abb27a03970e23b1c2140165c823234ebeac740328c396bcee36ea61429a7995d721a70"

17
tools/t8n/testdata/00-513/alloc.json vendored Normal file
View File

@ -0,0 +1,17 @@
{
"0x6295ee1b4f6dd65047762f924ecd367c17eabf8f" : {
"balance" : "0x00",
"code" : "0x",
"nonce" : "0x00",
"storage" : {
"0x00" : "0x01"
}
},
"0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
"balance" : "0x6400000000",
"code" : "0x",
"nonce" : "0x00",
"storage" : {
}
}
}

13
tools/t8n/testdata/00-513/env.json vendored Normal file
View File

@ -0,0 +1,13 @@
{
"currentCoinbase" : "0x2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
"currentNumber" : "0x01",
"currentTimestamp" : "0x03e8",
"currentGasLimit" : "0x0a00000000",
"previousHash" : "0x6c0204de229aa50c7484ed394c4bf826758d2829393b8730becb54fa534fee5d",
"parentTimestamp" : "0x00",
"parentDifficulty" : "0x020000",
"parentUncleHash" : "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
"blockHashes" : {
"0" : "0x6c0204de229aa50c7484ed394c4bf826758d2829393b8730becb54fa534fee5d"
}
}

42
tools/t8n/testdata/00-513/exp.json vendored Normal file
View File

@ -0,0 +1,42 @@
{
"alloc": {
"0x2adc25665018aa1fe0e6bc666dac8fc2697ff9ba": {
"balance": "0x13d300"
},
"0x6295ee1b4f6dd65047762f924ecd367c17eabf8f": {
"storage": {
"0x0000000000000000000000000000000000000000000000000000000000000000": "0x0000000000000000000000000000000000000000000000000000000000000020",
"0x0000000000000000000000000000000000000000000000000000000000000001": "0x0000000000000000000000000000000000000000000000000000000000112233"
},
"balance": "0x0",
"nonce": "0x2"
},
"0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b": {
"balance": "0x63ffec2d00",
"nonce": "0x1"
}
},
"result": {
"stateRoot": "0xd9dac0bdb42187224bd22799fb6d74ee60b019cab5f07e7d6e986d8a05685517",
"txRoot": "0x6b6b3de330c8f068c4e72c00440dfba319a4aff53a124121f89e0a1875488cb4",
"receiptsRoot": "0xf1e764ea6c4f95e27ff8e8e36afa8ef4485d98393f2831f522085fc4e86eae7c",
"logsHash": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
"logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"receipts": [
{
"root": "0x",
"status": "0x1",
"cumulativeGasUsed": "0x1fb80",
"logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"logs": null,
"transactionHash": "0x57ffa2f9cb76c8a72f602a26f2d11774788f38b9424094136d75baaef5f1404e",
"contractAddress": "0x6295ee1b4f6dd65047762f924ecd367c17eabf8f",
"gasUsed": "0x1fb80",
"blockHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
"transactionIndex": "0x0"
}
],
"currentDifficulty": "0x20000",
"gasUsed": "0x1fb80"
}
}

1
tools/t8n/testdata/00-513/txs.rlp vendored Normal file
View File

@ -0,0 +1 @@
"0xf881f87f800a8509fd8000018080b13050600d80602460003960006000f0503d6000556020600060003e6000516001550000fe6211223360005260206000fd001ca0d448c413515435193344f59d8f02f9aca6ca8de5558450966b8b6883ceac9c60a01cf76c2dedce616e99b6cf02541e94c8952f8c1c6c203501ab925d4bd63a9bf2"

32
tools/t8n/testdata/00-514/alloc.json vendored Normal file
View File

@ -0,0 +1,32 @@
{
"0x6295ee1b4f6dd65047762f924ecd367c17eabf8f" : {
"balance" : "0x00",
"code" : "0x",
"nonce" : "0x00",
"storage" : {
"0x01" : "0x01"
}
},
"0x7b9f5332c245e5c60923427eeb34e5adfba6470e" : {
"balance" : "0x00",
"code" : "0x",
"nonce" : "0x00",
"storage" : {
"0x01" : "0x01"
}
},
"0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
"balance" : "0xe8d4a51000",
"code" : "0x",
"nonce" : "0x00",
"storage" : {
}
},
"0xdea0000000000000000000000000000000000000" : {
"balance" : "0x00",
"code" : "0x6001600155600060015560016002556000600255600160035560006003556001600455600060045560016005556000600555600160065560006006556001600755600060075560016008556000600855600160095560006009556001600a556000600a556001600b556000600b556001600c556000600c556001600d556000600d556001600e556000600e556001600f556000600f5560016010556000601055600160015500",
"nonce" : "0x00",
"storage" : {
}
}
}

13
tools/t8n/testdata/00-514/env.json vendored Normal file
View File

@ -0,0 +1,13 @@
{
"currentCoinbase" : "0x2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
"currentNumber" : "0x01",
"currentTimestamp" : "0x03e8",
"currentGasLimit" : "0x989680",
"previousHash" : "0x0d0d6418086e66423a1d501d941dffa888f0c907772024ec0607101bccbb9572",
"parentTimestamp" : "0x00",
"parentDifficulty" : "0x020000",
"parentUncleHash" : "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
"blockHashes" : {
"0" : "0x0d0d6418086e66423a1d501d941dffa888f0c907772024ec0607101bccbb9572"
}
}

49
tools/t8n/testdata/00-514/exp.json vendored Normal file
View File

@ -0,0 +1,49 @@
{
"alloc": {
"0x2adc25665018aa1fe0e6bc666dac8fc2697ff9ba": {
"balance": "0x1e4e02"
},
"0x6295ee1b4f6dd65047762f924ecd367c17eabf8f": {
"balance": "0x0",
"nonce": "0x2"
},
"0x7b9f5332c245e5c60923427eeb34e5adfba6470e": {
"storage": {
"0x0000000000000000000000000000000000000000000000000000000000000001": "0x0000000000000000000000000000000000000000000000000000000000000001"
},
"balance": "0x0",
"nonce": "0x1"
},
"0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b": {
"balance": "0xe8d486c1fe",
"nonce": "0x1"
},
"0xdea0000000000000000000000000000000000000": {
"code": "0x6001600155600060015560016002556000600255600160035560006003556001600455600060045560016005556000600555600160065560006006556001600755600060075560016008556000600855600160095560006009556001600a556000600a556001600b556000600b556001600c556000600c556001600d556000600d556001600e556000600e556001600f556000600f5560016010556000601055600160015500",
"balance": "0x0"
}
},
"result": {
"stateRoot": "0x16d0fd49f5ee712bdad56326e859088ee949b87666b8a1aa6d146ae62f00d879",
"txRoot": "0x875c38cccd9ebeab40d7ff716a3010ede2b215f530a341271d7312d8f444c3b2",
"receiptsRoot": "0x43be55e1ef1e34ceaa4be0c9515bb0a672b25ab41fa9a781d41379777113119b",
"logsHash": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
"logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"receipts": [
{
"root": "0x",
"status": "0x1",
"cumulativeGasUsed": "0x307cd",
"logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"logs": null,
"transactionHash": "0x96cc2aefef7009d456429678da71afdbd182f7e9d4a133b1c74c547083ef11b0",
"contractAddress": "0x6295ee1b4f6dd65047762f924ecd367c17eabf8f",
"gasUsed": "0x307cd",
"blockHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
"transactionIndex": "0x0"
}
],
"currentDifficulty": "0x20000",
"gasUsed": "0x307cd"
}
}

1
tools/t8n/testdata/00-514/txs.rlp vendored Normal file
View File

@ -0,0 +1 @@
"0xf892f890800a83030d408080b8436000600b80603860003960006000f5506000600060006000600073dea000000000000000000000000000000000000062030d40f1500000fe60006001556001600155001ba0738661332ef09477d9cf9796cb738868c71b2a5def898669e685fc5519aadc9fa015e8509b1f8f96b8001ee77fa1745d04d370399092953ec09a996012d4f99e56"

View File

@ -9,7 +9,7 @@
# according to those terms.
import
std/[json, strutils, times, tables, os, math],
std/[json, strutils, times, tables, os, math, streams],
eth/[rlp, trie, eip1559],
stint, stew/results,
"."/[config, types, helpers],
@ -114,8 +114,7 @@ proc postState(db: AccountsCache, alloc: var GenesisAlloc) =
proc genAddress(vmState: BaseVMState, tx: Transaction, sender: EthAddress): EthAddress =
if tx.to.isNone:
let creationNonce = vmState.readOnlyStateDB().getNonce(sender)
result = generateAddress(sender, creationNonce)
result = generateAddress(sender, tx.nonce)
proc toTxReceipt(vmState: BaseVMState,
rec: Receipt,
@ -145,9 +144,42 @@ proc calcLogsHash(receipts: openArray[Receipt]): Hash256 =
logs.add rec.logs
rlpHash(logs)
proc dumpTrace(txIndex: int, txHash: Hash256, traceResult: JsonNode) =
let fName = "trace-$1-$2.jsonl" % [$txIndex, $txHash]
writeFile(fName, traceResult.pretty)
template stripLeadingZeros(value: string): string =
var cidx = 0
# ignore the last character so we retain '0' on zero value
while cidx < value.len - 1 and value[cidx] == '0':
cidx.inc
value[cidx .. ^1]
proc encodeHexInt(x: SomeInteger): JsonNode =
%("0x" & x.toHex.stripLeadingZeros.toLowerAscii)
proc toHex(x: Hash256): string =
"0x" & x.data.toHex
proc dumpTrace(txIndex: int, txHash: Hash256, vmState: BaseVMstate) =
let txHash = "0x" & toLowerAscii($txHash)
let fName = "trace-$1-$2.jsonl" % [$txIndex, txHash]
let trace = vmState.getTracingResult()
var s = newFileStream(fName, fmWrite)
trace["gasUsed"] = encodeHexInt(vmState.tracerGasUsed)
trace.delete("gas")
let stateRoot = %{
"stateRoot": %(vmState.readOnlyStateDB.rootHash.toHex)
}
let logs = trace["structLogs"]
trace.delete("structLogs")
for x in logs:
if "error" in x:
trace["error"] = x["error"]
x.delete("error")
s.writeLine($x)
s.writeLine($trace)
s.writeLine($stateRoot)
s.close()
func gwei(n: uint64): UInt256 =
n.u256 * (10 ^ 9).u256
@ -192,7 +224,7 @@ proc exec(ctx: var TransContext,
let rc = vmState.processTransaction(tx, sender, header)
if vmState.tracingEnabled:
dumpTrace(txIndex, rlpHash(tx), vmState.getTracingResult)
dumpTrace(txIndex, rlpHash(tx), vmState)
if rc.isErr:
rejected.add RejectedTx(
@ -321,7 +353,8 @@ proc transitionAction*(ctx: var TransContext, conf: T8NConf) =
TracerFlags.DisableStorage,
TracerFlags.DisableState,
TracerFlags.DisableStateDiff,
TracerFlags.DisableReturnData
TracerFlags.DisableReturnData,
TracerFlags.GethCompatibility
}
if conf.traceEnabled: