-
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
Record witness access in EXTCODEHASH #370
Changes from all commits
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 |
---|---|---|
|
@@ -37,6 +37,7 @@ import ( | |
"github.com/ethereum/go-ethereum/core/vm" | ||
"github.com/ethereum/go-ethereum/crypto" | ||
"github.com/ethereum/go-ethereum/params" | ||
"github.com/ethereum/go-ethereum/trie/utils" | ||
|
||
//"github.com/ethereum/go-ethereum/rlp" | ||
"github.com/ethereum/go-ethereum/trie" | ||
|
@@ -794,3 +795,135 @@ func TestProcessVerkleContractWithEmptyCode(t *testing.T) { | |
} | ||
} | ||
} | ||
|
||
func TestProcessVerklExtCodeHashOpcode(t *testing.T) { | ||
var ( | ||
config = ¶ms.ChainConfig{ | ||
ChainID: big.NewInt(69421), | ||
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, | ||
} | ||
signer = types.LatestSigner(config) | ||
testKey, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291") | ||
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: 3, | ||
}, | ||
}, | ||
} | ||
) | ||
// 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) | ||
|
||
dummyContract := []byte{ | ||
0x60, 2, // PUSH1 2 | ||
0x60, 12, // PUSH1 12 | ||
0x60, 0x00, // PUSH1 0 | ||
0x39, // CODECOPY | ||
|
||
0x60, 2, // PUSH1 2 | ||
0x60, 0x00, // PUSH1 0 | ||
0xF3, // RETURN | ||
|
||
// Contract that auto-calls EXTCODEHASH | ||
0x60, 42, // PUSH1 42 | ||
} | ||
dummyContractAddr := common.HexToAddress("3a220f351252089d385b29beca14e27f204c296a") | ||
extCodeHashContract := []byte{ | ||
0x60, 22, // PUSH1 22 | ||
0x60, 12, // PUSH1 12 | ||
0x60, 0x00, // PUSH1 0 | ||
0x39, // CODECOPY | ||
|
||
0x60, 22, // PUSH1 22 | ||
0x60, 0x00, // PUSH1 0 | ||
0xF3, // RETURN | ||
|
||
// Contract that auto-calls EXTCODEHASH | ||
0x73, // PUSH20 | ||
0x3a, 0x22, 0x0f, 0x35, 0x12, 0x52, 0x08, 0x9d, 0x38, 0x5b, 0x29, 0xbe, 0xca, 0x14, 0xe2, 0x7f, 0x20, 0x4c, 0x29, 0x6a, | ||
0x3F, // EXTCODEHASH | ||
} | ||
Comment on lines
+868
to
+882
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. Deploy another contract that actually makes the This was required to be super clear about witness checks. Initially, I made the dummy contract "auto call" EXTCODEHASH, but then is hard to distinguish why the witness have the contract code hash (e.g: from deployment or from EXTCODEHASH exec). |
||
extCodeHashContractAddr := common.HexToAddress("db7d6ab1f17c6b31909ae466702703daef9269cf") | ||
_, _, _, statediff := GenerateVerkleChain(gspec.Config, genesis, beacon.New(ethash.NewFaker()), gendb, 2, func(i int, gen *BlockGen) { | ||
gen.SetPoS() | ||
|
||
if i == 0 { | ||
// Create dummy contract. | ||
tx, _ := types.SignTx(types.NewContractCreation(0, big.NewInt(0), 100_000, big.NewInt(875000000), dummyContract), signer, testKey) | ||
gen.AddTx(tx) | ||
|
||
// Create contract with EXTCODEHASH opcode. | ||
tx, _ = types.SignTx(types.NewContractCreation(1, big.NewInt(0), 100_000, big.NewInt(875000000), extCodeHashContract), signer, testKey) | ||
gen.AddTx(tx) | ||
Comment on lines
+888
to
+894
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. In the first block deploy both contracts. |
||
} else { | ||
tx, _ := types.SignTx(types.NewTransaction(2, extCodeHashContractAddr, big.NewInt(0), 100_000, big.NewInt(875000000), nil), signer, testKey) | ||
gen.AddTx(tx) | ||
Comment on lines
+896
to
+897
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. In the next block do the actual execution, so if the witness shows the contract code hash address then we know its' from EXTCODEHASH execution and not contract deployments. |
||
} | ||
|
||
}) | ||
|
||
contractKeccakTreeKey := utils.GetTreeKeyCodeKeccak(dummyContractAddr[:]) | ||
|
||
var stateDiffIdx = -1 | ||
for i, stemStateDiff := range statediff[1] { | ||
if bytes.Equal(stemStateDiff.Stem[:], contractKeccakTreeKey[:31]) { | ||
stateDiffIdx = i | ||
break | ||
} | ||
} | ||
if stateDiffIdx == -1 { | ||
t.Fatalf("no state diff found for stem") | ||
} | ||
|
||
codeHashStateDiff := statediff[1][stateDiffIdx].SuffixDiffs[0] | ||
if codeHashStateDiff.Suffix != utils.CodeKeccakLeafKey { | ||
t.Fatalf("code hash invalid suffix") | ||
} | ||
if codeHashStateDiff.CurrentValue == nil { | ||
t.Fatalf("codeHash.CurrentValue must not be empty") | ||
} | ||
expCodeHash := crypto.Keccak256Hash(dummyContract[12:]) | ||
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. Avoiding magical hashes, so we know it's correct. |
||
if *codeHashStateDiff.CurrentValue != expCodeHash { | ||
t.Fatalf("codeHash.CurrentValue unexpected code hash") | ||
} | ||
if codeHashStateDiff.NewValue != nil { | ||
t.Fatalf("codeHash.NewValue must be nil") | ||
} | ||
} |
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.
Deploy
dummyContract
so we have some contract to use EXTCODEHASH later.