Commit 51a287b3 authored by Hamdi Allam's avatar Hamdi Allam

comments. compute withdrawal hash from the message passer contract for legacy

parent 40a0a24e
...@@ -9,6 +9,7 @@ import ( ...@@ -9,6 +9,7 @@ import (
"github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/crypto"
) )
type CrossDomainMessengerSentMessage struct { type CrossDomainMessengerSentMessage struct {
...@@ -57,5 +58,10 @@ func CrossDomainMessengerSentMessageHash(sentMessage *bindings.CrossDomainMessen ...@@ -57,5 +58,10 @@ func CrossDomainMessengerSentMessageHash(sentMessage *bindings.CrossDomainMessen
return common.Hash{}, err return common.Hash{}, err
} }
return contracts.CrossDomainMessageHash(abi, sentMessage, value) calldata, err := contracts.CrossDomainMessageCalldata(abi, sentMessage, value)
if err != nil {
return common.Hash{}, err
}
return crypto.Keccak256Hash(calldata), nil
} }
...@@ -31,6 +31,11 @@ func (m *MockEthClient) BlockHeadersByRange(from, to *big.Int) ([]types.Header, ...@@ -31,6 +31,11 @@ func (m *MockEthClient) BlockHeadersByRange(from, to *big.Int) ([]types.Header,
return args.Get(0).([]types.Header), args.Error(1) return args.Get(0).([]types.Header), args.Error(1)
} }
func (m *MockEthClient) TxByHash(hash common.Hash) (*types.Transaction, error) {
args := m.Called(hash)
return args.Get(0).(*types.Transaction), args.Error(1)
}
func (m *MockEthClient) StorageHash(address common.Address, blockNumber *big.Int) (common.Hash, error) { func (m *MockEthClient) StorageHash(address common.Address, blockNumber *big.Int) (common.Hash, error) {
args := m.Called(address, blockNumber) args := m.Called(address, blockNumber)
return args.Get(0).(common.Hash), args.Error(1) return args.Get(0).(common.Hash), args.Error(1)
......
...@@ -4,6 +4,7 @@ import ( ...@@ -4,6 +4,7 @@ import (
"fmt" "fmt"
"math/big" "math/big"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/log"
"github.com/ethereum-optimism/optimism/indexer/config" "github.com/ethereum-optimism/optimism/indexer/config"
...@@ -127,8 +128,7 @@ func LegacyL1ProcessInitiatedBridgeEvents(log log.Logger, db *database.DB, chain ...@@ -127,8 +128,7 @@ func LegacyL1ProcessInitiatedBridgeEvents(log log.Logger, db *database.DB, chain
// LegacyL2ProcessInitiatedEvents will query the data for bridge events within the specified block range // LegacyL2ProcessInitiatedEvents will query the data for bridge events within the specified block range
// according the pre-bedrock protocol. This follows: // according the pre-bedrock protocol. This follows:
// 1. L2CrossDomainMessenger // 1. L2CrossDomainMessenger - The LegacyMessagePasser contract cannot be used as entrypoint to bridge transactions from L2. The protocol
// - The LegacyMessagePasser contract cannot be used as entrypoint to bridge transactions from L2. The protocol
// only allows the L2CrossDomainMessenger as the sole sender when relaying a bridged message. // only allows the L2CrossDomainMessenger as the sole sender when relaying a bridged message.
// 2. L2StandardBridge // 2. L2StandardBridge
func LegacyL2ProcessInitiatedBridgeEvents(log log.Logger, db *database.DB, fromHeight *big.Int, toHeight *big.Int) error { func LegacyL2ProcessInitiatedBridgeEvents(log log.Logger, db *database.DB, fromHeight *big.Int, toHeight *big.Int) error {
...@@ -149,10 +149,11 @@ func LegacyL2ProcessInitiatedBridgeEvents(log log.Logger, db *database.DB, fromH ...@@ -149,10 +149,11 @@ func LegacyL2ProcessInitiatedBridgeEvents(log log.Logger, db *database.DB, fromH
sentMessage := crossDomainSentMessages[i] sentMessage := crossDomainSentMessages[i]
sentMessages[logKey{sentMessage.Event.BlockHash, sentMessage.Event.LogIndex}] = &sentMessage sentMessages[logKey{sentMessage.Event.BlockHash, sentMessage.Event.LogIndex}] = &sentMessage
// To ensure consistency in the schema, we duplicate this as the "root" transaction withdrawal. We re-use the same withdrawal hash as the storage // To ensure consistency in the schema, we duplicate this as the "root" transaction withdrawal. The storage key in the message
// key for the proof sha3(calldata + sender) can be derived from the fields. (NOTE: should we just use the storage key here?) // passer contract is sha3(calldata + sender). The sender always being the L2CrossDomainMessenger pre-bedrock.
withdrawalHash := crypto.Keccak256Hash(append(sentMessage.MessageCalldata, predeploys.L2CrossDomainMessengerAddr[:]...))
l2TransactionWithdrawals[i] = database.L2TransactionWithdrawal{ l2TransactionWithdrawals[i] = database.L2TransactionWithdrawal{
WithdrawalHash: sentMessage.BridgeMessage.MessageHash, WithdrawalHash: withdrawalHash,
InitiatedL2EventGUID: sentMessage.Event.GUID, InitiatedL2EventGUID: sentMessage.Event.GUID,
Nonce: sentMessage.BridgeMessage.Nonce, Nonce: sentMessage.BridgeMessage.Nonce,
GasLimit: sentMessage.BridgeMessage.GasLimit, GasLimit: sentMessage.BridgeMessage.GasLimit,
...@@ -166,7 +167,7 @@ func LegacyL2ProcessInitiatedBridgeEvents(log log.Logger, db *database.DB, fromH ...@@ -166,7 +167,7 @@ func LegacyL2ProcessInitiatedBridgeEvents(log log.Logger, db *database.DB, fromH
} }
l2BridgeMessages[i] = database.L2BridgeMessage{ l2BridgeMessages[i] = database.L2BridgeMessage{
TransactionWithdrawalHash: sentMessage.BridgeMessage.MessageHash, TransactionWithdrawalHash: withdrawalHash,
BridgeMessage: sentMessage.BridgeMessage, BridgeMessage: sentMessage.BridgeMessage,
} }
} }
...@@ -220,6 +221,10 @@ func LegacyL2ProcessInitiatedBridgeEvents(log log.Logger, db *database.DB, fromH ...@@ -220,6 +221,10 @@ func LegacyL2ProcessInitiatedBridgeEvents(log log.Logger, db *database.DB, fromH
// Legacy Bridge Finalization // Legacy Bridge Finalization
// LegacyL1ProcessFinalizedBridgeEvents will query for bridge events within the specified block range
// acording to the pre-bedrock protocol. This follows:
// 1. L1CrossDomainMessenger
// 2. L1StandardBridge
func LegacyL1ProcessFinalizedBridgeEvents(log log.Logger, db *database.DB, l1Client node.EthClient, chainConfig config.ChainConfig, fromHeight *big.Int, toHeight *big.Int) error { func LegacyL1ProcessFinalizedBridgeEvents(log log.Logger, db *database.DB, l1Client node.EthClient, chainConfig config.ChainConfig, fromHeight *big.Int, toHeight *big.Int) error {
// (1) L1CrossDomainMessenger -> This is the root-most contract from which bridge events are finalized since withdrawals must be initiated from the // (1) L1CrossDomainMessenger -> This is the root-most contract from which bridge events are finalized since withdrawals must be initiated from the
// L2CrossDomainMessenger. Since there's no two-step withdrawal process, we mark the transaction as proven/finalized in the same step // L2CrossDomainMessenger. Since there's no two-step withdrawal process, we mark the transaction as proven/finalized in the same step
...@@ -288,13 +293,18 @@ func LegacyL1ProcessFinalizedBridgeEvents(log log.Logger, db *database.DB, l1Cli ...@@ -288,13 +293,18 @@ func LegacyL1ProcessFinalizedBridgeEvents(log log.Logger, db *database.DB, l1Cli
log.Warn("skipped pre-regensis relayed L2CrossDomainMessenger withdrawals", "size", skippedPreRegenesisMessages) log.Warn("skipped pre-regensis relayed L2CrossDomainMessenger withdrawals", "size", skippedPreRegenesisMessages)
} }
// (2) L1StandardBridge // (2) L2StandardBridge -- no-op for now as there's nothing actionable to do here besides
// no-op for now as there's nothing actionable to do here besides sanity checks that we'll skip for now // santiy checks which is not important for legacy code. The message status is already tracked
// via the relayed bridge messed through the cross domain messenger.
// a-ok! // a-ok!
return nil return nil
} }
// LegacyL2ProcessFinalizedBridgeEvents will query for bridge events within the specified block range
// acording to the pre-bedrock protocol. This follows:
// 1. L2CrossDomainMessenger
// 2. L2StandardBridge
func LegacyL2ProcessFinalizedBridgeEvents(log log.Logger, db *database.DB, fromHeight *big.Int, toHeight *big.Int) error { func LegacyL2ProcessFinalizedBridgeEvents(log log.Logger, db *database.DB, fromHeight *big.Int, toHeight *big.Int) error {
// (1) L2CrossDomainMessenger // (1) L2CrossDomainMessenger
crossDomainRelayedMessages, err := contracts.CrossDomainMessengerRelayedMessageEvents("l2", predeploys.L2CrossDomainMessengerAddr, db, fromHeight, toHeight) crossDomainRelayedMessages, err := contracts.CrossDomainMessengerRelayedMessageEvents("l2", predeploys.L2CrossDomainMessengerAddr, db, fromHeight, toHeight)
...@@ -321,8 +331,9 @@ func LegacyL2ProcessFinalizedBridgeEvents(log log.Logger, db *database.DB, fromH ...@@ -321,8 +331,9 @@ func LegacyL2ProcessFinalizedBridgeEvents(log log.Logger, db *database.DB, fromH
} }
} }
// (2) L2StandardBridge // (2) L2StandardBridge -- no-op for now as there's nothing actionable to do here besides
// no-op for now as there's nothing actionable to do here besides sanity checks that we'll skip for now // santiy checks which is not important for legacy code. The message status is already tracked
// via the relayed bridge messed through the cross domain messenger.
// a-ok! // a-ok!
return nil return nil
......
...@@ -38,14 +38,14 @@ var ( ...@@ -38,14 +38,14 @@ var (
) )
type CrossDomainMessengerSentMessageEvent struct { type CrossDomainMessengerSentMessageEvent struct {
Event *database.ContractEvent Event *database.ContractEvent
BridgeMessage database.BridgeMessage MessageCalldata []byte
BridgeMessage database.BridgeMessage
} }
type CrossDomainMessengerRelayedMessageEvent struct { type CrossDomainMessengerRelayedMessageEvent struct {
Event *database.ContractEvent Event *database.ContractEvent
MessageHash common.Hash MessageHash common.Hash
MessageCallData []byte
} }
func CrossDomainMessengerSentMessageEvents(chainSelector string, contractAddress common.Address, db *database.DB, fromHeight, toHeight *big.Int) ([]CrossDomainMessengerSentMessageEvent, error) { func CrossDomainMessengerSentMessageEvents(chainSelector string, contractAddress common.Address, db *database.DB, fromHeight, toHeight *big.Int) ([]CrossDomainMessengerSentMessageEvent, error) {
...@@ -101,15 +101,16 @@ func CrossDomainMessengerSentMessageEvents(chainSelector string, contractAddress ...@@ -101,15 +101,16 @@ func CrossDomainMessengerSentMessageEvents(chainSelector string, contractAddress
value = sentMessageExtension.Value value = sentMessageExtension.Value
} }
messageHash, err := CrossDomainMessageHash(crossDomainMessengerAbi, &sentMessage, value) messageCalldata, err := CrossDomainMessageCalldata(crossDomainMessengerAbi, &sentMessage, value)
if err != nil { if err != nil {
return nil, err return nil, err
} }
crossDomainSentMessages[i] = CrossDomainMessengerSentMessageEvent{ crossDomainSentMessages[i] = CrossDomainMessengerSentMessageEvent{
Event: &sentMessageEvents[i], Event: &sentMessageEvents[i],
MessageCalldata: messageCalldata,
BridgeMessage: database.BridgeMessage{ BridgeMessage: database.BridgeMessage{
MessageHash: messageHash, MessageHash: crypto.Keccak256Hash(messageCalldata),
Nonce: sentMessage.MessageNonce, Nonce: sentMessage.MessageNonce,
SentMessageEventGUID: sentMessageEvents[i].GUID, SentMessageEventGUID: sentMessageEvents[i].GUID,
GasLimit: sentMessage.GasLimit, GasLimit: sentMessage.GasLimit,
...@@ -157,26 +158,25 @@ func CrossDomainMessengerRelayedMessageEvents(chainSelector string, contractAddr ...@@ -157,26 +158,25 @@ func CrossDomainMessengerRelayedMessageEvents(chainSelector string, contractAddr
return crossDomainRelayedMessages, nil return crossDomainRelayedMessages, nil
} }
// Replica of `Hashing.sol#hashCrossDomainMessage` solidity implementation // Replica of `Encoding.sol#encodeCrossDomainMessage` solidity implementation
func CrossDomainMessageHash(abi *abi.ABI, sentMsg *bindings.CrossDomainMessengerSentMessage, value *big.Int) (common.Hash, error) { func CrossDomainMessageCalldata(abi *abi.ABI, sentMsg *bindings.CrossDomainMessengerSentMessage, value *big.Int) ([]byte, error) {
version, _ := DecodeVersionedNonce(sentMsg.MessageNonce) version, _ := DecodeVersionedNonce(sentMsg.MessageNonce)
switch version { switch version {
case 0: case 0:
// Legacy Message // Legacy Message
inputBytes, err := CrossDomainMessengerLegacyRelayMessageEncoding.Inputs.Pack(sentMsg.Target, sentMsg.Sender, sentMsg.Message, sentMsg.MessageNonce) inputBytes, err := CrossDomainMessengerLegacyRelayMessageEncoding.Inputs.Pack(sentMsg.Target, sentMsg.Sender, sentMsg.Message, sentMsg.MessageNonce)
if err != nil { if err != nil {
return common.Hash{}, err return nil, err
} }
msgBytes := append(CrossDomainMessengerLegacyRelayMessageEncoding.ID, inputBytes...) return append(CrossDomainMessengerLegacyRelayMessageEncoding.ID, inputBytes...), nil
return crypto.Keccak256Hash(msgBytes), nil
case 1: case 1:
// Current Message // Current Message
msgBytes, err := abi.Pack("relayMessage", sentMsg.MessageNonce, sentMsg.Sender, sentMsg.Target, value, sentMsg.GasLimit, sentMsg.Message) msgBytes, err := abi.Pack("relayMessage", sentMsg.MessageNonce, sentMsg.Sender, sentMsg.Target, value, sentMsg.GasLimit, sentMsg.Message)
if err != nil { if err != nil {
return common.Hash{}, err return nil, err
} }
return crypto.Keccak256Hash(msgBytes), nil return msgBytes, nil
} }
return common.Hash{}, fmt.Errorf("unsupported cross domain messenger version: %d", version) return nil, fmt.Errorf("unsupported cross domain messenger version: %d", version)
} }
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