Commit 718b9b01 authored by protolambda's avatar protolambda Committed by GitHub

op-supervisor: encode full hashes (#12071)

parent 9a12768c
...@@ -21,7 +21,6 @@ import ( ...@@ -21,7 +21,6 @@ import (
"github.com/ethereum-optimism/optimism/op-supervisor/supervisor/backend/db/heads" "github.com/ethereum-optimism/optimism/op-supervisor/supervisor/backend/db/heads"
"github.com/ethereum-optimism/optimism/op-supervisor/supervisor/backend/db/logs" "github.com/ethereum-optimism/optimism/op-supervisor/supervisor/backend/db/logs"
"github.com/ethereum-optimism/optimism/op-supervisor/supervisor/backend/source" "github.com/ethereum-optimism/optimism/op-supervisor/supervisor/backend/source"
backendTypes "github.com/ethereum-optimism/optimism/op-supervisor/supervisor/backend/types"
"github.com/ethereum-optimism/optimism/op-supervisor/supervisor/frontend" "github.com/ethereum-optimism/optimism/op-supervisor/supervisor/frontend"
"github.com/ethereum-optimism/optimism/op-supervisor/supervisor/types" "github.com/ethereum-optimism/optimism/op-supervisor/supervisor/types"
) )
...@@ -191,7 +190,7 @@ func (su *SupervisorBackend) CheckMessage(identifier types.Identifier, payloadHa ...@@ -191,7 +190,7 @@ func (su *SupervisorBackend) CheckMessage(identifier types.Identifier, payloadHa
chainID := identifier.ChainID chainID := identifier.ChainID
blockNum := identifier.BlockNumber blockNum := identifier.BlockNumber
logIdx := identifier.LogIndex logIdx := identifier.LogIndex
i, err := su.db.Check(chainID, blockNum, uint32(logIdx), backendTypes.TruncateHash(payloadHash)) i, err := su.db.Check(chainID, blockNum, uint32(logIdx), payloadHash)
if errors.Is(err, logs.ErrFuture) { if errors.Is(err, logs.ErrFuture) {
return types.Unsafe, nil return types.Unsafe, nil
} }
......
...@@ -14,7 +14,6 @@ import ( ...@@ -14,7 +14,6 @@ import (
"github.com/ethereum-optimism/optimism/op-supervisor/supervisor/backend/db/entrydb" "github.com/ethereum-optimism/optimism/op-supervisor/supervisor/backend/db/entrydb"
"github.com/ethereum-optimism/optimism/op-supervisor/supervisor/backend/db/heads" "github.com/ethereum-optimism/optimism/op-supervisor/supervisor/backend/db/heads"
"github.com/ethereum-optimism/optimism/op-supervisor/supervisor/backend/db/logs" "github.com/ethereum-optimism/optimism/op-supervisor/supervisor/backend/db/logs"
backendTypes "github.com/ethereum-optimism/optimism/op-supervisor/supervisor/backend/types"
"github.com/ethereum-optimism/optimism/op-supervisor/supervisor/types" "github.com/ethereum-optimism/optimism/op-supervisor/supervisor/types"
) )
...@@ -25,8 +24,8 @@ var ( ...@@ -25,8 +24,8 @@ var (
type LogStorage interface { type LogStorage interface {
io.Closer io.Closer
AddLog(logHash backendTypes.TruncatedHash, parentBlock eth.BlockID, AddLog(logHash common.Hash, parentBlock eth.BlockID,
logIdx uint32, execMsg *backendTypes.ExecutingMessage) error logIdx uint32, execMsg *types.ExecutingMessage) error
SealBlock(parentHash common.Hash, block eth.BlockID, timestamp uint64) error SealBlock(parentHash common.Hash, block eth.BlockID, timestamp uint64) error
...@@ -45,7 +44,7 @@ type LogStorage interface { ...@@ -45,7 +44,7 @@ type LogStorage interface {
// returns ErrConflict if the log does not match the canonical chain. // returns ErrConflict if the log does not match the canonical chain.
// returns ErrFuture if the log is out of reach. // returns ErrFuture if the log is out of reach.
// returns nil if the log is known and matches the canonical chain. // returns nil if the log is known and matches the canonical chain.
Contains(blockNum uint64, logIdx uint32, logHash backendTypes.TruncatedHash) (nextIndex entrydb.EntryIdx, err error) Contains(blockNum uint64, logIdx uint32, logHash common.Hash) (nextIndex entrydb.EntryIdx, err error)
} }
var _ LogStorage = (*logs.DB)(nil) var _ LogStorage = (*logs.DB)(nil)
...@@ -125,7 +124,7 @@ func (db *ChainsDB) StartCrossHeadMaintenance(ctx context.Context) { ...@@ -125,7 +124,7 @@ func (db *ChainsDB) StartCrossHeadMaintenance(ctx context.Context) {
} }
// Check calls the underlying logDB to determine if the given log entry is safe with respect to the checker's criteria. // Check calls the underlying logDB to determine if the given log entry is safe with respect to the checker's criteria.
func (db *ChainsDB) Check(chain types.ChainID, blockNum uint64, logIdx uint32, logHash backendTypes.TruncatedHash) (entrydb.EntryIdx, error) { func (db *ChainsDB) Check(chain types.ChainID, blockNum uint64, logIdx uint32, logHash common.Hash) (entrydb.EntryIdx, error) {
logDB, ok := db.logDBs[chain] logDB, ok := db.logDBs[chain]
if !ok { if !ok {
return 0, fmt.Errorf("%w: %v", ErrUnknownChain, chain) return 0, fmt.Errorf("%w: %v", ErrUnknownChain, chain)
...@@ -267,7 +266,7 @@ func (db *ChainsDB) SealBlock(chain types.ChainID, parentHash common.Hash, block ...@@ -267,7 +266,7 @@ func (db *ChainsDB) SealBlock(chain types.ChainID, parentHash common.Hash, block
return logDB.SealBlock(parentHash, block, timestamp) return logDB.SealBlock(parentHash, block, timestamp)
} }
func (db *ChainsDB) AddLog(chain types.ChainID, logHash backendTypes.TruncatedHash, parentBlock eth.BlockID, logIdx uint32, execMsg *backendTypes.ExecutingMessage) error { func (db *ChainsDB) AddLog(chain types.ChainID, logHash common.Hash, parentBlock eth.BlockID, logIdx uint32, execMsg *types.ExecutingMessage) error {
logDB, ok := db.logDBs[chain] logDB, ok := db.logDBs[chain]
if !ok { if !ok {
return fmt.Errorf("%w: %v", ErrUnknownChain, chain) return fmt.Errorf("%w: %v", ErrUnknownChain, chain)
......
...@@ -16,14 +16,13 @@ import ( ...@@ -16,14 +16,13 @@ import (
"github.com/ethereum-optimism/optimism/op-supervisor/supervisor/backend/db/entrydb" "github.com/ethereum-optimism/optimism/op-supervisor/supervisor/backend/db/entrydb"
"github.com/ethereum-optimism/optimism/op-supervisor/supervisor/backend/db/heads" "github.com/ethereum-optimism/optimism/op-supervisor/supervisor/backend/db/heads"
"github.com/ethereum-optimism/optimism/op-supervisor/supervisor/backend/db/logs" "github.com/ethereum-optimism/optimism/op-supervisor/supervisor/backend/db/logs"
backendTypes "github.com/ethereum-optimism/optimism/op-supervisor/supervisor/backend/types"
"github.com/ethereum-optimism/optimism/op-supervisor/supervisor/types" "github.com/ethereum-optimism/optimism/op-supervisor/supervisor/types"
) )
func TestChainsDB_AddLog(t *testing.T) { func TestChainsDB_AddLog(t *testing.T) {
t.Run("UnknownChain", func(t *testing.T) { t.Run("UnknownChain", func(t *testing.T) {
db := NewChainsDB(nil, &stubHeadStorage{}, testlog.Logger(t, log.LevelDebug)) db := NewChainsDB(nil, &stubHeadStorage{}, testlog.Logger(t, log.LevelDebug))
err := db.AddLog(types.ChainIDFromUInt64(2), backendTypes.TruncatedHash{}, eth.BlockID{}, 33, nil) err := db.AddLog(types.ChainIDFromUInt64(2), common.Hash{}, eth.BlockID{}, 33, nil)
require.ErrorIs(t, err, ErrUnknownChain) require.ErrorIs(t, err, ErrUnknownChain)
}) })
...@@ -36,7 +35,7 @@ func TestChainsDB_AddLog(t *testing.T) { ...@@ -36,7 +35,7 @@ func TestChainsDB_AddLog(t *testing.T) {
bl10 := eth.BlockID{Hash: common.Hash{0x10}, Number: 10} bl10 := eth.BlockID{Hash: common.Hash{0x10}, Number: 10}
err := db.SealBlock(chainID, common.Hash{0x9}, bl10, 1234) err := db.SealBlock(chainID, common.Hash{0x9}, bl10, 1234)
require.NoError(t, err, err) require.NoError(t, err, err)
err = db.AddLog(chainID, backendTypes.TruncatedHash{}, bl10, 0, nil) err = db.AddLog(chainID, common.Hash{}, bl10, 0, nil)
require.NoError(t, err, err) require.NoError(t, err, err)
require.Equal(t, 1, logDB.addLogCalls) require.Equal(t, 1, logDB.addLogCalls)
require.Equal(t, 1, logDB.sealBlockCalls) require.Equal(t, 1, logDB.sealBlockCalls)
...@@ -195,13 +194,13 @@ func setupStubbedForUpdateHeads(chainID types.ChainID) (*stubLogDB, *stubChecker ...@@ -195,13 +194,13 @@ func setupStubbedForUpdateHeads(chainID types.ChainID) (*stubLogDB, *stubChecker
logDB := &stubLogDB{} logDB := &stubLogDB{}
// set up stubbed executing messages that the ChainsDB can pass to the checker // set up stubbed executing messages that the ChainsDB can pass to the checker
logDB.executingMessages = []*backendTypes.ExecutingMessage{} logDB.executingMessages = []*types.ExecutingMessage{}
for i := 0; i < numExecutingMessages; i++ { for i := 0; i < numExecutingMessages; i++ {
// executing messages are packed in groups of 3, with block numbers increasing by 1 // executing messages are packed in groups of 3, with block numbers increasing by 1
logDB.executingMessages = append(logDB.executingMessages, &backendTypes.ExecutingMessage{ logDB.executingMessages = append(logDB.executingMessages, &types.ExecutingMessage{
BlockNum: uint64(100 + int(i/3)), BlockNum: uint64(100 + int(i/3)),
LogIdx: uint32(i), LogIdx: uint32(i),
Hash: backendTypes.TruncatedHash{}, Hash: common.Hash{},
}) })
} }
...@@ -210,7 +209,7 @@ func setupStubbedForUpdateHeads(chainID types.ChainID) (*stubLogDB, *stubChecker ...@@ -210,7 +209,7 @@ func setupStubbedForUpdateHeads(chainID types.ChainID) (*stubLogDB, *stubChecker
logIndex := uint32(0) logIndex := uint32(0)
executedCount := 0 executedCount := 0
for i := entrydb.EntryIdx(0); i <= local; i++ { for i := entrydb.EntryIdx(0); i <= local; i++ {
var logHash backendTypes.TruncatedHash var logHash common.Hash
rng.Read(logHash[:]) rng.Read(logHash[:])
execIndex := -1 execIndex := -1
...@@ -266,7 +265,7 @@ func (s *stubChecker) CrossHeadForChain(chainID types.ChainID) entrydb.EntryIdx ...@@ -266,7 +265,7 @@ func (s *stubChecker) CrossHeadForChain(chainID types.ChainID) entrydb.EntryIdx
} }
// stubbed Check returns true for the first numSafe calls, and false thereafter // stubbed Check returns true for the first numSafe calls, and false thereafter
func (s *stubChecker) Check(chain types.ChainID, blockNum uint64, logIdx uint32, logHash backendTypes.TruncatedHash) bool { func (s *stubChecker) Check(chain types.ChainID, blockNum uint64, logIdx uint32, logHash common.Hash) bool {
if s.checkCalls >= s.numSafe { if s.checkCalls >= s.numSafe {
return false return false
} }
...@@ -305,7 +304,7 @@ type nextLogResponse struct { ...@@ -305,7 +304,7 @@ type nextLogResponse struct {
logIdx uint32 logIdx uint32
evtHash backendTypes.TruncatedHash evtHash common.Hash
err error err error
...@@ -356,22 +355,22 @@ func (s *stubIterator) NextIndex() entrydb.EntryIdx { ...@@ -356,22 +355,22 @@ func (s *stubIterator) NextIndex() entrydb.EntryIdx {
return s.index + 1 return s.index + 1
} }
func (s *stubIterator) SealedBlock() (hash backendTypes.TruncatedHash, num uint64, ok bool) { func (s *stubIterator) SealedBlock() (hash common.Hash, num uint64, ok bool) {
panic("not yet supported") panic("not yet supported")
} }
func (s *stubIterator) InitMessage() (hash backendTypes.TruncatedHash, logIndex uint32, ok bool) { func (s *stubIterator) InitMessage() (hash common.Hash, logIndex uint32, ok bool) {
if s.index < 0 { if s.index < 0 {
return backendTypes.TruncatedHash{}, 0, false return common.Hash{}, 0, false
} }
if s.index >= entrydb.EntryIdx(len(s.db.nextLogs)) { if s.index >= entrydb.EntryIdx(len(s.db.nextLogs)) {
return backendTypes.TruncatedHash{}, 0, false return common.Hash{}, 0, false
} }
e := s.db.nextLogs[s.index] e := s.db.nextLogs[s.index]
return e.evtHash, e.logIdx, true return e.evtHash, e.logIdx, true
} }
func (s *stubIterator) ExecMessage() *backendTypes.ExecutingMessage { func (s *stubIterator) ExecMessage() *types.ExecutingMessage {
if s.index < 0 { if s.index < 0 {
return nil return nil
} }
...@@ -392,13 +391,13 @@ type stubLogDB struct { ...@@ -392,13 +391,13 @@ type stubLogDB struct {
sealBlockCalls int sealBlockCalls int
headBlockNum uint64 headBlockNum uint64
executingMessages []*backendTypes.ExecutingMessage executingMessages []*types.ExecutingMessage
nextLogs []nextLogResponse nextLogs []nextLogResponse
containsResponse containsResponse containsResponse containsResponse
} }
func (s *stubLogDB) AddLog(logHash backendTypes.TruncatedHash, parentBlock eth.BlockID, logIdx uint32, execMsg *backendTypes.ExecutingMessage) error { func (s *stubLogDB) AddLog(logHash common.Hash, parentBlock eth.BlockID, logIdx uint32, execMsg *types.ExecutingMessage) error {
s.addLogCalls++ s.addLogCalls++
return nil return nil
} }
...@@ -432,7 +431,7 @@ type containsResponse struct { ...@@ -432,7 +431,7 @@ type containsResponse struct {
// stubbed Contains records the arguments passed to it // stubbed Contains records the arguments passed to it
// it returns the response set in the struct, or an empty response // it returns the response set in the struct, or an empty response
func (s *stubLogDB) Contains(blockNum uint64, logIdx uint32, logHash backendTypes.TruncatedHash) (nextIndex entrydb.EntryIdx, err error) { func (s *stubLogDB) Contains(blockNum uint64, logIdx uint32, logHash common.Hash) (nextIndex entrydb.EntryIdx, err error) {
return s.containsResponse.index, s.containsResponse.err return s.containsResponse.index, s.containsResponse.err
} }
......
...@@ -10,7 +10,7 @@ import ( ...@@ -10,7 +10,7 @@ import (
) )
const ( const (
EntrySize = 24 EntrySize = 34
) )
type EntryIdx int64 type EntryIdx int64
......
...@@ -12,7 +12,7 @@ import ( ...@@ -12,7 +12,7 @@ import (
"github.com/ethereum-optimism/optimism/op-service/eth" "github.com/ethereum-optimism/optimism/op-service/eth"
"github.com/ethereum-optimism/optimism/op-supervisor/supervisor/backend/db/entrydb" "github.com/ethereum-optimism/optimism/op-supervisor/supervisor/backend/db/entrydb"
"github.com/ethereum-optimism/optimism/op-supervisor/supervisor/backend/types" "github.com/ethereum-optimism/optimism/op-supervisor/supervisor/types"
) )
const ( const (
...@@ -103,11 +103,11 @@ func (db *DB) init(trimToLastSealed bool) error { ...@@ -103,11 +103,11 @@ func (db *DB) init(trimToLastSealed bool) error {
// and is then followed up with canonical-hash entry of genesis. // and is then followed up with canonical-hash entry of genesis.
db.lastEntryContext = logContext{ db.lastEntryContext = logContext{
nextEntryIndex: 0, nextEntryIndex: 0,
blockHash: types.TruncatedHash{}, blockHash: common.Hash{},
blockNum: 0, blockNum: 0,
timestamp: 0, timestamp: 0,
logsSince: 0, logsSince: 0,
logHash: types.TruncatedHash{}, logHash: common.Hash{},
execMsg: nil, execMsg: nil,
out: nil, out: nil,
} }
...@@ -199,7 +199,7 @@ func (db *DB) FindSealedBlock(block eth.BlockID) (nextEntry entrydb.EntryIdx, er ...@@ -199,7 +199,7 @@ func (db *DB) FindSealedBlock(block eth.BlockID) (nextEntry entrydb.EntryIdx, er
if !ok { if !ok {
panic("expected block") panic("expected block")
} }
if types.TruncateHash(block.Hash) != h { if block.Hash != h {
return 0, fmt.Errorf("queried %s but got %s at number %d: %w", block.Hash, h, block.Number, ErrConflict) return 0, fmt.Errorf("queried %s but got %s at number %d: %w", block.Hash, h, block.Number, ErrConflict)
} }
return iter.NextIndex(), nil return iter.NextIndex(), nil
...@@ -220,9 +220,9 @@ func (db *DB) LatestSealedBlockNum() (n uint64, ok bool) { ...@@ -220,9 +220,9 @@ func (db *DB) LatestSealedBlockNum() (n uint64, ok bool) {
return db.lastEntryContext.blockNum, true return db.lastEntryContext.blockNum, true
} }
// Get returns the truncated hash of the log at the specified blockNum (of the sealed block) // Get returns the hash of the log at the specified blockNum (of the sealed block)
// and logIdx (of the log after the block), or an error if the log is not found. // and logIdx (of the log after the block), or an error if the log is not found.
func (db *DB) Get(blockNum uint64, logIdx uint32) (types.TruncatedHash, error) { func (db *DB) Get(blockNum uint64, logIdx uint32) (common.Hash, error) {
db.rwLock.RLock() db.rwLock.RLock()
defer db.rwLock.RUnlock() defer db.rwLock.RUnlock()
hash, _, err := db.findLogInfo(blockNum, logIdx) hash, _, err := db.findLogInfo(blockNum, logIdx)
...@@ -234,7 +234,7 @@ func (db *DB) Get(blockNum uint64, logIdx uint32) (types.TruncatedHash, error) { ...@@ -234,7 +234,7 @@ func (db *DB) Get(blockNum uint64, logIdx uint32) (types.TruncatedHash, error) {
// If the log is determined to conflict with the canonical chain, then ErrConflict is returned. // If the log is determined to conflict with the canonical chain, then ErrConflict is returned.
// logIdx is the index of the log in the array of all logs in the block. // logIdx is the index of the log in the array of all logs in the block.
// This can be used to check the validity of cross-chain interop events. // This can be used to check the validity of cross-chain interop events.
func (db *DB) Contains(blockNum uint64, logIdx uint32, logHash types.TruncatedHash) (entrydb.EntryIdx, error) { func (db *DB) Contains(blockNum uint64, logIdx uint32, logHash common.Hash) (entrydb.EntryIdx, error) {
db.rwLock.RLock() db.rwLock.RLock()
defer db.rwLock.RUnlock() defer db.rwLock.RUnlock()
db.log.Trace("Checking for log", "blockNum", blockNum, "logIdx", logIdx, "hash", logHash) db.log.Trace("Checking for log", "blockNum", blockNum, "logIdx", logIdx, "hash", logHash)
...@@ -251,29 +251,29 @@ func (db *DB) Contains(blockNum uint64, logIdx uint32, logHash types.TruncatedHa ...@@ -251,29 +251,29 @@ func (db *DB) Contains(blockNum uint64, logIdx uint32, logHash types.TruncatedHa
return iter.NextIndex(), nil return iter.NextIndex(), nil
} }
func (db *DB) findLogInfo(blockNum uint64, logIdx uint32) (types.TruncatedHash, Iterator, error) { func (db *DB) findLogInfo(blockNum uint64, logIdx uint32) (common.Hash, Iterator, error) {
if blockNum == 0 { if blockNum == 0 {
return types.TruncatedHash{}, nil, ErrConflict // no logs in block 0 return common.Hash{}, nil, ErrConflict // no logs in block 0
} }
// blockNum-1, such that we find a log that came after the parent num-1 was sealed. // blockNum-1, such that we find a log that came after the parent num-1 was sealed.
// logIdx, such that all entries before logIdx can be skipped, but logIdx itself is still readable. // logIdx, such that all entries before logIdx can be skipped, but logIdx itself is still readable.
iter, err := db.newIteratorAt(blockNum-1, logIdx) iter, err := db.newIteratorAt(blockNum-1, logIdx)
if errors.Is(err, ErrFuture) { if errors.Is(err, ErrFuture) {
db.log.Trace("Could not find log yet", "blockNum", blockNum, "logIdx", logIdx) db.log.Trace("Could not find log yet", "blockNum", blockNum, "logIdx", logIdx)
return types.TruncatedHash{}, nil, err return common.Hash{}, nil, err
} else if err != nil { } else if err != nil {
db.log.Error("Failed searching for log", "blockNum", blockNum, "logIdx", logIdx) db.log.Error("Failed searching for log", "blockNum", blockNum, "logIdx", logIdx)
return types.TruncatedHash{}, nil, err return common.Hash{}, nil, err
} }
if err := iter.NextInitMsg(); err != nil { if err := iter.NextInitMsg(); err != nil {
return types.TruncatedHash{}, nil, fmt.Errorf("failed to read initiating message %d, on top of block %d: %w", logIdx, blockNum, err) return common.Hash{}, nil, fmt.Errorf("failed to read initiating message %d, on top of block %d: %w", logIdx, blockNum, err)
} }
if _, x, ok := iter.SealedBlock(); !ok { if _, x, ok := iter.SealedBlock(); !ok {
panic("expected block") panic("expected block")
} else if x < blockNum-1 { } else if x < blockNum-1 {
panic(fmt.Errorf("bug in newIteratorAt, expected to have found parent block %d but got %d", blockNum-1, x)) panic(fmt.Errorf("bug in newIteratorAt, expected to have found parent block %d but got %d", blockNum-1, x))
} else if x > blockNum-1 { } else if x > blockNum-1 {
return types.TruncatedHash{}, nil, fmt.Errorf("log does not exist, found next block already: %w", ErrConflict) return common.Hash{}, nil, fmt.Errorf("log does not exist, found next block already: %w", ErrConflict)
} }
logHash, x, ok := iter.InitMessage() logHash, x, ok := iter.InitMessage()
if !ok { if !ok {
...@@ -459,7 +459,7 @@ func (db *DB) SealBlock(parentHash common.Hash, block eth.BlockID, timestamp uin ...@@ -459,7 +459,7 @@ func (db *DB) SealBlock(parentHash common.Hash, block eth.BlockID, timestamp uin
return db.flush() return db.flush()
} }
func (db *DB) AddLog(logHash types.TruncatedHash, parentBlock eth.BlockID, logIdx uint32, execMsg *types.ExecutingMessage) error { func (db *DB) AddLog(logHash common.Hash, parentBlock eth.BlockID, logIdx uint32, execMsg *types.ExecutingMessage) error {
db.rwLock.Lock() db.rwLock.Lock()
defer db.rwLock.Unlock() defer db.rwLock.Unlock()
......
...@@ -4,8 +4,10 @@ import ( ...@@ -4,8 +4,10 @@ import (
"encoding/binary" "encoding/binary"
"fmt" "fmt"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum-optimism/optimism/op-supervisor/supervisor/backend/db/entrydb" "github.com/ethereum-optimism/optimism/op-supervisor/supervisor/backend/db/entrydb"
"github.com/ethereum-optimism/optimism/op-supervisor/supervisor/backend/types" "github.com/ethereum-optimism/optimism/op-supervisor/supervisor/types"
) )
// searchCheckpoint is both a checkpoint for searching, as well as a checkpoint for sealing blocks. // searchCheckpoint is both a checkpoint for searching, as well as a checkpoint for sealing blocks.
...@@ -48,10 +50,10 @@ func (s searchCheckpoint) encode() entrydb.Entry { ...@@ -48,10 +50,10 @@ func (s searchCheckpoint) encode() entrydb.Entry {
} }
type canonicalHash struct { type canonicalHash struct {
hash types.TruncatedHash hash common.Hash
} }
func newCanonicalHash(hash types.TruncatedHash) canonicalHash { func newCanonicalHash(hash common.Hash) canonicalHash {
return canonicalHash{hash: hash} return canonicalHash{hash: hash}
} }
...@@ -59,21 +61,19 @@ func newCanonicalHashFromEntry(data entrydb.Entry) (canonicalHash, error) { ...@@ -59,21 +61,19 @@ func newCanonicalHashFromEntry(data entrydb.Entry) (canonicalHash, error) {
if data.Type() != entrydb.TypeCanonicalHash { if data.Type() != entrydb.TypeCanonicalHash {
return canonicalHash{}, fmt.Errorf("%w: attempting to decode canonical hash but was type %s", ErrDataCorruption, data.Type()) return canonicalHash{}, fmt.Errorf("%w: attempting to decode canonical hash but was type %s", ErrDataCorruption, data.Type())
} }
var truncated types.TruncatedHash return newCanonicalHash(common.Hash(data[1:33])), nil
copy(truncated[:], data[1:21])
return newCanonicalHash(truncated), nil
} }
func (c canonicalHash) encode() entrydb.Entry { func (c canonicalHash) encode() entrydb.Entry {
var entry entrydb.Entry var entry entrydb.Entry
entry[0] = uint8(entrydb.TypeCanonicalHash) entry[0] = uint8(entrydb.TypeCanonicalHash)
copy(entry[1:21], c.hash[:]) copy(entry[1:33], c.hash[:])
return entry return entry
} }
type initiatingEvent struct { type initiatingEvent struct {
hasExecMsg bool hasExecMsg bool
logHash types.TruncatedHash logHash common.Hash
} }
func newInitiatingEventFromEntry(data entrydb.Entry) (initiatingEvent, error) { func newInitiatingEventFromEntry(data entrydb.Entry) (initiatingEvent, error) {
...@@ -83,11 +83,11 @@ func newInitiatingEventFromEntry(data entrydb.Entry) (initiatingEvent, error) { ...@@ -83,11 +83,11 @@ func newInitiatingEventFromEntry(data entrydb.Entry) (initiatingEvent, error) {
flags := data[1] flags := data[1]
return initiatingEvent{ return initiatingEvent{
hasExecMsg: flags&eventFlagHasExecutingMessage != 0, hasExecMsg: flags&eventFlagHasExecutingMessage != 0,
logHash: types.TruncatedHash(data[2:22]), logHash: common.Hash(data[2:34]),
}, nil }, nil
} }
func newInitiatingEvent(logHash types.TruncatedHash, hasExecMsg bool) initiatingEvent { func newInitiatingEvent(logHash common.Hash, hasExecMsg bool) initiatingEvent {
return initiatingEvent{ return initiatingEvent{
hasExecMsg: hasExecMsg, hasExecMsg: hasExecMsg,
logHash: logHash, logHash: logHash,
...@@ -104,7 +104,7 @@ func (i initiatingEvent) encode() entrydb.Entry { ...@@ -104,7 +104,7 @@ func (i initiatingEvent) encode() entrydb.Entry {
flags = flags | eventFlagHasExecutingMessage flags = flags | eventFlagHasExecutingMessage
} }
data[1] = flags data[1] = flags
copy(data[2:22], i.logHash[:]) copy(data[2:34], i.logHash[:])
return data return data
} }
...@@ -157,10 +157,10 @@ func (e executingLink) encode() entrydb.Entry { ...@@ -157,10 +157,10 @@ func (e executingLink) encode() entrydb.Entry {
} }
type executingCheck struct { type executingCheck struct {
hash types.TruncatedHash hash common.Hash
} }
func newExecutingCheck(hash types.TruncatedHash) executingCheck { func newExecutingCheck(hash common.Hash) executingCheck {
return executingCheck{hash: hash} return executingCheck{hash: hash}
} }
...@@ -168,24 +168,22 @@ func newExecutingCheckFromEntry(data entrydb.Entry) (executingCheck, error) { ...@@ -168,24 +168,22 @@ func newExecutingCheckFromEntry(data entrydb.Entry) (executingCheck, error) {
if data.Type() != entrydb.TypeExecutingCheck { if data.Type() != entrydb.TypeExecutingCheck {
return executingCheck{}, fmt.Errorf("%w: attempting to decode executing check but was type %s", ErrDataCorruption, data.Type()) return executingCheck{}, fmt.Errorf("%w: attempting to decode executing check but was type %s", ErrDataCorruption, data.Type())
} }
var hash types.TruncatedHash return newExecutingCheck(common.Hash(data[1:33])), nil
copy(hash[:], data[1:21])
return newExecutingCheck(hash), nil
} }
// encode creates an executing check entry // encode creates an executing check entry
// type 4: "executing check" <type><event-hash: 20 bytes> = 21 bytes // type 4: "executing check" <type><event-hash: 32 bytes> = 33 bytes
func (e executingCheck) encode() entrydb.Entry { func (e executingCheck) encode() entrydb.Entry {
var entry entrydb.Entry var entry entrydb.Entry
entry[0] = uint8(entrydb.TypeExecutingCheck) entry[0] = uint8(entrydb.TypeExecutingCheck)
copy(entry[1:21], e.hash[:]) copy(entry[1:33], e.hash[:])
return entry return entry
} }
type paddingEntry struct{} type paddingEntry struct{}
// encoding of the padding entry // encoding of the padding entry
// type 5: "padding" <type><padding: 23 bytes> = 24 bytes // type 5: "padding" <type><padding: 33 bytes> = 34 bytes
func (e paddingEntry) encode() entrydb.Entry { func (e paddingEntry) encode() entrydb.Entry {
var entry entrydb.Entry var entry entrydb.Entry
entry[0] = uint8(entrydb.TypePadding) entry[0] = uint8(entrydb.TypePadding)
......
...@@ -5,14 +5,16 @@ import ( ...@@ -5,14 +5,16 @@ import (
"fmt" "fmt"
"io" "io"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum-optimism/optimism/op-supervisor/supervisor/backend/db/entrydb" "github.com/ethereum-optimism/optimism/op-supervisor/supervisor/backend/db/entrydb"
"github.com/ethereum-optimism/optimism/op-supervisor/supervisor/backend/types" "github.com/ethereum-optimism/optimism/op-supervisor/supervisor/types"
) )
type IteratorState interface { type IteratorState interface {
NextIndex() entrydb.EntryIdx NextIndex() entrydb.EntryIdx
SealedBlock() (hash types.TruncatedHash, num uint64, ok bool) SealedBlock() (hash common.Hash, num uint64, ok bool)
InitMessage() (hash types.TruncatedHash, logIndex uint32, ok bool) InitMessage() (hash common.Hash, logIndex uint32, ok bool)
ExecMessage() *types.ExecutingMessage ExecMessage() *types.ExecutingMessage
} }
...@@ -127,12 +129,12 @@ func (i *iterator) NextIndex() entrydb.EntryIdx { ...@@ -127,12 +129,12 @@ func (i *iterator) NextIndex() entrydb.EntryIdx {
// SealedBlock returns the sealed block that we are appending logs after, if any is available. // SealedBlock returns the sealed block that we are appending logs after, if any is available.
// I.e. the block is the parent block of the block containing the logs that are currently appending to it. // I.e. the block is the parent block of the block containing the logs that are currently appending to it.
func (i *iterator) SealedBlock() (hash types.TruncatedHash, num uint64, ok bool) { func (i *iterator) SealedBlock() (hash common.Hash, num uint64, ok bool) {
return i.current.SealedBlock() return i.current.SealedBlock()
} }
// InitMessage returns the current initiating message, if any is available. // InitMessage returns the current initiating message, if any is available.
func (i *iterator) InitMessage() (hash types.TruncatedHash, logIndex uint32, ok bool) { func (i *iterator) InitMessage() (hash common.Hash, logIndex uint32, ok bool) {
return i.current.InitMessage() return i.current.InitMessage()
} }
......
...@@ -9,7 +9,7 @@ import ( ...@@ -9,7 +9,7 @@ import (
"github.com/ethereum-optimism/optimism/op-service/eth" "github.com/ethereum-optimism/optimism/op-service/eth"
"github.com/ethereum-optimism/optimism/op-supervisor/supervisor/backend/db/entrydb" "github.com/ethereum-optimism/optimism/op-supervisor/supervisor/backend/db/entrydb"
"github.com/ethereum-optimism/optimism/op-supervisor/supervisor/backend/types" "github.com/ethereum-optimism/optimism/op-supervisor/supervisor/types"
) )
// logContext is a buffer on top of the DB, // logContext is a buffer on top of the DB,
...@@ -32,14 +32,14 @@ import ( ...@@ -32,14 +32,14 @@ import (
// //
// Types (<type> = 1 byte): // Types (<type> = 1 byte):
// type 0: "checkpoint" <type><uint64 block number: 8 bytes><uint32 logsSince count: 4 bytes><uint64 timestamp: 8 bytes> = 21 bytes // type 0: "checkpoint" <type><uint64 block number: 8 bytes><uint32 logsSince count: 4 bytes><uint64 timestamp: 8 bytes> = 21 bytes
// type 1: "canonical hash" <type><parent blockhash truncated: 20 bytes> = 21 bytes // type 1: "canonical hash" <type><parent blockhash: 32 bytes> = 33 bytes
// type 2: "initiating event" <type><event flags: 1 byte><event-hash: 20 bytes> = 22 bytes // type 2: "initiating event" <type><event flags: 1 byte><event-hash: 32 bytes> = 34 bytes
// type 3: "executing link" <type><chain: 4 bytes><blocknum: 8 bytes><event index: 3 bytes><uint64 timestamp: 8 bytes> = 24 bytes // type 3: "executing link" <type><chain: 4 bytes><blocknum: 8 bytes><event index: 3 bytes><uint64 timestamp: 8 bytes> = 24 bytes
// type 4: "executing check" <type><event-hash: 20 bytes> = 21 bytes // type 4: "executing check" <type><event-hash: 32 bytes> = 33 bytes
// type 5: "padding" <type><padding: 23 bytes> = 24 bytes // type 5: "padding" <type><padding: 33 bytes> = 34 bytes
// other types: future compat. E.g. for linking to L1, registering block-headers as a kind of initiating-event, tracking safe-head progression, etc. // other types: future compat. E.g. for linking to L1, registering block-headers as a kind of initiating-event, tracking safe-head progression, etc.
// //
// Right-pad each entry that is not 24 bytes. // Right-pad each entry that is not 34 bytes.
// //
// We insert a checkpoint for every search interval and block sealing event, // We insert a checkpoint for every search interval and block sealing event,
// and these may overlap as the same thing. // and these may overlap as the same thing.
...@@ -55,7 +55,7 @@ type logContext struct { ...@@ -55,7 +55,7 @@ type logContext struct {
// blockHash of the last sealed block. // blockHash of the last sealed block.
// A block is not considered sealed until we know its block hash. // A block is not considered sealed until we know its block hash.
// While we process logs we keep the parent-block of said logs around as sealed block. // While we process logs we keep the parent-block of said logs around as sealed block.
blockHash types.TruncatedHash blockHash common.Hash
// blockNum of the last sealed block // blockNum of the last sealed block
blockNum uint64 blockNum uint64
// timestamp of the last sealed block // timestamp of the last sealed block
...@@ -65,7 +65,7 @@ type logContext struct { ...@@ -65,7 +65,7 @@ type logContext struct {
logsSince uint32 logsSince uint32
// payload-hash of the log-event that was last processed. (may not be fully processed, see doneLog) // payload-hash of the log-event that was last processed. (may not be fully processed, see doneLog)
logHash types.TruncatedHash logHash common.Hash
// executing message that might exist for the current log event. // executing message that might exist for the current log event.
// Might be incomplete; if !logDone while we already processed the initiating event, // Might be incomplete; if !logDone while we already processed the initiating event,
...@@ -91,9 +91,9 @@ func (l *logContext) NextIndex() entrydb.EntryIdx { ...@@ -91,9 +91,9 @@ func (l *logContext) NextIndex() entrydb.EntryIdx {
} }
// SealedBlock returns the block that we are building on top of, and if it is sealed. // SealedBlock returns the block that we are building on top of, and if it is sealed.
func (l *logContext) SealedBlock() (hash types.TruncatedHash, num uint64, ok bool) { func (l *logContext) SealedBlock() (hash common.Hash, num uint64, ok bool) {
if !l.hasCompleteBlock() { if !l.hasCompleteBlock() {
return types.TruncatedHash{}, 0, false return common.Hash{}, 0, false
} }
return l.blockHash, l.blockNum, true return l.blockHash, l.blockNum, true
} }
...@@ -111,9 +111,9 @@ func (l *logContext) hasReadableLog() bool { ...@@ -111,9 +111,9 @@ func (l *logContext) hasReadableLog() bool {
} }
// InitMessage returns the current initiating message, if any is available. // InitMessage returns the current initiating message, if any is available.
func (l *logContext) InitMessage() (hash types.TruncatedHash, logIndex uint32, ok bool) { func (l *logContext) InitMessage() (hash common.Hash, logIndex uint32, ok bool) {
if !l.hasReadableLog() { if !l.hasReadableLog() {
return types.TruncatedHash{}, 0, false return common.Hash{}, 0, false
} }
return l.logHash, l.logsSince - 1, true return l.logHash, l.logsSince - 1, true
} }
...@@ -150,13 +150,13 @@ func (l *logContext) processEntry(entry entrydb.Entry) error { ...@@ -150,13 +150,13 @@ func (l *logContext) processEntry(entry entrydb.Entry) error {
return err return err
} }
l.blockNum = current.blockNum l.blockNum = current.blockNum
l.blockHash = types.TruncatedHash{} l.blockHash = common.Hash{}
l.logsSince = current.logsSince // TODO this is bumping the logsSince? l.logsSince = current.logsSince // TODO this is bumping the logsSince?
l.timestamp = current.timestamp l.timestamp = current.timestamp
l.need.Add(entrydb.FlagCanonicalHash) l.need.Add(entrydb.FlagCanonicalHash)
// Log data after the block we are sealing remains to be seen // Log data after the block we are sealing remains to be seen
if l.logsSince == 0 { if l.logsSince == 0 {
l.logHash = types.TruncatedHash{} l.logHash = common.Hash{}
l.execMsg = nil l.execMsg = nil
} }
case entrydb.TypeCanonicalHash: case entrydb.TypeCanonicalHash:
...@@ -201,7 +201,7 @@ func (l *logContext) processEntry(entry entrydb.Entry) error { ...@@ -201,7 +201,7 @@ func (l *logContext) processEntry(entry entrydb.Entry) error {
BlockNum: link.blockNum, BlockNum: link.blockNum,
LogIdx: link.logIdx, LogIdx: link.logIdx,
Timestamp: link.timestamp, Timestamp: link.timestamp,
Hash: types.TruncatedHash{}, // not known yet Hash: common.Hash{}, // not known yet
} }
l.need.Remove(entrydb.FlagExecutingLink) l.need.Remove(entrydb.FlagExecutingLink)
l.need.Add(entrydb.FlagExecutingCheck) l.need.Add(entrydb.FlagExecutingCheck)
...@@ -331,12 +331,12 @@ func (l *logContext) forceBlock(upd eth.BlockID, timestamp uint64) error { ...@@ -331,12 +331,12 @@ func (l *logContext) forceBlock(upd eth.BlockID, timestamp uint64) error {
if l.nextEntryIndex != 0 { if l.nextEntryIndex != 0 {
return errors.New("can only bootstrap on top of an empty state") return errors.New("can only bootstrap on top of an empty state")
} }
l.blockHash = types.TruncateHash(upd.Hash) l.blockHash = upd.Hash
l.blockNum = upd.Number l.blockNum = upd.Number
l.timestamp = timestamp l.timestamp = timestamp
l.logsSince = 0 l.logsSince = 0
l.execMsg = nil l.execMsg = nil
l.logHash = types.TruncatedHash{} l.logHash = common.Hash{}
l.need = 0 l.need = 0
l.out = nil l.out = nil
return l.inferFull() // apply to the state as much as possible return l.inferFull() // apply to the state as much as possible
...@@ -350,29 +350,29 @@ func (l *logContext) SealBlock(parent common.Hash, upd eth.BlockID, timestamp ui ...@@ -350,29 +350,29 @@ func (l *logContext) SealBlock(parent common.Hash, upd eth.BlockID, timestamp ui
if err := l.inferFull(); err != nil { // ensure we can start applying if err := l.inferFull(); err != nil { // ensure we can start applying
return err return err
} }
if l.blockHash != types.TruncateHash(parent) { if l.blockHash != parent {
return fmt.Errorf("%w: cannot apply block %s (parent %s) on top of %s", ErrConflict, upd, parent, l.blockHash) return fmt.Errorf("%w: cannot apply block %s (parent %s) on top of %s", ErrConflict, upd, parent, l.blockHash)
} }
if l.blockHash != (types.TruncatedHash{}) && l.blockNum+1 != upd.Number { if l.blockHash != (common.Hash{}) && l.blockNum+1 != upd.Number {
return fmt.Errorf("%w: cannot apply block %d on top of %d", ErrConflict, upd.Number, l.blockNum) return fmt.Errorf("%w: cannot apply block %d on top of %d", ErrConflict, upd.Number, l.blockNum)
} }
if l.timestamp > timestamp { if l.timestamp > timestamp {
return fmt.Errorf("%w: block timestamp %d must be equal or larger than current timestamp %d", ErrConflict, timestamp, l.timestamp) return fmt.Errorf("%w: block timestamp %d must be equal or larger than current timestamp %d", ErrConflict, timestamp, l.timestamp)
} }
} }
l.blockHash = types.TruncateHash(upd.Hash) l.blockHash = upd.Hash
l.blockNum = upd.Number l.blockNum = upd.Number
l.timestamp = timestamp l.timestamp = timestamp
l.logsSince = 0 l.logsSince = 0
l.execMsg = nil l.execMsg = nil
l.logHash = types.TruncatedHash{} l.logHash = common.Hash{}
l.need.Add(entrydb.FlagSearchCheckpoint) l.need.Add(entrydb.FlagSearchCheckpoint)
return l.inferFull() // apply to the state as much as possible return l.inferFull() // apply to the state as much as possible
} }
// ApplyLog applies a log on top of the current state. // ApplyLog applies a log on top of the current state.
// The parent-block that the log comes after must be applied with ApplyBlock first. // The parent-block that the log comes after must be applied with ApplyBlock first.
func (l *logContext) ApplyLog(parentBlock eth.BlockID, logIdx uint32, logHash types.TruncatedHash, execMsg *types.ExecutingMessage) error { func (l *logContext) ApplyLog(parentBlock eth.BlockID, logIdx uint32, logHash common.Hash, execMsg *types.ExecutingMessage) error {
if parentBlock == (eth.BlockID{}) { if parentBlock == (eth.BlockID{}) {
return fmt.Errorf("genesis does not have logs: %w", ErrLogOutOfOrder) return fmt.Errorf("genesis does not have logs: %w", ErrLogOutOfOrder)
} }
...@@ -387,7 +387,7 @@ func (l *logContext) ApplyLog(parentBlock eth.BlockID, logIdx uint32, logHash ty ...@@ -387,7 +387,7 @@ func (l *logContext) ApplyLog(parentBlock eth.BlockID, logIdx uint32, logHash ty
} }
} }
// check parent block // check parent block
if l.blockHash != types.TruncateHash(parentBlock.Hash) { if l.blockHash != parentBlock.Hash {
return fmt.Errorf("%w: log builds on top of block %s, but have block %s", ErrLogOutOfOrder, parentBlock, l.blockHash) return fmt.Errorf("%w: log builds on top of block %s, but have block %s", ErrLogOutOfOrder, parentBlock, l.blockHash)
} }
if l.blockNum != parentBlock.Number { if l.blockNum != parentBlock.Number {
......
...@@ -3,10 +3,11 @@ package db ...@@ -3,10 +3,11 @@ package db
import ( import (
"errors" "errors"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum-optimism/optimism/op-supervisor/supervisor/backend/db/entrydb" "github.com/ethereum-optimism/optimism/op-supervisor/supervisor/backend/db/entrydb"
"github.com/ethereum-optimism/optimism/op-supervisor/supervisor/backend/db/heads" "github.com/ethereum-optimism/optimism/op-supervisor/supervisor/backend/db/heads"
"github.com/ethereum-optimism/optimism/op-supervisor/supervisor/backend/db/logs" "github.com/ethereum-optimism/optimism/op-supervisor/supervisor/backend/db/logs"
backendTypes "github.com/ethereum-optimism/optimism/op-supervisor/supervisor/backend/types"
"github.com/ethereum-optimism/optimism/op-supervisor/supervisor/types" "github.com/ethereum-optimism/optimism/op-supervisor/supervisor/types"
) )
...@@ -21,7 +22,7 @@ const ( ...@@ -21,7 +22,7 @@ const (
type SafetyChecker interface { type SafetyChecker interface {
LocalHeadForChain(chainID types.ChainID) entrydb.EntryIdx LocalHeadForChain(chainID types.ChainID) entrydb.EntryIdx
CrossHeadForChain(chainID types.ChainID) entrydb.EntryIdx CrossHeadForChain(chainID types.ChainID) entrydb.EntryIdx
Check(chain types.ChainID, blockNum uint64, logIdx uint32, logHash backendTypes.TruncatedHash) bool Check(chain types.ChainID, blockNum uint64, logIdx uint32, logHash common.Hash) bool
Update(chain types.ChainID, index entrydb.EntryIdx) heads.OperationFn Update(chain types.ChainID, index entrydb.EntryIdx) heads.OperationFn
Name() string Name() string
SafetyLevel() types.SafetyLevel SafetyLevel() types.SafetyLevel
...@@ -129,7 +130,7 @@ func check( ...@@ -129,7 +130,7 @@ func check(
chain types.ChainID, chain types.ChainID,
blockNum uint64, blockNum uint64,
logIdx uint32, logIdx uint32,
logHash backendTypes.TruncatedHash) bool { logHash common.Hash) bool {
// for the Check to be valid, the log must: // for the Check to be valid, the log must:
// exist at the blockNum and logIdx // exist at the blockNum and logIdx
...@@ -150,13 +151,13 @@ func check( ...@@ -150,13 +151,13 @@ func check(
// Check checks if the log entry is safe, provided a local head for the chain // Check checks if the log entry is safe, provided a local head for the chain
// it passes on the local head this checker is concerned with, along with its view of the database // it passes on the local head this checker is concerned with, along with its view of the database
func (c *unsafeChecker) Check(chain types.ChainID, blockNum uint64, logIdx uint32, logHash backendTypes.TruncatedHash) bool { func (c *unsafeChecker) Check(chain types.ChainID, blockNum uint64, logIdx uint32, logHash common.Hash) bool {
return check(c.chainsDB, c.LocalHeadForChain(chain), chain, blockNum, logIdx, logHash) return check(c.chainsDB, c.LocalHeadForChain(chain), chain, blockNum, logIdx, logHash)
} }
func (c *safeChecker) Check(chain types.ChainID, blockNum uint64, logIdx uint32, logHash backendTypes.TruncatedHash) bool { func (c *safeChecker) Check(chain types.ChainID, blockNum uint64, logIdx uint32, logHash common.Hash) bool {
return check(c.chainsDB, c.LocalHeadForChain(chain), chain, blockNum, logIdx, logHash) return check(c.chainsDB, c.LocalHeadForChain(chain), chain, blockNum, logIdx, logHash)
} }
func (c *finalizedChecker) Check(chain types.ChainID, blockNum uint64, logIdx uint32, logHash backendTypes.TruncatedHash) bool { func (c *finalizedChecker) Check(chain types.ChainID, blockNum uint64, logIdx uint32, logHash common.Hash) bool {
return check(c.chainsDB, c.LocalHeadForChain(chain), chain, blockNum, logIdx, logHash) return check(c.chainsDB, c.LocalHeadForChain(chain), chain, blockNum, logIdx, logHash)
} }
......
...@@ -6,13 +6,13 @@ import ( ...@@ -6,13 +6,13 @@ import (
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/log"
"github.com/ethereum-optimism/optimism/op-service/testlog" "github.com/ethereum-optimism/optimism/op-service/testlog"
"github.com/ethereum-optimism/optimism/op-supervisor/supervisor/backend/db/entrydb" "github.com/ethereum-optimism/optimism/op-supervisor/supervisor/backend/db/entrydb"
"github.com/ethereum-optimism/optimism/op-supervisor/supervisor/backend/db/heads" "github.com/ethereum-optimism/optimism/op-supervisor/supervisor/backend/db/heads"
"github.com/ethereum-optimism/optimism/op-supervisor/supervisor/backend/db/logs" "github.com/ethereum-optimism/optimism/op-supervisor/supervisor/backend/db/logs"
backendTypes "github.com/ethereum-optimism/optimism/op-supervisor/supervisor/backend/types"
"github.com/ethereum-optimism/optimism/op-supervisor/supervisor/types" "github.com/ethereum-optimism/optimism/op-supervisor/supervisor/types"
) )
...@@ -105,7 +105,7 @@ func TestCheck(t *testing.T) { ...@@ -105,7 +105,7 @@ func TestCheck(t *testing.T) {
chainID types.ChainID chainID types.ChainID
blockNum uint64 blockNum uint64
logIdx uint32 logIdx uint32
loghash backendTypes.TruncatedHash loghash common.Hash
containsResponse containsResponse containsResponse containsResponse
expected bool expected bool
}{ }{
...@@ -117,7 +117,7 @@ func TestCheck(t *testing.T) { ...@@ -117,7 +117,7 @@ func TestCheck(t *testing.T) {
types.ChainIDFromUInt64(1), types.ChainIDFromUInt64(1),
1, 1,
1, 1,
backendTypes.TruncatedHash{1, 2, 3}, common.Hash{1, 2, 3},
containsResponse{entrydb.EntryIdx(6), nil}, containsResponse{entrydb.EntryIdx(6), nil},
true, true,
}, },
...@@ -128,7 +128,7 @@ func TestCheck(t *testing.T) { ...@@ -128,7 +128,7 @@ func TestCheck(t *testing.T) {
types.ChainIDFromUInt64(1), types.ChainIDFromUInt64(1),
1, 1,
1, 1,
backendTypes.TruncatedHash{1, 2, 3}, common.Hash{1, 2, 3},
containsResponse{entrydb.EntryIdx(3), nil}, containsResponse{entrydb.EntryIdx(3), nil},
true, true,
}, },
...@@ -139,7 +139,7 @@ func TestCheck(t *testing.T) { ...@@ -139,7 +139,7 @@ func TestCheck(t *testing.T) {
types.ChainIDFromUInt64(1), types.ChainIDFromUInt64(1),
1, 1,
1, 1,
backendTypes.TruncatedHash{1, 2, 3}, common.Hash{1, 2, 3},
containsResponse{entrydb.EntryIdx(1), nil}, containsResponse{entrydb.EntryIdx(1), nil},
true, true,
}, },
...@@ -150,7 +150,7 @@ func TestCheck(t *testing.T) { ...@@ -150,7 +150,7 @@ func TestCheck(t *testing.T) {
types.ChainIDFromUInt64(1), types.ChainIDFromUInt64(1),
1, 1,
1, 1,
backendTypes.TruncatedHash{1, 2, 3}, common.Hash{1, 2, 3},
containsResponse{entrydb.EntryIdx(1), logs.ErrConflict}, containsResponse{entrydb.EntryIdx(1), logs.ErrConflict},
false, false,
}, },
...@@ -161,7 +161,7 @@ func TestCheck(t *testing.T) { ...@@ -161,7 +161,7 @@ func TestCheck(t *testing.T) {
types.ChainIDFromUInt64(1), types.ChainIDFromUInt64(1),
1, 1,
1, 1,
backendTypes.TruncatedHash{1, 2, 3}, common.Hash{1, 2, 3},
containsResponse{entrydb.EntryIdx(100), nil}, containsResponse{entrydb.EntryIdx(100), nil},
false, false,
}, },
...@@ -172,7 +172,7 @@ func TestCheck(t *testing.T) { ...@@ -172,7 +172,7 @@ func TestCheck(t *testing.T) {
types.ChainIDFromUInt64(1), types.ChainIDFromUInt64(1),
1, 1,
1, 1,
backendTypes.TruncatedHash{1, 2, 3}, common.Hash{1, 2, 3},
containsResponse{entrydb.EntryIdx(5), nil}, containsResponse{entrydb.EntryIdx(5), nil},
false, false,
}, },
...@@ -183,7 +183,7 @@ func TestCheck(t *testing.T) { ...@@ -183,7 +183,7 @@ func TestCheck(t *testing.T) {
types.ChainIDFromUInt64(1), types.ChainIDFromUInt64(1),
1, 1,
1, 1,
backendTypes.TruncatedHash{1, 2, 3}, common.Hash{1, 2, 3},
containsResponse{entrydb.EntryIdx(3), nil}, containsResponse{entrydb.EntryIdx(3), nil},
false, false,
}, },
...@@ -194,7 +194,7 @@ func TestCheck(t *testing.T) { ...@@ -194,7 +194,7 @@ func TestCheck(t *testing.T) {
types.ChainIDFromUInt64(1), types.ChainIDFromUInt64(1),
1, 1,
1, 1,
backendTypes.TruncatedHash{1, 2, 3}, common.Hash{1, 2, 3},
containsResponse{entrydb.EntryIdx(0), errors.New("error")}, containsResponse{entrydb.EntryIdx(0), errors.New("error")},
false, false,
}, },
......
...@@ -10,7 +10,6 @@ import ( ...@@ -10,7 +10,6 @@ import (
"github.com/ethereum-optimism/optimism/op-service/predeploys" "github.com/ethereum-optimism/optimism/op-service/predeploys"
"github.com/ethereum-optimism/optimism/op-service/solabi" "github.com/ethereum-optimism/optimism/op-service/solabi"
"github.com/ethereum-optimism/optimism/op-service/sources/batching" "github.com/ethereum-optimism/optimism/op-service/sources/batching"
backendTypes "github.com/ethereum-optimism/optimism/op-supervisor/supervisor/backend/types"
"github.com/ethereum-optimism/optimism/op-supervisor/supervisor/types" "github.com/ethereum-optimism/optimism/op-supervisor/supervisor/types"
"github.com/ethereum-optimism/optimism/packages/contracts-bedrock/snapshots" "github.com/ethereum-optimism/optimism/packages/contracts-bedrock/snapshots"
"github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common"
...@@ -48,20 +47,20 @@ func NewCrossL2Inbox() *CrossL2Inbox { ...@@ -48,20 +47,20 @@ func NewCrossL2Inbox() *CrossL2Inbox {
} }
} }
func (i *CrossL2Inbox) DecodeExecutingMessageLog(l *ethTypes.Log) (backendTypes.ExecutingMessage, error) { func (i *CrossL2Inbox) DecodeExecutingMessageLog(l *ethTypes.Log) (types.ExecutingMessage, error) {
if l.Address != i.contract.Addr() { if l.Address != i.contract.Addr() {
return backendTypes.ExecutingMessage{}, fmt.Errorf("%w: log not from CrossL2Inbox", ErrEventNotFound) return types.ExecutingMessage{}, fmt.Errorf("%w: log not from CrossL2Inbox", ErrEventNotFound)
} }
// use DecodeEvent to check the name of the event // use DecodeEvent to check the name of the event
// but the actual decoding is done manually to extract the contract identifier // but the actual decoding is done manually to extract the contract identifier
name, _, err := i.contract.DecodeEvent(l) name, _, err := i.contract.DecodeEvent(l)
if errors.Is(err, batching.ErrUnknownEvent) { if errors.Is(err, batching.ErrUnknownEvent) {
return backendTypes.ExecutingMessage{}, fmt.Errorf("%w: %v", ErrEventNotFound, err.Error()) return types.ExecutingMessage{}, fmt.Errorf("%w: %v", ErrEventNotFound, err.Error())
} else if err != nil { } else if err != nil {
return backendTypes.ExecutingMessage{}, fmt.Errorf("failed to decode event: %w", err) return types.ExecutingMessage{}, fmt.Errorf("failed to decode event: %w", err)
} }
if name != eventExecutingMessage { if name != eventExecutingMessage {
return backendTypes.ExecutingMessage{}, fmt.Errorf("%w: event %v not an ExecutingMessage event", ErrEventNotFound, name) return types.ExecutingMessage{}, fmt.Errorf("%w: event %v not an ExecutingMessage event", ErrEventNotFound, name)
} }
// the second topic is the hash of the payload (the first is the event ID) // the second topic is the hash of the payload (the first is the event ID)
msgHash := l.Topics[1] msgHash := l.Topics[1]
...@@ -69,14 +68,14 @@ func (i *CrossL2Inbox) DecodeExecutingMessageLog(l *ethTypes.Log) (backendTypes. ...@@ -69,14 +68,14 @@ func (i *CrossL2Inbox) DecodeExecutingMessageLog(l *ethTypes.Log) (backendTypes.
identifierBytes := bytes.NewReader(l.Data[32:]) identifierBytes := bytes.NewReader(l.Data[32:])
identifier, err := identifierFromBytes(identifierBytes) identifier, err := identifierFromBytes(identifierBytes)
if err != nil { if err != nil {
return backendTypes.ExecutingMessage{}, fmt.Errorf("failed to read contract identifier: %w", err) return types.ExecutingMessage{}, fmt.Errorf("failed to read contract identifier: %w", err)
} }
chainID, err := types.ChainIDFromBig(identifier.ChainId).ToUInt32() chainID, err := types.ChainIDFromBig(identifier.ChainId).ToUInt32()
if err != nil { if err != nil {
return backendTypes.ExecutingMessage{}, fmt.Errorf("failed to convert chain ID %v to uint32: %w", identifier.ChainId, err) return types.ExecutingMessage{}, fmt.Errorf("failed to convert chain ID %v to uint32: %w", identifier.ChainId, err)
} }
hash := payloadHashToLogHash(msgHash, identifier.Origin) hash := payloadHashToLogHash(msgHash, identifier.Origin)
return backendTypes.ExecutingMessage{ return types.ExecutingMessage{
Chain: chainID, Chain: chainID,
Hash: hash, Hash: hash,
BlockNum: identifier.BlockNumber.Uint64(), BlockNum: identifier.BlockNumber.Uint64(),
...@@ -126,9 +125,9 @@ func identifierFromBytes(identifierBytes io.Reader) (contractIdentifier, error) ...@@ -126,9 +125,9 @@ func identifierFromBytes(identifierBytes io.Reader) (contractIdentifier, error)
// to the log the referenced initiating message. // to the log the referenced initiating message.
// TODO: this function is duplicated between contracts and backend/source/log_processor.go // TODO: this function is duplicated between contracts and backend/source/log_processor.go
// to avoid a circular dependency. It should be reorganized to avoid this duplication. // to avoid a circular dependency. It should be reorganized to avoid this duplication.
func payloadHashToLogHash(payloadHash common.Hash, addr common.Address) backendTypes.TruncatedHash { func payloadHashToLogHash(payloadHash common.Hash, addr common.Address) common.Hash {
msg := make([]byte, 0, 2*common.HashLength) msg := make([]byte, 0, 2*common.HashLength)
msg = append(msg, addr.Bytes()...) msg = append(msg, addr.Bytes()...)
msg = append(msg, payloadHash.Bytes()...) msg = append(msg, payloadHash.Bytes()...)
return backendTypes.TruncateHash(crypto.Keccak256Hash(msg)) return crypto.Keccak256Hash(msg)
} }
...@@ -7,7 +7,7 @@ import ( ...@@ -7,7 +7,7 @@ import (
"github.com/ethereum-optimism/optimism/op-service/predeploys" "github.com/ethereum-optimism/optimism/op-service/predeploys"
"github.com/ethereum-optimism/optimism/op-service/sources/batching" "github.com/ethereum-optimism/optimism/op-service/sources/batching"
backendTypes "github.com/ethereum-optimism/optimism/op-supervisor/supervisor/backend/types" "github.com/ethereum-optimism/optimism/op-supervisor/supervisor/types"
"github.com/ethereum-optimism/optimism/packages/contracts-bedrock/snapshots" "github.com/ethereum-optimism/optimism/packages/contracts-bedrock/snapshots"
"github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common"
ethTypes "github.com/ethereum/go-ethereum/core/types" ethTypes "github.com/ethereum/go-ethereum/core/types"
...@@ -19,7 +19,7 @@ func TestDecodeExecutingMessageEvent(t *testing.T) { ...@@ -19,7 +19,7 @@ func TestDecodeExecutingMessageEvent(t *testing.T) {
inbox := NewCrossL2Inbox() inbox := NewCrossL2Inbox()
payload := bytes.Repeat([]byte{0xaa, 0xbb}, 50) payload := bytes.Repeat([]byte{0xaa, 0xbb}, 50)
payloadHash := crypto.Keccak256Hash(payload) payloadHash := crypto.Keccak256Hash(payload)
expected := backendTypes.ExecutingMessage{ expected := types.ExecutingMessage{
Chain: 42424, Chain: 42424,
BlockNum: 12345, BlockNum: 12345,
LogIdx: 98, LogIdx: 98,
......
...@@ -11,26 +11,25 @@ import ( ...@@ -11,26 +11,25 @@ import (
"github.com/ethereum-optimism/optimism/op-service/eth" "github.com/ethereum-optimism/optimism/op-service/eth"
"github.com/ethereum-optimism/optimism/op-supervisor/supervisor/backend/source/contracts" "github.com/ethereum-optimism/optimism/op-supervisor/supervisor/backend/source/contracts"
backendTypes "github.com/ethereum-optimism/optimism/op-supervisor/supervisor/backend/types" "github.com/ethereum-optimism/optimism/op-supervisor/supervisor/types"
supTypes "github.com/ethereum-optimism/optimism/op-supervisor/supervisor/types"
) )
type LogStorage interface { type LogStorage interface {
SealBlock(chain supTypes.ChainID, parentHash common.Hash, block eth.BlockID, timestamp uint64) error SealBlock(chain types.ChainID, parentHash common.Hash, block eth.BlockID, timestamp uint64) error
AddLog(chain supTypes.ChainID, logHash backendTypes.TruncatedHash, parentBlock eth.BlockID, logIdx uint32, execMsg *backendTypes.ExecutingMessage) error AddLog(chain types.ChainID, logHash common.Hash, parentBlock eth.BlockID, logIdx uint32, execMsg *types.ExecutingMessage) error
} }
type EventDecoder interface { type EventDecoder interface {
DecodeExecutingMessageLog(log *ethTypes.Log) (backendTypes.ExecutingMessage, error) DecodeExecutingMessageLog(log *ethTypes.Log) (types.ExecutingMessage, error)
} }
type logProcessor struct { type logProcessor struct {
chain supTypes.ChainID chain types.ChainID
logStore LogStorage logStore LogStorage
eventDecoder EventDecoder eventDecoder EventDecoder
} }
func newLogProcessor(chain supTypes.ChainID, logStore LogStorage) *logProcessor { func newLogProcessor(chain types.ChainID, logStore LogStorage) *logProcessor {
return &logProcessor{ return &logProcessor{
chain: chain, chain: chain,
logStore: logStore, logStore: logStore,
...@@ -45,7 +44,7 @@ func (p *logProcessor) ProcessLogs(_ context.Context, block eth.L1BlockRef, rcpt ...@@ -45,7 +44,7 @@ func (p *logProcessor) ProcessLogs(_ context.Context, block eth.L1BlockRef, rcpt
for _, l := range rcpt.Logs { for _, l := range rcpt.Logs {
// log hash represents the hash of *this* log as a potentially initiating message // log hash represents the hash of *this* log as a potentially initiating message
logHash := logToLogHash(l) logHash := logToLogHash(l)
var execMsg *backendTypes.ExecutingMessage var execMsg *types.ExecutingMessage
msg, err := p.eventDecoder.DecodeExecutingMessageLog(l) msg, err := p.eventDecoder.DecodeExecutingMessageLog(l)
if err != nil && !errors.Is(err, contracts.ErrEventNotFound) { if err != nil && !errors.Is(err, contracts.ErrEventNotFound) {
return fmt.Errorf("failed to decode executing message log: %w", err) return fmt.Errorf("failed to decode executing message log: %w", err)
...@@ -72,7 +71,7 @@ func (p *logProcessor) ProcessLogs(_ context.Context, block eth.L1BlockRef, rcpt ...@@ -72,7 +71,7 @@ func (p *logProcessor) ProcessLogs(_ context.Context, block eth.L1BlockRef, rcpt
// which is then hashed again. This is the hash that is stored in the log storage. // which is then hashed again. This is the hash that is stored in the log storage.
// The address is hashed into the payload hash to save space in the log storage, // The address is hashed into the payload hash to save space in the log storage,
// and because they represent paired data. // and because they represent paired data.
func logToLogHash(l *ethTypes.Log) backendTypes.TruncatedHash { func logToLogHash(l *ethTypes.Log) common.Hash {
payloadHash := crypto.Keccak256(logToMessagePayload(l)) payloadHash := crypto.Keccak256(logToMessagePayload(l))
return payloadHashToLogHash(common.Hash(payloadHash), l.Address) return payloadHashToLogHash(common.Hash(payloadHash), l.Address)
} }
...@@ -94,9 +93,9 @@ func logToMessagePayload(l *ethTypes.Log) []byte { ...@@ -94,9 +93,9 @@ func logToMessagePayload(l *ethTypes.Log) []byte {
// which is then hashed. This is the hash that is stored in the log storage. // which is then hashed. This is the hash that is stored in the log storage.
// The logHash can then be used to traverse from the executing message // The logHash can then be used to traverse from the executing message
// to the log the referenced initiating message. // to the log the referenced initiating message.
func payloadHashToLogHash(payloadHash common.Hash, addr common.Address) backendTypes.TruncatedHash { func payloadHashToLogHash(payloadHash common.Hash, addr common.Address) common.Hash {
msg := make([]byte, 0, 2*common.HashLength) msg := make([]byte, 0, 2*common.HashLength)
msg = append(msg, addr.Bytes()...) msg = append(msg, addr.Bytes()...)
msg = append(msg, payloadHash.Bytes()...) msg = append(msg, payloadHash.Bytes()...)
return backendTypes.TruncateHash(crypto.Keccak256Hash(msg)) return crypto.Keccak256Hash(msg)
} }
...@@ -7,14 +7,13 @@ import ( ...@@ -7,14 +7,13 @@ import (
"github.com/ethereum-optimism/optimism/op-service/eth" "github.com/ethereum-optimism/optimism/op-service/eth"
"github.com/ethereum-optimism/optimism/op-service/predeploys" "github.com/ethereum-optimism/optimism/op-service/predeploys"
backendTypes "github.com/ethereum-optimism/optimism/op-supervisor/supervisor/backend/types" "github.com/ethereum-optimism/optimism/op-supervisor/supervisor/types"
supTypes "github.com/ethereum-optimism/optimism/op-supervisor/supervisor/types"
"github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common"
ethTypes "github.com/ethereum/go-ethereum/core/types" ethTypes "github.com/ethereum/go-ethereum/core/types"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
) )
var logProcessorChainID = supTypes.ChainIDFromUInt64(4) var logProcessorChainID = types.ChainIDFromUInt64(4)
func TestLogProcessor(t *testing.T) { func TestLogProcessor(t *testing.T) {
ctx := context.Background() ctx := context.Background()
...@@ -108,16 +107,16 @@ func TestLogProcessor(t *testing.T) { ...@@ -108,16 +107,16 @@ func TestLogProcessor(t *testing.T) {
}, },
}, },
} }
execMsg := backendTypes.ExecutingMessage{ execMsg := types.ExecutingMessage{
Chain: 4, Chain: 4,
BlockNum: 6, BlockNum: 6,
LogIdx: 8, LogIdx: 8,
Timestamp: 10, Timestamp: 10,
Hash: backendTypes.TruncatedHash{0xaa}, Hash: common.Hash{0xaa},
} }
store := &stubLogStorage{} store := &stubLogStorage{}
processor := newLogProcessor(supTypes.ChainID{4}, store) processor := newLogProcessor(types.ChainID{4}, store)
processor.eventDecoder = EventDecoderFn(func(l *ethTypes.Log) (backendTypes.ExecutingMessage, error) { processor.eventDecoder = EventDecoderFn(func(l *ethTypes.Log) (types.ExecutingMessage, error) {
require.Equal(t, rcpts[0].Logs[0], l) require.Equal(t, rcpts[0].Logs[0], l)
return execMsg, nil return execMsg, nil
}) })
...@@ -182,7 +181,7 @@ func TestToLogHash(t *testing.T) { ...@@ -182,7 +181,7 @@ func TestToLogHash(t *testing.T) {
refHash := logToLogHash(mkLog()) refHash := logToLogHash(mkLog())
// The log hash is stored in the database so test that it matches the actual value. // The log hash is stored in the database so test that it matches the actual value.
// If this changes, compatibility with existing databases may be affected // If this changes, compatibility with existing databases may be affected
expectedRefHash := backendTypes.TruncateHash(common.HexToHash("0x4e1dc08fddeb273275f787762cdfe945cf47bb4e80a1fabbc7a825801e81b73f")) expectedRefHash := common.HexToHash("0x4e1dc08fddeb273275f787762cdfe945cf47bb4e80a1fabbc7a825801e81b73f")
require.Equal(t, expectedRefHash, refHash, "reference hash changed, check that database compatibility is not broken") require.Equal(t, expectedRefHash, refHash, "reference hash changed, check that database compatibility is not broken")
// Check that the hash is changed when any data it should include changes // Check that the hash is changed when any data it should include changes
...@@ -206,7 +205,7 @@ type stubLogStorage struct { ...@@ -206,7 +205,7 @@ type stubLogStorage struct {
seals []storedSeal seals []storedSeal
} }
func (s *stubLogStorage) SealBlock(chainID supTypes.ChainID, parentHash common.Hash, block eth.BlockID, timestamp uint64) error { func (s *stubLogStorage) SealBlock(chainID types.ChainID, parentHash common.Hash, block eth.BlockID, timestamp uint64) error {
if logProcessorChainID != chainID { if logProcessorChainID != chainID {
return fmt.Errorf("chain id mismatch, expected %v but got %v", logProcessorChainID, chainID) return fmt.Errorf("chain id mismatch, expected %v but got %v", logProcessorChainID, chainID)
} }
...@@ -218,7 +217,7 @@ func (s *stubLogStorage) SealBlock(chainID supTypes.ChainID, parentHash common.H ...@@ -218,7 +217,7 @@ func (s *stubLogStorage) SealBlock(chainID supTypes.ChainID, parentHash common.H
return nil return nil
} }
func (s *stubLogStorage) AddLog(chainID supTypes.ChainID, logHash backendTypes.TruncatedHash, parentBlock eth.BlockID, logIdx uint32, execMsg *backendTypes.ExecutingMessage) error { func (s *stubLogStorage) AddLog(chainID types.ChainID, logHash common.Hash, parentBlock eth.BlockID, logIdx uint32, execMsg *types.ExecutingMessage) error {
if logProcessorChainID != chainID { if logProcessorChainID != chainID {
return fmt.Errorf("chain id mismatch, expected %v but got %v", logProcessorChainID, chainID) return fmt.Errorf("chain id mismatch, expected %v but got %v", logProcessorChainID, chainID)
} }
...@@ -240,12 +239,12 @@ type storedSeal struct { ...@@ -240,12 +239,12 @@ type storedSeal struct {
type storedLog struct { type storedLog struct {
parent eth.BlockID parent eth.BlockID
logIdx uint32 logIdx uint32
logHash backendTypes.TruncatedHash logHash common.Hash
execMsg *backendTypes.ExecutingMessage execMsg *types.ExecutingMessage
} }
type EventDecoderFn func(*ethTypes.Log) (backendTypes.ExecutingMessage, error) type EventDecoderFn func(*ethTypes.Log) (types.ExecutingMessage, error)
func (f EventDecoderFn) DecodeExecutingMessageLog(log *ethTypes.Log) (backendTypes.ExecutingMessage, error) { func (f EventDecoderFn) DecodeExecutingMessageLog(log *ethTypes.Log) (types.ExecutingMessage, error) {
return f(log) return f(log)
} }
package types
import (
"encoding/hex"
"github.com/ethereum/go-ethereum/common"
)
type TruncatedHash [20]byte
func TruncateHash(hash common.Hash) TruncatedHash {
var truncated TruncatedHash
copy(truncated[:], hash[0:20])
return truncated
}
func (h TruncatedHash) String() string {
return hex.EncodeToString(h[:])
}
type ExecutingMessage struct {
Chain uint32
BlockNum uint64
LogIdx uint32
Timestamp uint64
Hash TruncatedHash
}
...@@ -13,6 +13,14 @@ import ( ...@@ -13,6 +13,14 @@ import (
"github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/common/hexutil"
) )
type ExecutingMessage struct {
Chain uint32 // same as ChainID for now, but will be indirect, i.e. translated to full ID, later
BlockNum uint64
LogIdx uint32
Timestamp uint64
Hash common.Hash
}
type Message struct { type Message struct {
Identifier Identifier `json:"identifier"` Identifier Identifier `json:"identifier"`
PayloadHash common.Hash `json:"payloadHash"` PayloadHash common.Hash `json:"payloadHash"`
......
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