-
Notifications
You must be signed in to change notification settings - Fork 13
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
test: check witness when contract creation fails #333
Changes from all commits
546b27e
ebdd6c2
f7273dc
a874d6e
3833b4d
08e095e
858d642
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -17,6 +17,7 @@ | |
package core | ||
|
||
import ( | ||
"bytes" | ||
"crypto/ecdsa" | ||
|
||
//"fmt" | ||
|
@@ -542,3 +543,132 @@ func TestProcessVerkle(t *testing.T) { | |
} | ||
} | ||
} | ||
|
||
func TestProcessVerkleiInvalidContractCreation(t *testing.T) { | ||
var ( | ||
config = ¶ms.ChainConfig{ | ||
ChainID: big.NewInt(69420), | ||
HomesteadBlock: big.NewInt(0), | ||
EIP150Block: big.NewInt(0), | ||
EIP155Block: big.NewInt(0), | ||
EIP158Block: big.NewInt(0), | ||
ByzantiumBlock: big.NewInt(0), | ||
ConstantinopleBlock: big.NewInt(0), | ||
PetersburgBlock: big.NewInt(0), | ||
IstanbulBlock: big.NewInt(0), | ||
MuirGlacierBlock: big.NewInt(0), | ||
BerlinBlock: big.NewInt(0), | ||
LondonBlock: big.NewInt(0), | ||
Ethash: new(params.EthashConfig), | ||
ShanghaiTime: u64(0), | ||
PragueTime: u64(0), | ||
TerminalTotalDifficulty: common.Big0, | ||
TerminalTotalDifficultyPassed: true, | ||
ProofInBlocks: true, | ||
} | ||
bcdb = rawdb.NewMemoryDatabase() // Database for the blockchain | ||
gendb = rawdb.NewMemoryDatabase() // Database for the block-generation code, they must be separate as they are path-based. | ||
coinbase = common.HexToAddress("0x71562b71999873DB5b286dF957af199Ec94617F7") | ||
account1 = common.HexToAddress("0x687704DB07e902e9A8B3754031D168D46E3D586e") | ||
account2 = common.HexToAddress("0x6177843db3138ae69679A54b95cf345ED759450d") | ||
gspec = &Genesis{ | ||
Config: config, | ||
Alloc: GenesisAlloc{ | ||
coinbase: GenesisAccount{ | ||
Balance: big.NewInt(1000000000000000000), // 1 ether | ||
Nonce: 0, | ||
}, | ||
account1: GenesisAccount{ | ||
Balance: big.NewInt(1000000000000000000), // 1 ether | ||
Nonce: 0, | ||
}, | ||
account2: GenesisAccount{ | ||
Balance: big.NewInt(1000000000000000000), // 1 ether | ||
Nonce: 1, | ||
}, | ||
}, | ||
} | ||
) | ||
// Verkle trees use the snapshot, which must be enabled before the | ||
// data is saved into the tree+database. | ||
genesis := gspec.MustCommit(bcdb) | ||
|
||
// Commit the genesis block to the block-generation database as it | ||
// is now independent of the blockchain database. | ||
gspec.MustCommit(gendb) | ||
|
||
// Create two blocks that reproduce what is happening on kaustinen. | ||
// - The first block contains two failing contract creation transactions, that write to storage before they revert. | ||
// - The second block contains a single failing contract creation transaction, that fails right off the bat. | ||
_, _, _, statediff := GenerateVerkleChain(gspec.Config, genesis, beacon.New(ethash.NewFaker()), gendb, 2, func(i int, gen *BlockGen) { | ||
gen.SetPoS() | ||
|
||
if i == 0 { | ||
var tx1, tx2, tx3 types.Transaction | ||
// SSTORE at slot 105 and reverts | ||
tx1payload := common.Hex2Bytes("f8d48084479c2c18830186a08080b8806000602955bda3f9600060ca55600060695523b360006039551983576000601255b0620c2fde2c592ac2600060bc55e0ac6000606455a63e22600060e655eb607e605c5360a2605d5360c7605e53601d605f5360eb606053606b606153608e60625360816063536079606453601e60655360fc60665360b7606753608b60685383021e7ca0cc20c65a97d2e526b8ec0f4266e8b01bdcde43b9aeb59d8bfb44e8eb8119c109a07a8e751813ae1b2ce734960dbc39a4f954917d7822a2c5d1dca18b06c584131f") | ||
gballet marked this conversation as resolved.
Show resolved
Hide resolved
|
||
if err := tx1.UnmarshalBinary(tx1payload); err != nil { | ||
t.Fatal(err) | ||
} | ||
gen.AddTx(&tx1) | ||
|
||
// SSTORE at slot 133 and reverts | ||
tx2payload := common.Hex2Bytes("02f8db83010f2c01843b9aca0084479c2c18830186a08080b88060006085553fad6000600a55600060565555600060b55506600060cf557f1b8b38183e7bd1bdfaa7123c5a4976e54cce0e42049d841411978fd3595e25c66019527f0538943712953cf08900aae40222a40b2d5a4ac8075ad8cf0870e2be307edbb96039527f9f3174ff85024747041ae7a611acffb987c513c088d90ab288aec080a0cd6ac65ce2cb0a912371f6b5a551ba8caffc22ec55ad4d3cb53de41d05eb77b6a02e0dfe8513dfa6ec7bfd7eda6f5c0dac21b39b982436045e128cec46cfd3f960") | ||
gballet marked this conversation as resolved.
Show resolved
Hide resolved
|
||
if err := tx2.UnmarshalBinary(tx2payload); err != nil { | ||
t.Fatal(err) | ||
} | ||
gen.AddTx(&tx2) | ||
|
||
// this one is a simple transfer that succeeds, necessary to get the correct nonce in the other block. | ||
tx3payload := common.Hex2Bytes("f8e80184479c2c18830186a094bbbbde4ca27f83fc18aa108170547ff57675936a80b8807ff71f7c15faadb969a76a5f54a81a0117e1e743cb7f24e378eda28442ea4c6eb6604a527fb5409e5718d44e23bfffac926e5ea726067f772772e7e19446acba0c853f62f5606a526020608a536088608b536039608c536004608d5360af608e537f7f7675d9f210e0a61564e6d11e7cd75f5bc9009ac9f6b94a0fc63035441a83021e7ba04a4a172d81ebb02847829b76a387ac09749c8b65668083699abe20c887fb9efca07c5b1a990702ec7b31a5e8e3935cd9a77649f8c25a84131229e24ab61aec6093") | ||
if err := tx3.UnmarshalBinary(tx3payload); err != nil { | ||
t.Fatal(err) | ||
} | ||
gen.AddTx(&tx3) | ||
} else { | ||
var tx types.Transaction | ||
// immediately reverts | ||
txpayload := common.Hex2Bytes("01f8d683010f2c028443ad7d0e830186a08080b880b00e7fa3c849dce891cce5fae8a4c46cbb313d6aec0c0ffe7863e05fb7b22d4807674c6055527ffbfcb0938f3e18f7937aa8fa95d880afebd5c4cec0d85186095832d03c85cf8a60755260ab60955360cf6096536066609753606e60985360fa609953609e609a53608e609b536024609c5360f6609d536072609e5360a4609fc080a08fc6f7101f292ff1fb0de8ac69c2d320fbb23bfe61cf327173786ea5daee6e37a044c42d91838ef06646294bf4f9835588aee66243b16a66a2da37641fae4c045f") | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. immediately reverts.
gballet marked this conversation as resolved.
Show resolved
Hide resolved
|
||
if err := tx.UnmarshalBinary(txpayload); err != nil { | ||
t.Fatal(err) | ||
} | ||
gen.AddTx(&tx) | ||
} | ||
}) | ||
|
||
// Check that values 0x29 and 0x05 are found in the storage (and that they lead | ||
// to no update, since the contract creation code reverted) | ||
for _, stemStateDiff := range statediff[0] { | ||
// Check that the value 0x85, which is overflowing the account header, | ||
// is present. | ||
if bytes.Equal(stemStateDiff.Stem[:], common.Hex2Bytes("a10042195481d30478251625e1ccef0e2174dc4e083e81d2566d880373f791")) { | ||
for _, suffixDiff := range stemStateDiff.SuffixDiffs { | ||
if suffixDiff.Suffix != 133 { | ||
t.Fatalf("invalid suffix diff found for %x in block #1: %d\n", stemStateDiff.Stem, suffixDiff.Suffix) | ||
} | ||
} | ||
} else if bytes.Equal(stemStateDiff.Stem[:], common.Hex2Bytes("b24fa84f214459af17d6e3f604811f252cac93146f02d67d7811bbcdfa448b")) { | ||
for _, suffixDiff := range stemStateDiff.SuffixDiffs { | ||
if suffixDiff.Suffix != 105 && suffixDiff.Suffix != 0 && suffixDiff.Suffix != 2 && suffixDiff.Suffix != 3 { | ||
t.Fatalf("invalid suffix diff found for %x in block #1: %d\n", stemStateDiff.Stem, suffixDiff.Suffix) | ||
} | ||
} | ||
} else { | ||
for _, suffixDiff := range stemStateDiff.SuffixDiffs { | ||
if suffixDiff.Suffix > 4 { | ||
t.Fatalf("invalid suffix diff found for %x in block #1: %d\n", stemStateDiff.Stem, suffixDiff.Suffix) | ||
} | ||
} | ||
} | ||
} | ||
|
||
// Check that no account has a value above 4 in the 2nd block as no storage nor | ||
// code should make it to the witness. | ||
for _, stemStateDiff := range statediff[1] { | ||
for _, suffixDiff := range stemStateDiff.SuffixDiffs { | ||
if suffixDiff.Suffix > 4 { | ||
t.Fatalf("invalid suffix diff found for %x in block #2: %d\n", stemStateDiff.Stem, suffixDiff.Suffix) | ||
} | ||
} | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -186,28 +186,6 @@ func GetTreeKeyCodeChunkWithEvaluatedAddress(addressPoint *verkle.Point, chunk * | |
return GetTreeKeyWithEvaluatedAddess(addressPoint, treeIndex, subIndex) | ||
} | ||
|
||
func GetTreeKeyStorageSlot(address []byte, storageKey *uint256.Int) []byte { | ||
pos := storageKey.Clone() | ||
if storageKey.Cmp(codeStorageDelta) < 0 { | ||
pos.Add(HeaderStorageOffset, storageKey) | ||
} else { | ||
pos.Add(MainStorageOffset, storageKey) | ||
} | ||
treeIndex := new(uint256.Int).Div(pos, VerkleNodeWidth) | ||
|
||
// calculate the sub_index, i.e. the index in the stem tree. | ||
// Because the modulus is 256, it's the last byte of treeIndex | ||
subIndexMod := new(uint256.Int).Mod(pos, VerkleNodeWidth) | ||
var subIndex byte | ||
if len(subIndexMod) != 0 { | ||
// uint256 is broken into 4 little-endian quads, | ||
// each with native endianness. Extract the least | ||
// significant byte. | ||
subIndex = byte(subIndexMod[0]) | ||
} | ||
return GetTreeKey(address, treeIndex, subIndex) | ||
} | ||
|
||
Comment on lines
-189
to
-210
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This function is not used anywhere, and is buggy. Removing it. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. not buggy, as it turns out, but still unnecessary |
||
func PointToHash(evaluated *verkle.Point, suffix byte) []byte { | ||
// The output of Byte() is big engian for banderwagon. This | ||
// introduces an imbalance in the tree, because hashes are | ||
|
@@ -289,12 +267,23 @@ func GetTreeKeyStorageSlotTreeIndexes(storageKey []byte) (*uint256.Int, byte) { | |
} | ||
// If the storage slot is in the main storage, we need to add the main storage offset. | ||
|
||
// The first MAIN_STORAGE_OFFSET group will see its | ||
// first 64 slots unreachable. This is either a typo in the | ||
// spec or intended to conserve the 256-u256 | ||
// aligment. If we decide to ever access these 64 | ||
// slots, uncomment this. | ||
// // Get the new offset since we now know that we are above 64. | ||
// pos.Sub(&pos, codeStorageDelta) | ||
// suffix := byte(pos[0] & 0xFF) | ||
suffix := storageKey[len(storageKey)-1] | ||
|
||
// We first divide by VerkleNodeWidth to create room to avoid an overflow next. | ||
pos.Rsh(&pos, uint(VerkleNodeWidthLog2)) | ||
|
||
// We add mainStorageOffset/VerkleNodeWidth which can't overflow. | ||
pos.Add(&pos, mainStorageOffsetLshVerkleNodeWidth) | ||
|
||
// The sub-index is the LSB of the original storage key, since mainStorageOffset | ||
// doesn't affect this byte, so we can avoid masks or shifts. | ||
return &pos, storageKey[len(storageKey)-1] | ||
return &pos, suffix | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
these values are chosen to simulate the state of kaustinen on blocks 13 and 16, since that's what these problematic txs are taken from.