Commit 4cd3ca84 authored by david-roth-cb's avatar david-roth-cb Committed by GitHub

Create function to return l1 + l2 missing hashes (#9048)

parent 50a6a55c
...@@ -28,6 +28,16 @@ func AttributesMatchBlock(rollupCfg *rollup.Config, attrs *eth.PayloadAttributes ...@@ -28,6 +28,16 @@ func AttributesMatchBlock(rollupCfg *rollup.Config, attrs *eth.PayloadAttributes
return fmt.Errorf("random field does not match. expected: %v. got: %v", attrs.PrevRandao, block.PrevRandao) return fmt.Errorf("random field does not match. expected: %v. got: %v", attrs.PrevRandao, block.PrevRandao)
} }
if len(attrs.Transactions) != len(block.Transactions) { if len(attrs.Transactions) != len(block.Transactions) {
missingSafeHashes, missingUnsafeHashes, err := getMissingTxnHashes(l, attrs.Transactions, block.Transactions)
if err != nil {
l.Error("failed to get missing txn hashes", "err", err)
} else {
l.Error("mismatched hashes",
"missingSafeHashes", missingSafeHashes,
"missingUnsafeHashes", missingUnsafeHashes,
)
}
return fmt.Errorf("transaction count does not match. expected: %d. got: %d", len(attrs.Transactions), len(block.Transactions)) return fmt.Errorf("transaction count does not match. expected: %d. got: %d", len(attrs.Transactions), len(block.Transactions))
} }
for i, otx := range attrs.Transactions { for i, otx := range attrs.Transactions {
...@@ -138,3 +148,50 @@ func logL1InfoTxns(rollupCfg *rollup.Config, l log.Logger, l2Number, l2Timestamp ...@@ -138,3 +148,50 @@ func logL1InfoTxns(rollupCfg *rollup.Config, l log.Logger, l2Number, l2Timestamp
"unsafe_gpo_scalar", unsafeInfo.L1FeeScalar, "unsafe_gpo_overhead", unsafeInfo.L1FeeOverhead) "unsafe_gpo_scalar", unsafeInfo.L1FeeScalar, "unsafe_gpo_overhead", unsafeInfo.L1FeeOverhead)
} }
} }
func getMissingTxnHashes(l log.Logger, safeTxns, unsafeTxns []hexutil.Bytes) ([]common.Hash, []common.Hash, error) {
safeTxnHashes := make(map[common.Hash]struct{}, len(safeTxns))
unsafeTxnHashes := make(map[common.Hash]struct{}, len(unsafeTxns))
for _, tx := range safeTxns {
safeTxValue := &types.Transaction{}
errSafe := safeTxValue.UnmarshalBinary(tx)
if errSafe != nil {
return nil, nil, fmt.Errorf("failed to unmarshal safe tx: %w", errSafe)
}
if _, ok := safeTxnHashes[safeTxValue.Hash()]; ok {
l.Warn("duplicate safe tx value hash detected", "safeTxValueHash", safeTxValue.Hash())
}
safeTxnHashes[safeTxValue.Hash()] = struct{}{}
}
for _, tx := range unsafeTxns {
unsafeTxValue := &types.Transaction{}
errUnsafe := unsafeTxValue.UnmarshalBinary(tx)
if errUnsafe != nil {
return nil, nil, fmt.Errorf("failed to unmarshal unsafe tx: %w", errUnsafe)
}
if _, ok := unsafeTxnHashes[unsafeTxValue.Hash()]; ok {
l.Warn("duplicate unsafe tx value hash detected", "unsafeTxValueHash", unsafeTxValue.Hash())
}
unsafeTxnHashes[unsafeTxValue.Hash()] = struct{}{}
}
missingUnsafeHashes := []common.Hash{}
for hash := range safeTxnHashes {
if _, ok := unsafeTxnHashes[hash]; !ok {
missingUnsafeHashes = append(missingUnsafeHashes, hash)
}
}
missingSafeHashes := []common.Hash{}
for hash := range unsafeTxnHashes {
if _, ok := safeTxnHashes[hash]; !ok {
missingSafeHashes = append(missingSafeHashes, hash)
}
}
return missingSafeHashes, missingUnsafeHashes, nil
}
package derive package derive
import ( import (
"math/rand"
"testing" "testing"
"github.com/ethereum-optimism/optimism/op-node/rollup" "github.com/ethereum-optimism/optimism/op-node/rollup"
"github.com/ethereum-optimism/optimism/op-service/eth" "github.com/ethereum-optimism/optimism/op-service/eth"
"github.com/ethereum-optimism/optimism/op-service/testlog"
"github.com/ethereum-optimism/optimism/op-service/testlog"
"github.com/ethereum-optimism/optimism/op-service/testutils"
"github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/log"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
...@@ -261,3 +264,126 @@ func TestWithdrawalsMatch(t *testing.T) { ...@@ -261,3 +264,126 @@ func TestWithdrawalsMatch(t *testing.T) {
} }
} }
} }
func TestGetMissingTxnHashes(t *testing.T) {
depositTxs := make([]*types.Transaction, 5)
for i := 0; i < len(depositTxs); i++ {
rng := rand.New(rand.NewSource(1234 + int64(i)))
safeDeposit := testutils.GenerateDeposit(testutils.RandomHash(rng), rng)
depositTxs[i] = types.NewTx(safeDeposit)
}
tests := []struct {
safeTransactions []hexutil.Bytes
unsafeTransactions []hexutil.Bytes
expectedSafeMissingHashes []common.Hash
expectedUnsafeMissingHashes []common.Hash
expectErr bool
}{
{
safeTransactions: []hexutil.Bytes{},
unsafeTransactions: []hexutil.Bytes{depositTxToBytes(t, depositTxs[0])},
expectedSafeMissingHashes: []common.Hash{depositTxs[0].Hash()},
expectedUnsafeMissingHashes: []common.Hash{},
expectErr: false,
},
{
safeTransactions: []hexutil.Bytes{depositTxToBytes(t, depositTxs[0])},
unsafeTransactions: []hexutil.Bytes{},
expectedSafeMissingHashes: []common.Hash{},
expectedUnsafeMissingHashes: []common.Hash{depositTxs[0].Hash()},
expectErr: false,
},
{
safeTransactions: []hexutil.Bytes{
depositTxToBytes(t, depositTxs[0]),
},
unsafeTransactions: []hexutil.Bytes{
depositTxToBytes(t, depositTxs[0]),
depositTxToBytes(t, depositTxs[1]),
depositTxToBytes(t, depositTxs[2]),
},
expectedSafeMissingHashes: []common.Hash{
depositTxs[1].Hash(),
depositTxs[2].Hash(),
},
expectedUnsafeMissingHashes: []common.Hash{},
expectErr: false,
},
{
safeTransactions: []hexutil.Bytes{
depositTxToBytes(t, depositTxs[0]),
depositTxToBytes(t, depositTxs[1]),
depositTxToBytes(t, depositTxs[2]),
},
unsafeTransactions: []hexutil.Bytes{
depositTxToBytes(t, depositTxs[0]),
},
expectedSafeMissingHashes: []common.Hash{},
expectedUnsafeMissingHashes: []common.Hash{
depositTxs[1].Hash(),
depositTxs[2].Hash(),
},
expectErr: false,
},
{
safeTransactions: []hexutil.Bytes{
depositTxToBytes(t, depositTxs[0]),
depositTxToBytes(t, depositTxs[1]),
depositTxToBytes(t, depositTxs[2]),
},
unsafeTransactions: []hexutil.Bytes{
depositTxToBytes(t, depositTxs[2]),
depositTxToBytes(t, depositTxs[3]),
depositTxToBytes(t, depositTxs[4]),
},
expectedSafeMissingHashes: []common.Hash{
depositTxs[3].Hash(),
depositTxs[4].Hash(),
},
expectedUnsafeMissingHashes: []common.Hash{
depositTxs[0].Hash(),
depositTxs[1].Hash(),
},
expectErr: false,
},
{
safeTransactions: []hexutil.Bytes{{1, 2, 3}},
unsafeTransactions: []hexutil.Bytes{},
expectedSafeMissingHashes: []common.Hash{},
expectedUnsafeMissingHashes: []common.Hash{},
expectErr: true,
},
{
safeTransactions: []hexutil.Bytes{},
unsafeTransactions: []hexutil.Bytes{{1, 2, 3}},
expectedSafeMissingHashes: []common.Hash{},
expectedUnsafeMissingHashes: []common.Hash{},
expectErr: true,
},
}
for _, test := range tests {
missingSafeHashes, missingUnsafeHashes, err := getMissingTxnHashes(
testlog.Logger(t, log.LvlError),
test.safeTransactions,
test.unsafeTransactions,
)
if test.expectErr {
require.Error(t, err)
} else {
require.NoError(t, err)
require.ElementsMatch(t, test.expectedSafeMissingHashes, missingSafeHashes)
require.ElementsMatch(t, test.expectedUnsafeMissingHashes, missingUnsafeHashes)
}
}
}
func depositTxToBytes(t *testing.T, tx *types.Transaction) hexutil.Bytes {
txBytes, err := tx.MarshalBinary()
require.NoError(t, err)
return txBytes
}
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