Commit cba80384 authored by Adrian Sutton's avatar Adrian Sutton Committed by GitHub

op-challenger: Add support for calling challenge methods to preimage oracle bindings (#9184)

* op-challenger: Add support for calling challenge methods to preimage oracle bindings.

* op-challenger: Include merkle proofs in oracle calls.

Fix dependency cycle by removing references to types.Leaf from BinaryMerkleTree and just accept the leaf hash to add.

* op-challenger: Undo switch from error to panic.
parent 287cb116
...@@ -30,6 +30,8 @@ const ( ...@@ -30,6 +30,8 @@ const (
methodProposalBlocks = "proposalBlocks" methodProposalBlocks = "proposalBlocks"
methodPreimagePartOk = "preimagePartOk" methodPreimagePartOk = "preimagePartOk"
methodMinProposalSize = "minProposalSize" methodMinProposalSize = "minProposalSize"
methodChallengeFirstLPP = "challengeFirstLPP"
methodChallengeLPP = "challengeLPP"
) )
var ( var (
...@@ -126,7 +128,10 @@ func (c *PreimageOracleContract) Squeeze( ...@@ -126,7 +128,10 @@ func (c *PreimageOracleContract) Squeeze(
// abiEncodeStateMatrix encodes the state matrix for the contract ABI // abiEncodeStateMatrix encodes the state matrix for the contract ABI
func abiEncodeStateMatrix(stateMatrix *matrix.StateMatrix) bindings.LibKeccakStateMatrix { func abiEncodeStateMatrix(stateMatrix *matrix.StateMatrix) bindings.LibKeccakStateMatrix {
packedState := stateMatrix.PackState() return abiEncodePackedState(stateMatrix.PackState())
}
func abiEncodePackedState(packedState []byte) bindings.LibKeccakStateMatrix {
stateSlice := new([25]uint64) stateSlice := new([25]uint64)
// SAFETY: a maximum of 25 * 8 bytes will be read from packedState and written to stateSlice // SAFETY: a maximum of 25 * 8 bytes will be read from packedState and written to stateSlice
for i := 0; i < min(len(packedState), 25*8); i += 8 { for i := 0; i < min(len(packedState), 25*8); i += 8 {
...@@ -242,6 +247,29 @@ func (c *PreimageOracleContract) GlobalDataExists(ctx context.Context, data *typ ...@@ -242,6 +247,29 @@ func (c *PreimageOracleContract) GlobalDataExists(ctx context.Context, data *typ
return results.GetBool(0), nil return results.GetBool(0), nil
} }
func (c *PreimageOracleContract) ChallengeTx(ident keccakTypes.LargePreimageIdent, challenge keccakTypes.Challenge) (txmgr.TxCandidate, error) {
var call *batching.ContractCall
if challenge.Prestate == (keccakTypes.Leaf{}) {
call = c.contract.Call(
methodChallengeFirstLPP,
ident.Claimant,
ident.UUID,
toPreimageOracleLeaf(challenge.Poststate),
challenge.PoststateProof)
} else {
call = c.contract.Call(
methodChallengeLPP,
ident.Claimant,
ident.UUID,
abiEncodePackedState(challenge.StateMatrix),
toPreimageOracleLeaf(challenge.Prestate),
challenge.PrestateProof,
toPreimageOracleLeaf(challenge.Poststate),
challenge.PoststateProof)
}
return call.ToTxCandidate()
}
func (c *PreimageOracleContract) decodePreimageIdent(result *batching.CallResult) keccakTypes.LargePreimageIdent { func (c *PreimageOracleContract) decodePreimageIdent(result *batching.CallResult) keccakTypes.LargePreimageIdent {
return keccakTypes.LargePreimageIdent{ return keccakTypes.LargePreimageIdent{
Claimant: result.GetAddress(0), Claimant: result.GetAddress(0),
......
package contracts package contracts
import ( import (
"bytes"
"context" "context"
"fmt" "fmt"
"math" "math"
...@@ -472,6 +473,84 @@ func TestDecodeInputData(t *testing.T) { ...@@ -472,6 +473,84 @@ func TestDecodeInputData(t *testing.T) {
} }
} }
func TestChallenge_First(t *testing.T) {
stubRpc, oracle := setupPreimageOracleTest(t)
ident := keccakTypes.LargePreimageIdent{
Claimant: common.Address{0xab},
UUID: big.NewInt(4829),
}
challenge := keccakTypes.Challenge{
StateMatrix: []byte{1, 2, 3, 4, 5},
Prestate: keccakTypes.Leaf{},
Poststate: keccakTypes.Leaf{
Input: [136]byte{5, 4, 3, 2, 1},
Index: big.NewInt(0),
StateCommitment: common.Hash{0xbb},
},
PoststateProof: merkle.Proof{common.Hash{0x01}, common.Hash{0x02}},
}
stubRpc.SetResponse(oracleAddr, methodChallengeFirstLPP, batching.BlockLatest,
[]interface{}{
ident.Claimant, ident.UUID,
bindings.PreimageOracleLeaf{
Input: challenge.Poststate.Input[:],
Index: challenge.Poststate.Index,
StateCommitment: challenge.Poststate.StateCommitment,
},
challenge.PoststateProof,
},
nil)
tx, err := oracle.ChallengeTx(ident, challenge)
require.NoError(t, err)
stubRpc.VerifyTxCandidate(tx)
}
func TestChallenge_NotFirst(t *testing.T) {
stubRpc, oracle := setupPreimageOracleTest(t)
ident := keccakTypes.LargePreimageIdent{
Claimant: common.Address{0xab},
UUID: big.NewInt(4829),
}
challenge := keccakTypes.Challenge{
StateMatrix: bytes.Repeat([]byte{1, 2, 3, 4, 5, 6, 7, 8}, 25),
Prestate: keccakTypes.Leaf{
Input: [136]byte{9, 8, 7, 6, 5},
Index: big.NewInt(3),
StateCommitment: common.Hash{0xcc},
},
PrestateProof: merkle.Proof{common.Hash{0x01}, common.Hash{0x02}},
Poststate: keccakTypes.Leaf{
Input: [136]byte{5, 4, 3, 2, 1},
Index: big.NewInt(4),
StateCommitment: common.Hash{0xbb},
},
PoststateProof: merkle.Proof{common.Hash{0x03}, common.Hash{0x04}},
}
stubRpc.SetResponse(oracleAddr, methodChallengeLPP, batching.BlockLatest,
[]interface{}{
ident.Claimant, ident.UUID,
abiEncodePackedState(challenge.StateMatrix),
bindings.PreimageOracleLeaf{
Input: challenge.Prestate.Input[:],
Index: challenge.Prestate.Index,
StateCommitment: challenge.Prestate.StateCommitment,
},
challenge.PrestateProof,
bindings.PreimageOracleLeaf{
Input: challenge.Poststate.Input[:],
Index: challenge.Poststate.Index,
StateCommitment: challenge.Poststate.StateCommitment,
},
challenge.PoststateProof,
},
nil)
tx, err := oracle.ChallengeTx(ident, challenge)
require.NoError(t, err)
stubRpc.VerifyTxCandidate(tx)
}
func toAddLeavesTxData(t *testing.T, oracle *PreimageOracleContract, uuid *big.Int, inputData keccakTypes.InputData) []byte { func toAddLeavesTxData(t *testing.T, oracle *PreimageOracleContract, uuid *big.Int, inputData keccakTypes.InputData) []byte {
tx, err := oracle.AddLeaves(uuid, big.NewInt(1), inputData.Input, inputData.Commitments, inputData.Finalize) tx, err := oracle.AddLeaves(uuid, big.NewInt(1), inputData.Input, inputData.Commitments, inputData.Finalize)
require.NoError(t, err) require.NoError(t, err)
......
...@@ -63,6 +63,7 @@ func Challenge(data io.Reader, commitments []common.Hash) (types.Challenge, erro ...@@ -63,6 +63,7 @@ func Challenge(data io.Reader, commitments []common.Hash) (types.Challenge, erro
} }
if validCommitment != claimedCommitment { if validCommitment != claimedCommitment {
// TODO(client-pod#480): Add merkle proofs for these (invalid) leaves
return types.Challenge{ return types.Challenge{
StateMatrix: m, StateMatrix: m,
Prestate: prestate, Prestate: prestate,
...@@ -204,7 +205,7 @@ func (d *StateMatrix) absorbNextLeafInput(in io.Reader) ([]byte, error) { ...@@ -204,7 +205,7 @@ func (d *StateMatrix) absorbNextLeafInput(in io.Reader) ([]byte, error) {
d.prestateLeaf = d.poststateLeaf d.prestateLeaf = d.poststateLeaf
d.poststateLeaf = newLeafWithPadding(input, new(big.Int).Add(d.prestateLeaf.Index, big.NewInt(1)), d.StateCommitment()) d.poststateLeaf = newLeafWithPadding(input, new(big.Int).Add(d.prestateLeaf.Index, big.NewInt(1)), d.StateCommitment())
} }
d.merkleTree.AddLeaf(d.poststateLeaf) d.merkleTree.AddLeaf(d.poststateLeaf.Hash())
if final { if final {
return input, io.EOF return input, io.EOF
} }
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
}, },
{ {
"name": "SingleLeaf", "name": "SingleLeaf",
"rootHash": "0xde8451f1c4f0153718b46951d0764a63e979fa13d496e709cceafcdbbe4ae68c", "rootHash": "0x8285ae2d9ccfc8021051c1ea3dfa5ba8219605d0e28c941f1bc174822eda1154",
"leafCount": 1, "leafCount": 1,
"index": 0, "index": 0,
"proofs": [ "proofs": [
...@@ -32,11 +32,11 @@ ...@@ -32,11 +32,11 @@
}, },
{ {
"name": "TwoLeaves", "name": "TwoLeaves",
"rootHash": "0xcaa0130e02ef997ebab07643394f7fa90767a68c49170669a9262573bfc46116", "rootHash": "0x2f27513ae8b07634c3ac408e55e7b4b6d0dc400e3fa9b2165607d61a84625608",
"leafCount": 2, "leafCount": 2,
"index": 1, "index": 1,
"proofs": [ "proofs": [
"0xcfd23b6298abaea12ade48cd472295893b7facf37c92f425e50722a72ed084ac", "0xff00000000000000000000000000000000000000000000000000000000000000",
"0xad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5", "0xad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5",
"0xb4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30", "0xb4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30",
"0x21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85", "0x21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85",
...@@ -56,11 +56,11 @@ ...@@ -56,11 +56,11 @@
}, },
{ {
"name": "SingleLeaf", "name": "SingleLeaf",
"rootHash": "0xde8451f1c4f0153718b46951d0764a63e979fa13d496e709cceafcdbbe4ae68c", "rootHash": "0x8285ae2d9ccfc8021051c1ea3dfa5ba8219605d0e28c941f1bc174822eda1154",
"leafCount": 1, "leafCount": 1,
"index": 1, "index": 1,
"proofs": [ "proofs": [
"0xcfd23b6298abaea12ade48cd472295893b7facf37c92f425e50722a72ed084ac", "0xff00000000000000000000000000000000000000000000000000000000000000",
"0xad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5", "0xad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5",
"0xb4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30", "0xb4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30",
"0x21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85", "0x21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85",
...@@ -80,15 +80,15 @@ ...@@ -80,15 +80,15 @@
}, },
{ {
"name": "PartialTree", "name": "PartialTree",
"rootHash": "0x2e1c9c8d6e2ab9051b2ea6f77e58302dbb6f06b9dddda46a83a8ca5c8690fed7", "rootHash": "0x72cdab4557ab96d1246b76e49b1d1a582662ebfceafe2f9c2922304d4fb9db33",
"leafCount": 20, "leafCount": 20,
"index": 10, "index": 10,
"proofs": [ "proofs": [
"0x30009b412aade7d8309511a4408ae2f4b72573dde601905693af9f3abb2e1dc8", "0xff0b000000000000000000000000000000000000000000000000000000000000",
"0xa7ca9b77295eadcfe6d58ef5e86e88432a0417b36ac6e4ab2d2e9d45702292e5", "0xa68dfd9074d20ce110c771102e62f17a85ae562a56149e112dd4fecb6cbd8f52",
"0x0a8eb56a75e17742db02f5de94120005cfe95e26c80891de57e390b3e6a3ebc5", "0x892339d3cfe686a15b728211f6a3e4f21cf4ee128b152664c90f231f5a9f8333",
"0xc9909a93d2c0248ef490da737dabda9e41eb3d9a379ddb004cfe66c60f3072df", "0xd8ca500dee0f1f7334075ebef1e979652b70355c56e09b74d50c87e31e675ddb",
"0xa063b1a2583a43114cd150b3c2320fe0bccf5f1b0f75c92c9d7e55433a291517", "0x0c9a9c89e79e068154f6c2b9b827cd4f3972e035542ebb68d68b9120e757626c",
"0x0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d", "0x0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d",
"0x887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968", "0x887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968",
"0xffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83", "0xffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83",
...@@ -104,15 +104,15 @@ ...@@ -104,15 +104,15 @@
}, },
{ {
"name": "PartialTree", "name": "PartialTree",
"rootHash": "0x2e1c9c8d6e2ab9051b2ea6f77e58302dbb6f06b9dddda46a83a8ca5c8690fed7", "rootHash": "0x72cdab4557ab96d1246b76e49b1d1a582662ebfceafe2f9c2922304d4fb9db33",
"leafCount": 20, "leafCount": 20,
"index": 11, "index": 11,
"proofs": [ "proofs": [
"0x536c2dfcd1e4d209e13b2e17323dc3d71171114b4ea9481dcfaac0361eeaffae", "0xff0a000000000000000000000000000000000000000000000000000000000000",
"0xa7ca9b77295eadcfe6d58ef5e86e88432a0417b36ac6e4ab2d2e9d45702292e5", "0xa68dfd9074d20ce110c771102e62f17a85ae562a56149e112dd4fecb6cbd8f52",
"0x0a8eb56a75e17742db02f5de94120005cfe95e26c80891de57e390b3e6a3ebc5", "0x892339d3cfe686a15b728211f6a3e4f21cf4ee128b152664c90f231f5a9f8333",
"0xc9909a93d2c0248ef490da737dabda9e41eb3d9a379ddb004cfe66c60f3072df", "0xd8ca500dee0f1f7334075ebef1e979652b70355c56e09b74d50c87e31e675ddb",
"0xa063b1a2583a43114cd150b3c2320fe0bccf5f1b0f75c92c9d7e55433a291517", "0x0c9a9c89e79e068154f6c2b9b827cd4f3972e035542ebb68d68b9120e757626c",
"0x0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d", "0x0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d",
"0x887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968", "0x887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968",
"0xffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83", "0xffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83",
...@@ -128,50 +128,50 @@ ...@@ -128,50 +128,50 @@
}, },
{ {
"name": "PartialTree", "name": "PartialTree",
"rootHash": "0xb003f2e3ac0841e22e4dc58f001f9ba731081dcfdc823c295429264e55ebfd95", "rootHash": "0x9c089c06e4f93c68d74fdfef9255cb75f78b053dabb43749d20e21aa8330092c",
"leafCount": 65535, "leafCount": 65535,
"index": 65533, "index": 65533,
"proofs": [ "proofs": [
"0xa7ead3155af3540785a09632e1a9a0e905700dddc29ca3531643209d11abde34", "0xfffc000000000000000000000000000000000000000000000000000000000000",
"0x2510bc5d56f49d7f5cdce4e37424936b31f7a01ba27c0201b40bd00d7241f525", "0xf52ca96368ae7189a9a33f0efefd1b0a2a2c208c8dca11a2b1066fe99a6582c5",
"0x69251e33d3beeac7d24417e095adf8994eca90f7b220477b7dbdf7833ed5c646", "0x6a9b869f709b2d34940a0bbe9eea3d502f1e918a4490eb890f1727d6843c055d",
"0x37e281b275aa30e45a87ad2cfb8fbd6402fca47633dd698c519595e1360714dd", "0x02f7a2dbcc9b3d6780f7f72aafd200af423ba438d45c535d2d4e333e43ce98fc",
"0x5fdae72b17eea7ab12066760cfe8dff858665ece3b5ec7ea30fb88737bc63e00", "0x84952e81b8cba49f78e4ee1ef684936b09c1b851ecbe03382afecc04fb98b305",
"0x6657aa64e042b55b6915c5ac65c9f07e29e1e67466d159ab8432f15e7088ded6", "0x2f9e97e47493214948c70a6b818145a7e9cd84f7ceab384b179559730d7efbac",
"0xa689859b6b6f0b586d267b5228b3d07c169889b219a49231386c4ed6c934df6e", "0x3414ae9dd358c60fae6b4010fc90af715bcc5d0fdd55cefd5370277de456c4b8",
"0xb9d17d1a81bcc1e9434e517008e3f68e2e19ab73b464ca13885c9e3b1072fd0c", "0x04c3b7e470a22c856003970d95b7015f284a0a09c8bc18e1da02078ded445d58",
"0xaf79e21764536f60b54298ba40da1d16fe432510c40d54e8d6d12f4c5491418d", "0x417e698fd035c879670c381d7bb0815ce67fb854625e502984ae8e2436ede0a9",
"0x0071a9f78633e4bf4f008134694b97783ffdf7651bf09096bce74b1cc77c9254", "0x042abe5eb9668a197d5389e4b225c474a7646950279cbd6d326db073ea120266",
"0x7d0475c42ed689be225ec7de3d6f620f5afa50d17223d3cf3b5faebe6b8eab63", "0x34f6ea610e918f37226300a42b22f702f3dd7bd7ae17e9dcb6e7374906b83aef",
"0x7efcb6ac59e3ebd6cb62985827c634e88a9cf118a906d2d25f0facf44f8ce48d", "0x1c050824157972417b2931f6018ed24e3fe7fedf7c5a502eb26710501d5379d2",
"0x0c2264f5c766dafd9ed23277449b2affe176e7ffeef29dad949932654df90f17", "0x529067b7c2a065d285b931d19fd85ad35eb0abf89c1ed40ca836ace2c7ddad9e",
"0x0622a9974a31b7774c1b89e494663f008a82d525dd00ac6fbaf322ae9845261a", "0xfd4d4328beb216713b978c561d4acde2ffe400c60d4b6abe21940c0cff2bf0bc",
"0x882284d7f31dec4cadb4b46d2209ef7806e440d541f1d6efd2e1b53a32ee9e65", "0x9b4a92fefca8b04570c15e329cbc6c953dbe30e06607d985882f35fb8cfd986a",
"0xfbcf92d99fd2e103e15b1647b177895b0529dd715e551a80c90744818458a8e3" "0x6ec52bd9024705f2c1bd913c43550f5c2b3fbba19dee077b4da6aa6cd90d1c3f"
] ]
}, },
{ {
"name": "FullTree", "name": "FullTree",
"rootHash": "0xb003f2e3ac0841e22e4dc58f001f9ba731081dcfdc823c295429264e55ebfd95", "rootHash": "0x9c089c06e4f93c68d74fdfef9255cb75f78b053dabb43749d20e21aa8330092c",
"leafCount": 65535, "leafCount": 65535,
"index": 65534, "index": 65534,
"proofs": [ "proofs": [
"0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000",
"0x5d5992fd072e73c425c84efbd29e9e4a87756a67d972f096661c967583809c8f", "0x65cf5d60111a84456933bd43218230c6235995be88b274e196e8ffcb88927db6",
"0x69251e33d3beeac7d24417e095adf8994eca90f7b220477b7dbdf7833ed5c646", "0x6a9b869f709b2d34940a0bbe9eea3d502f1e918a4490eb890f1727d6843c055d",
"0x37e281b275aa30e45a87ad2cfb8fbd6402fca47633dd698c519595e1360714dd", "0x02f7a2dbcc9b3d6780f7f72aafd200af423ba438d45c535d2d4e333e43ce98fc",
"0x5fdae72b17eea7ab12066760cfe8dff858665ece3b5ec7ea30fb88737bc63e00", "0x84952e81b8cba49f78e4ee1ef684936b09c1b851ecbe03382afecc04fb98b305",
"0x6657aa64e042b55b6915c5ac65c9f07e29e1e67466d159ab8432f15e7088ded6", "0x2f9e97e47493214948c70a6b818145a7e9cd84f7ceab384b179559730d7efbac",
"0xa689859b6b6f0b586d267b5228b3d07c169889b219a49231386c4ed6c934df6e", "0x3414ae9dd358c60fae6b4010fc90af715bcc5d0fdd55cefd5370277de456c4b8",
"0xb9d17d1a81bcc1e9434e517008e3f68e2e19ab73b464ca13885c9e3b1072fd0c", "0x04c3b7e470a22c856003970d95b7015f284a0a09c8bc18e1da02078ded445d58",
"0xaf79e21764536f60b54298ba40da1d16fe432510c40d54e8d6d12f4c5491418d", "0x417e698fd035c879670c381d7bb0815ce67fb854625e502984ae8e2436ede0a9",
"0x0071a9f78633e4bf4f008134694b97783ffdf7651bf09096bce74b1cc77c9254", "0x042abe5eb9668a197d5389e4b225c474a7646950279cbd6d326db073ea120266",
"0x7d0475c42ed689be225ec7de3d6f620f5afa50d17223d3cf3b5faebe6b8eab63", "0x34f6ea610e918f37226300a42b22f702f3dd7bd7ae17e9dcb6e7374906b83aef",
"0x7efcb6ac59e3ebd6cb62985827c634e88a9cf118a906d2d25f0facf44f8ce48d", "0x1c050824157972417b2931f6018ed24e3fe7fedf7c5a502eb26710501d5379d2",
"0x0c2264f5c766dafd9ed23277449b2affe176e7ffeef29dad949932654df90f17", "0x529067b7c2a065d285b931d19fd85ad35eb0abf89c1ed40ca836ace2c7ddad9e",
"0x0622a9974a31b7774c1b89e494663f008a82d525dd00ac6fbaf322ae9845261a", "0xfd4d4328beb216713b978c561d4acde2ffe400c60d4b6abe21940c0cff2bf0bc",
"0x882284d7f31dec4cadb4b46d2209ef7806e440d541f1d6efd2e1b53a32ee9e65", "0x9b4a92fefca8b04570c15e329cbc6c953dbe30e06607d985882f35fb8cfd986a",
"0xfbcf92d99fd2e103e15b1647b177895b0529dd715e551a80c90744818458a8e3" "0x6ec52bd9024705f2c1bd913c43550f5c2b3fbba19dee077b4da6aa6cd90d1c3f"
] ]
} }
] ]
...@@ -3,7 +3,6 @@ package merkle ...@@ -3,7 +3,6 @@ package merkle
import ( import (
"errors" "errors"
"github.com/ethereum-optimism/optimism/op-challenger/game/keccak/types"
"github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/crypto"
) )
...@@ -76,7 +75,7 @@ func (m *BinaryMerkleTree) walkDownToLeafCount(subtreeLeafCount uint64) *merkleN ...@@ -76,7 +75,7 @@ func (m *BinaryMerkleTree) walkDownToLeafCount(subtreeLeafCount uint64) *merkleN
maxSubtreeLeafCount := uint64(MaxLeafCount) + 1 maxSubtreeLeafCount := uint64(MaxLeafCount) + 1
levelNode := m.Root levelNode := m.Root
for height := 0; height < BinaryMerkleTreeDepth; height++ { for height := 0; height < BinaryMerkleTreeDepth; height++ {
if subtreeLeafCount*2 <= uint64(maxSubtreeLeafCount) { if subtreeLeafCount*2 <= maxSubtreeLeafCount {
if levelNode.Left == nil { if levelNode.Left == nil {
levelNode.Left = &merkleNode{ levelNode.Left = &merkleNode{
Label: zeroHashes[height], Label: zeroHashes[height],
...@@ -100,12 +99,7 @@ func (m *BinaryMerkleTree) walkDownToLeafCount(subtreeLeafCount uint64) *merkleN ...@@ -100,12 +99,7 @@ func (m *BinaryMerkleTree) walkDownToLeafCount(subtreeLeafCount uint64) *merkleN
} }
// AddLeaf adds a leaf to the binary merkle tree. // AddLeaf adds a leaf to the binary merkle tree.
func (m *BinaryMerkleTree) AddLeaf(leaf types.Leaf) { func (m *BinaryMerkleTree) AddLeaf(hash common.Hash) {
m.AddRawLeaf(leaf.Hash())
}
// AddRawLeaf adds a raw 32 byte leaf to the binary merkle tree.
func (m *BinaryMerkleTree) AddRawLeaf(hash common.Hash) {
// Walk down to the new max leaf node. // Walk down to the new max leaf node.
m.LeafCount += 1 m.LeafCount += 1
levelNode := m.walkDownToLeafCount(m.LeafCount) levelNode := m.walkDownToLeafCount(m.LeafCount)
......
package merkle package merkle
import ( import (
"bytes"
_ "embed" _ "embed"
"encoding/json" "encoding/json"
"fmt" "fmt"
"math/big"
"testing" "testing"
"github.com/ethereum-optimism/optimism/op-challenger/game/keccak/types"
"github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
) )
...@@ -34,14 +31,8 @@ func TestBinaryMerkleTree_AddLeaf(t *testing.T) { ...@@ -34,14 +31,8 @@ func TestBinaryMerkleTree_AddLeaf(t *testing.T) {
tree := NewBinaryMerkleTree() tree := NewBinaryMerkleTree()
expectedLeafHash := zeroHashes[BinaryMerkleTreeDepth-1] expectedLeafHash := zeroHashes[BinaryMerkleTreeDepth-1]
for i := 0; i < int(test.LeafCount); i++ { for i := 0; i < int(test.LeafCount); i++ {
input := ([types.BlockSize]byte)(bytes.Repeat([]byte{byte(i)}, types.BlockSize)) expectedLeafHash = leafHash(i)
lastLeaf := types.Leaf{ tree.AddLeaf(expectedLeafHash)
Input: input,
Index: big.NewInt(int64(i)),
StateCommitment: common.Hash{},
}
tree.AddLeaf(lastLeaf)
expectedLeafHash = lastLeaf.Hash()
} }
leaf := tree.walkDownToLeafCount(tree.LeafCount) leaf := tree.walkDownToLeafCount(tree.LeafCount)
require.Equal(t, expectedLeafHash, leaf.Label) require.Equal(t, expectedLeafHash, leaf.Label)
...@@ -58,12 +49,7 @@ func TestBinaryMerkleTree_RootHash(t *testing.T) { ...@@ -58,12 +49,7 @@ func TestBinaryMerkleTree_RootHash(t *testing.T) {
t.Run(fmt.Sprintf("%s-LeafCount-%v-Ref-%v", test.Name, test.LeafCount, i), func(t *testing.T) { t.Run(fmt.Sprintf("%s-LeafCount-%v-Ref-%v", test.Name, test.LeafCount, i), func(t *testing.T) {
tree := NewBinaryMerkleTree() tree := NewBinaryMerkleTree()
for i := 0; i < int(test.LeafCount); i++ { for i := 0; i < int(test.LeafCount); i++ {
input := ([types.BlockSize]byte)(bytes.Repeat([]byte{byte(i)}, types.BlockSize)) tree.AddLeaf(leafHash(i))
tree.AddLeaf(types.Leaf{
Input: input,
Index: big.NewInt(int64(i)),
StateCommitment: common.Hash{},
})
} }
require.Equal(t, test.RootHash, tree.RootHash()) require.Equal(t, test.RootHash, tree.RootHash())
}) })
...@@ -79,12 +65,7 @@ func TestBinaryMerkleTree_ProofAtIndex(t *testing.T) { ...@@ -79,12 +65,7 @@ func TestBinaryMerkleTree_ProofAtIndex(t *testing.T) {
t.Run(fmt.Sprintf("%s-Index-%v-Ref-%v", test.Name, test.LeafCount, i), func(t *testing.T) { t.Run(fmt.Sprintf("%s-Index-%v-Ref-%v", test.Name, test.LeafCount, i), func(t *testing.T) {
tree := NewBinaryMerkleTree() tree := NewBinaryMerkleTree()
for i := 0; i < int(test.LeafCount); i++ { for i := 0; i < int(test.LeafCount); i++ {
input := ([types.BlockSize]byte)(bytes.Repeat([]byte{byte(i)}, types.BlockSize)) tree.AddLeaf(leafHash(i))
tree.AddLeaf(types.Leaf{
Input: input,
Index: big.NewInt(int64(i)),
StateCommitment: common.Hash{},
})
} }
proof, err := tree.ProofAtIndex(test.Index) proof, err := tree.ProofAtIndex(test.Index)
require.NoError(t, err) require.NoError(t, err)
...@@ -92,3 +73,7 @@ func TestBinaryMerkleTree_ProofAtIndex(t *testing.T) { ...@@ -92,3 +73,7 @@ func TestBinaryMerkleTree_ProofAtIndex(t *testing.T) {
}) })
} }
} }
func leafHash(idx int) common.Hash {
return common.Hash{0xff, byte(idx)}
}
...@@ -4,6 +4,7 @@ import ( ...@@ -4,6 +4,7 @@ import (
"context" "context"
"math/big" "math/big"
"github.com/ethereum-optimism/optimism/op-challenger/game/keccak/merkle"
"github.com/ethereum-optimism/optimism/op-service/sources/batching" "github.com/ethereum-optimism/optimism/op-service/sources/batching"
"github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/crypto"
...@@ -24,7 +25,7 @@ type Leaf struct { ...@@ -24,7 +25,7 @@ type Leaf struct {
// Hash returns the hash of the leaf data. That is the // Hash returns the hash of the leaf data. That is the
// bytewise concatenation of the input, index, and state commitment. // bytewise concatenation of the input, index, and state commitment.
func (l *Leaf) Hash() common.Hash { func (l Leaf) Hash() common.Hash {
concatted := make([]byte, 0, 136+32+32) concatted := make([]byte, 0, 136+32+32)
concatted = append(concatted, l.Input[:]...) concatted = append(concatted, l.Input[:]...)
concatted = append(concatted, l.Index.Bytes()...) concatted = append(concatted, l.Index.Bytes()...)
...@@ -73,10 +74,12 @@ type Challenge struct { ...@@ -73,10 +74,12 @@ type Challenge struct {
StateMatrix []byte // TODO(client-pod#480): Need a better representation of this StateMatrix []byte // TODO(client-pod#480): Need a better representation of this
// Prestate is the valid leaf immediately prior to the first invalid leaf // Prestate is the valid leaf immediately prior to the first invalid leaf
Prestate Leaf Prestate Leaf
PrestateProof merkle.Proof
// Poststate is the first invalid leaf in the preimage. The challenge claims that this leaf is invalid. // Poststate is the first invalid leaf in the preimage. The challenge claims that this leaf is invalid.
Poststate Leaf Poststate Leaf
PoststateProof merkle.Proof
} }
type LargePreimageOracle interface { type LargePreimageOracle interface {
......
...@@ -71,7 +71,7 @@ func DiffMerkle() { ...@@ -71,7 +71,7 @@ func DiffMerkle() {
// Append all leaves to the merkle tree. // Append all leaves to the merkle tree.
for i := 0; i < len(rawLeaves)/32; i++ { for i := 0; i < len(rawLeaves)/32; i++ {
leaf := common.BytesToHash(rawLeaves[i<<5 : (i+1)<<5]) leaf := common.BytesToHash(rawLeaves[i<<5 : (i+1)<<5])
merkleTree.AddRawLeaf(leaf) merkleTree.AddLeaf(leaf)
} }
// Generate the proof for the given index. // Generate the proof for the given index.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment