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 (
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/crypto"
)
type CrossDomainMessengerSentMessage struct {
......@@ -57,5 +58,10 @@ func CrossDomainMessengerSentMessageHash(sentMessage *bindings.CrossDomainMessen
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,
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) {
args := m.Called(address, blockNumber)
return args.Get(0).(common.Hash), args.Error(1)
......
......@@ -4,6 +4,7 @@ import (
"fmt"
"math/big"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/log"
"github.com/ethereum-optimism/optimism/indexer/config"
......@@ -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
// according the pre-bedrock protocol. This follows:
// 1. L2CrossDomainMessenger
// - The LegacyMessagePasser contract cannot be used as entrypoint to bridge transactions from L2. The protocol
// 1. L2CrossDomainMessenger - 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.
// 2. L2StandardBridge
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
sentMessage := crossDomainSentMessages[i]
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
// key for the proof sha3(calldata + sender) can be derived from the fields. (NOTE: should we just use the storage key here?)
// To ensure consistency in the schema, we duplicate this as the "root" transaction withdrawal. The storage key in the message
// 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{
WithdrawalHash: sentMessage.BridgeMessage.MessageHash,
WithdrawalHash: withdrawalHash,
InitiatedL2EventGUID: sentMessage.Event.GUID,
Nonce: sentMessage.BridgeMessage.Nonce,
GasLimit: sentMessage.BridgeMessage.GasLimit,
......@@ -166,7 +167,7 @@ func LegacyL2ProcessInitiatedBridgeEvents(log log.Logger, db *database.DB, fromH
}
l2BridgeMessages[i] = database.L2BridgeMessage{
TransactionWithdrawalHash: sentMessage.BridgeMessage.MessageHash,
TransactionWithdrawalHash: withdrawalHash,
BridgeMessage: sentMessage.BridgeMessage,
}
}
......@@ -220,6 +221,10 @@ func LegacyL2ProcessInitiatedBridgeEvents(log log.Logger, db *database.DB, fromH
// 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 {
// (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
......@@ -288,13 +293,18 @@ func LegacyL1ProcessFinalizedBridgeEvents(log log.Logger, db *database.DB, l1Cli
log.Warn("skipped pre-regensis relayed L2CrossDomainMessenger withdrawals", "size", skippedPreRegenesisMessages)
}
// (2) L1StandardBridge
// no-op for now as there's nothing actionable to do here besides sanity checks that we'll skip for now
// (2) L2StandardBridge -- no-op for now as there's nothing actionable to do here besides
// 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!
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 {
// (1) L2CrossDomainMessenger
crossDomainRelayedMessages, err := contracts.CrossDomainMessengerRelayedMessageEvents("l2", predeploys.L2CrossDomainMessengerAddr, db, fromHeight, toHeight)
......@@ -321,8 +331,9 @@ func LegacyL2ProcessFinalizedBridgeEvents(log log.Logger, db *database.DB, fromH
}
}
// (2) L2StandardBridge
// no-op for now as there's nothing actionable to do here besides sanity checks that we'll skip for now
// (2) L2StandardBridge -- no-op for now as there's nothing actionable to do here besides
// 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!
return nil
......
......@@ -38,14 +38,14 @@ var (
)
type CrossDomainMessengerSentMessageEvent struct {
Event *database.ContractEvent
BridgeMessage database.BridgeMessage
Event *database.ContractEvent
MessageCalldata []byte
BridgeMessage database.BridgeMessage
}
type CrossDomainMessengerRelayedMessageEvent struct {
Event *database.ContractEvent
MessageHash common.Hash
MessageCallData []byte
Event *database.ContractEvent
MessageHash common.Hash
}
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
value = sentMessageExtension.Value
}
messageHash, err := CrossDomainMessageHash(crossDomainMessengerAbi, &sentMessage, value)
messageCalldata, err := CrossDomainMessageCalldata(crossDomainMessengerAbi, &sentMessage, value)
if err != nil {
return nil, err
}
crossDomainSentMessages[i] = CrossDomainMessengerSentMessageEvent{
Event: &sentMessageEvents[i],
Event: &sentMessageEvents[i],
MessageCalldata: messageCalldata,
BridgeMessage: database.BridgeMessage{
MessageHash: messageHash,
MessageHash: crypto.Keccak256Hash(messageCalldata),
Nonce: sentMessage.MessageNonce,
SentMessageEventGUID: sentMessageEvents[i].GUID,
GasLimit: sentMessage.GasLimit,
......@@ -157,26 +158,25 @@ func CrossDomainMessengerRelayedMessageEvents(chainSelector string, contractAddr
return crossDomainRelayedMessages, nil
}
// Replica of `Hashing.sol#hashCrossDomainMessage` solidity implementation
func CrossDomainMessageHash(abi *abi.ABI, sentMsg *bindings.CrossDomainMessengerSentMessage, value *big.Int) (common.Hash, error) {
// Replica of `Encoding.sol#encodeCrossDomainMessage` solidity implementation
func CrossDomainMessageCalldata(abi *abi.ABI, sentMsg *bindings.CrossDomainMessengerSentMessage, value *big.Int) ([]byte, error) {
version, _ := DecodeVersionedNonce(sentMsg.MessageNonce)
switch version {
case 0:
// Legacy Message
inputBytes, err := CrossDomainMessengerLegacyRelayMessageEncoding.Inputs.Pack(sentMsg.Target, sentMsg.Sender, sentMsg.Message, sentMsg.MessageNonce)
if err != nil {
return common.Hash{}, err
return nil, err
}
msgBytes := append(CrossDomainMessengerLegacyRelayMessageEncoding.ID, inputBytes...)
return crypto.Keccak256Hash(msgBytes), nil
return append(CrossDomainMessengerLegacyRelayMessageEncoding.ID, inputBytes...), nil
case 1:
// Current Message
msgBytes, err := abi.Pack("relayMessage", sentMsg.MessageNonce, sentMsg.Sender, sentMsg.Target, value, sentMsg.GasLimit, sentMsg.Message)
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