From 0587cf3e862d405c0a762b7da6ca7782e97d26c5 Mon Sep 17 00:00:00 2001 From: nicolas <48695862+merklefruit@users.noreply.github.com> Date: Thu, 18 Jul 2024 12:29:57 +0200 Subject: [PATCH] fix: calculate leaves for blob txs --- builder/builder/utils_test.go | 16 +++++++++++----- mev-boost-relay/services/api/proofs.go | 19 ++++++++++++++++++- mev-boost/server/service.go | 19 ++++++++++++++++++- 3 files changed, 47 insertions(+), 7 deletions(-) diff --git a/builder/builder/utils_test.go b/builder/builder/utils_test.go index 768bb4315..d4758003f 100644 --- a/builder/builder/utils_test.go +++ b/builder/builder/utils_test.go @@ -24,9 +24,10 @@ func TestGenerateMerkleMultiProofs(t *testing.T) { raw := `["0x03f9029c01830299f184b2d05e008507aef40a00832dc6c09468d30f47f19c07bccef4ac7fae2dc12fca3e0dc980b90204ef16e845000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000001e0000000000000000000000000000000000000000000000000000000000000018000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000633b68f5d8d3a86593ebb815b4663bcbe0302e31382e302d64657600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004109de8da2a97e37f2e6dc9f7d50a408f9344d7aa1a925ae53daf7fbef43491a571960d76c0cb926190a9da10df7209fb1ba93cd98b1565a3a2368749d505f90c81c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c0843b9aca00e1a00141e3a338e30c49ed0501e315bcc45e4edefebed43ab1368a1505461d9cf64901a01e8511e06b17683d89eb57b9869b96b8b611f969f7f56cbc0adc2df7c88a2a07a00910deacf91bba0d74e368d285d311dc5884e7cfe219d85aea5741b2b6e3a2fe", "0x02f873011a8405f5e10085037fcc60e182520894f7eaaf75cb6ec4d0e2b53964ce6733f54f7d3ffc880b6139a7cbd2000080c080a095a7a3cbb7383fc3e7d217054f861b890a935adc1adf4f05e3a2f23688cf2416a00875cdc45f4395257e44d709d04990349b105c22c11034a60d7af749ffea2765","0xf8708305dc6885029332e35883019a2894500b0107e172e420561565c8177c28ac0f62017f8810ffb80e6cc327008025a0e9c0b380c68f040ae7affefd11979f5ed18ae82c00e46aa3238857c372a358eca06b26e179dd2f7a7f1601755249f4cff56690c4033553658f0d73e26c36fe7815", "0xf86c0785028fa6ae0082520894098d880c4753d0332ca737aa592332ed2522cd22880d2f09f6558750008026a0963e58027576b3a8930d7d9b4a49253b6e1a2060e259b2102e34a451d375ce87a063f802538d3efed17962c96fcea431388483bbe3860ea9bb3ef01d4781450fbf", "0x02f87601836384348477359400850517683ba883019a28943678fce4028b6745eb04fa010d9c8e4b36d6288c872b0f1366ad800080c080a0b6b7aba1954160d081b2c8612e039518b9c46cd7df838b405a03f927ad196158a071d2fb6813e5b5184def6bd90fb5f29e0c52671dea433a7decb289560a58416e"]` - byteTxs := make([]*common.HexBytes, 0, 3) + byteTxs := make([]*common.HexBytes, 0, 5) err := json.Unmarshal([]byte(raw), &byteTxs) require.NoError(t, err) + require.Equal(t, len(byteTxs), 5) payloadTransactions := common.Map(byteTxs, func(rawTx *common.HexBytes) *types.Transaction { transaction := new(types.Transaction) @@ -38,10 +39,13 @@ func TestGenerateMerkleMultiProofs(t *testing.T) { err = json.Unmarshal([]byte(raw), transactionsRaw) require.NoError(t, err) - constraints := make(types.HashToConstraintDecoded, 3) - constraints[payloadTransactions[0].Hash()] = &types.ConstraintDecoded{Tx: payloadTransactions[0]} + require.Equal(t, payloadTransactions[0].Type(), uint8(3)) + require.Equal(t, payloadTransactions[1].Type(), uint8(2)) + + constraints := make(types.HashToConstraintDecoded, 1) + // constraints[payloadTransactions[0].Hash()] = &types.ConstraintDecoded{Tx: payloadTransactions[0]} constraints[payloadTransactions[1].Hash()] = &types.ConstraintDecoded{Tx: payloadTransactions[1]} - constraints[payloadTransactions[2].Hash()] = &types.ConstraintDecoded{Tx: payloadTransactions[2]} + // constraints[payloadTransactions[2].Hash()] = &types.ConstraintDecoded{Tx: payloadTransactions[2]} inclusionProof, root, err := CalculateMerkleMultiProofs(payloadTransactions, constraints) require.NoError(t, err) @@ -63,5 +67,7 @@ func TestGenerateMerkleMultiProofs(t *testing.T) { indicesInt[i] = int(index) } - fastSsz.VerifyMultiproof(rootHash, hashesBytes, leavesBytes, indicesInt) + ok, err := fastSsz.VerifyMultiproof(rootHash, hashesBytes, leavesBytes, indicesInt) + require.NoError(t, err) + require.True(t, ok) } diff --git a/mev-boost-relay/services/api/proofs.go b/mev-boost-relay/services/api/proofs.go index 33b387fd4..b96386162 100644 --- a/mev-boost-relay/services/api/proofs.go +++ b/mev-boost-relay/services/api/proofs.go @@ -6,6 +6,7 @@ import ( "time" "github.com/attestantio/go-eth2-client/spec/phase0" + "github.com/ethereum/go-ethereum/core/types" fastSsz "github.com/ferranbt/fastssz" "github.com/flashbots/mev-boost-relay/common" "github.com/sirupsen/logrus" @@ -39,7 +40,23 @@ func verifyInclusionProof(log *logrus.Entry, transactionsRoot phase0.Root, proof // Compute the hash tree root for the raw preconfirmed transaction // and use it as "Leaf" in the proof to be verified against - tx := Transaction(constraint.Tx) + + // TODO: this is pretty inefficient, we should work with the transaction already + // parsed without the blob here to avoid unmarshalling and marshalling again + transaction := new(types.Transaction) + err := transaction.UnmarshalBinary(constraint.Tx) + if err != nil { + log.WithError(err).Error("error unmarshalling transaction while verifying proofs") + return err + } + + withoutBlob, err := transaction.WithoutBlobTxSidecar().MarshalBinary() + if err != nil { + log.WithError(err).Error("error marshalling transaction without blob tx sidecar") + return err + } + + tx := Transaction(withoutBlob) txHashTreeRoot, err := tx.HashTreeRoot() if err != nil { return ErrInvalidRoot diff --git a/mev-boost/server/service.go b/mev-boost/server/service.go index d7cde2164..748aa97be 100644 --- a/mev-boost/server/service.go +++ b/mev-boost/server/service.go @@ -22,6 +22,7 @@ import ( eth2ApiV1Capella "github.com/attestantio/go-eth2-client/api/v1/capella" eth2ApiV1Deneb "github.com/attestantio/go-eth2-client/api/v1/deneb" "github.com/attestantio/go-eth2-client/spec/phase0" + gethTypes "github.com/ethereum/go-ethereum/core/types" fastSsz "github.com/ferranbt/fastssz" "github.com/flashbots/go-boost-utils/ssz" "github.com/flashbots/go-boost-utils/types" @@ -373,7 +374,23 @@ func (m *BoostService) verifyInclusionProof(responsePayload *BidWithInclusionPro // Compute the hash tree root for the raw preconfirmed transaction // and use it as "Leaf" in the proof to be verified against - tx := Transaction(constraint.Tx) + + // TODO: this is pretty inefficient, we should work with the transaction already + // parsed without the blob here to avoid unmarshalling and marshalling again + transaction := new(gethTypes.Transaction) + err := transaction.UnmarshalBinary(constraint.Tx) + if err != nil { + log.WithError(err).Error("error unmarshalling transaction while verifying proofs") + return err + } + + withoutBlob, err := transaction.WithoutBlobTxSidecar().MarshalBinary() + if err != nil { + log.WithError(err).Error("error marshalling transaction without blob tx sidecar") + return err + } + + tx := Transaction(withoutBlob) txHashTreeRoot, err := tx.HashTreeRoot() if err != nil { return errInvalidRoot