Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Index Messaging Contracts with Explorer #255

Closed
wants to merge 12 commits into from
16 changes: 12 additions & 4 deletions services/explorer/consumer/backfill/chain.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,14 @@ type ChainBackfiller struct {
bridgeConfigAddress common.Address
// fetcher is the fetcher to use to fetch logs.
fetcher consumer.Fetcher
// messageParser is the parser to use to parse message events.
messageParser *consumer.MessageParser
// messageAddress is the address of the message contract.
messageAddress common.Address
}

// NewChainBackfiller creates a new backfiller for a chain.
func NewChainBackfiller(chainID uint32, consumerDB db.ConsumerDB, fetchBlockIncrement uint64, bridgeParser *consumer.BridgeParser, bridgeAddress common.Address, swapParsers map[common.Address]*consumer.SwapParser, fetcher consumer.Fetcher, bridgeConfigAddress common.Address) *ChainBackfiller {
func NewChainBackfiller(chainID uint32, consumerDB db.ConsumerDB, fetchBlockIncrement uint64, bridgeParser *consumer.BridgeParser, bridgeAddress common.Address, swapParsers map[common.Address]*consumer.SwapParser, fetcher consumer.Fetcher, bridgeConfigAddress common.Address, messageParser *consumer.MessageParser, messageAddress common.Address) *ChainBackfiller {
failedLogs := atomic.Uint32{}
failedLogs.Store(0)
return &ChainBackfiller{
Expand All @@ -46,6 +50,8 @@ func NewChainBackfiller(chainID uint32, consumerDB db.ConsumerDB, fetchBlockIncr
swapParsers: swapParsers,
fetcher: fetcher,
bridgeConfigAddress: bridgeConfigAddress,
messageParser: messageParser,
messageAddress: messageAddress,
}
}

Expand Down Expand Up @@ -109,16 +115,18 @@ func (c *ChainBackfiller) processLogs(ctx context.Context, logs []ethTypes.Log)
log := log
g.Go(func() error {
var eventParser consumer.Parser
if log.Address == c.bridgeAddress {
switch log.Address {
case c.bridgeAddress:
eventParser = c.bridgeParser
} else {
case c.messageAddress:
eventParser = c.messageParser
default:
if c.swapParsers[log.Address] == nil {
logger.Warnf("no parser found for contract %s", log.Address.Hex())
return nil
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should this err?

}
eventParser = c.swapParsers[log.Address]
}

err := eventParser.ParseAndStore(groupCtx, log, c.chainID)
if err != nil {
return fmt.Errorf("could not parse and store log: %w", err)
Expand Down
130 changes: 128 additions & 2 deletions services/explorer/consumer/backfill/chain_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import (
"github.com/synapsecns/sanguine/services/explorer/db/sql"
"github.com/synapsecns/sanguine/services/explorer/testutil/testcontracts"
bridgeTypes "github.com/synapsecns/sanguine/services/explorer/types/bridge"
messageTypes "github.com/synapsecns/sanguine/services/explorer/types/message"
swapTypes "github.com/synapsecns/sanguine/services/explorer/types/swap"
"math/big"
)
Expand All @@ -24,12 +25,15 @@ func arrayToTokenIndexMap(input []*big.Int) map[uint8]string {
}
return output
}

// nolint:maintidx
func (b *BackfillSuite) TestBackfill() {
testChainID := b.testBackend.GetBigChainID()
bridgeContract, bridgeRef := b.testDeployManager.GetTestSynapseBridge(b.GetTestContext(), b.testBackend)
swapContractA, swapRefA := b.testDeployManager.GetTestSwapFlashLoan(b.GetTestContext(), b.testBackend)
testDeployManagerB := testcontracts.NewDeployManager(b.T())
swapContractB, swapRefB := testDeployManagerB.GetTestSwapFlashLoan(b.GetTestContext(), b.testBackend)
messageContract, messageRef := b.testDeployManager.GetTestMessageBusUpgradeable(b.GetTestContext(), b.testBackend)

transactOpts := b.testBackend.GetTxContext(b.GetTestContext(), nil)

Expand Down Expand Up @@ -117,7 +121,25 @@ func (b *BackfillSuite) TestBackfill() {
flashLoanLog, err := b.storeTestLog(swapTx, uint32(testChainID.Uint64()), 9)
Nil(b.T(), err)

// Store every message event.
messageTx, err := messageRef.TestExecuted(transactOpts.TransactOpts, [32]byte{byte(gofakeit.Uint64())}, uint8(gofakeit.Number(0, 2)), common.BigToAddress(big.NewInt(gofakeit.Int64())), gofakeit.Uint64(), gofakeit.Uint64())
Nil(b.T(), err)
executedLog, err := b.storeTestLog(messageTx, uint32(testChainID.Uint64()), 5)
Nil(b.T(), err)

messageTx, err = messageRef.TestMessageSent(transactOpts.TransactOpts, common.BigToAddress(big.NewInt(gofakeit.Int64())), big.NewInt(int64(gofakeit.Uint32())), [32]byte{byte(gofakeit.Uint64())}, big.NewInt(int64(gofakeit.Uint32())), []byte(gofakeit.Paragraph(2, 5, 30, " ")), gofakeit.Uint64(), []byte{byte(gofakeit.Uint64())}, big.NewInt(int64(gofakeit.Uint32())), [32]byte{byte(gofakeit.Uint64())})
Nil(b.T(), err)
messageSentLog, err := b.storeTestLog(messageTx, uint32(testChainID.Uint64()), 6)
Nil(b.T(), err)

messageTx, err = messageRef.TestCallReverted(transactOpts.TransactOpts, gofakeit.Paragraph(2, 4, 20, " "))
Nil(b.T(), err)
callRevertedLog, err := b.storeTestLog(messageTx, uint32(testChainID.Uint64()), 7)
Nil(b.T(), err)

// set up a ChainBackfiller

// bridge
bcf, err := consumer.NewBridgeConfigFetcher(b.bridgeConfigContract.Address(), b.testBackend)
Nil(b.T(), err)
bp, err := consumer.NewBridgeParser(b.db, bridgeContract.Address(), *bcf, b.consumerFetcher)
Expand All @@ -134,14 +156,19 @@ func (b *BackfillSuite) TestBackfill() {
Nil(b.T(), err)
spB, err := consumer.NewSwapParser(b.db, swapContractB.Address(), *srB, b.consumerFetcher)
Nil(b.T(), err)

// message
mbp, err := consumer.NewMessageParser(b.db, messageContract.Address(), b.consumerFetcher)
Nil(b.T(), err)

spMap := map[common.Address]*consumer.SwapParser{}
spMap[swapContractA.Address()] = spA
spMap[swapContractB.Address()] = spB
f := consumer.NewFetcher(b.gqlClient)
chainBackfiller := backfill.NewChainBackfiller(uint32(testChainID.Uint64()), b.db, 3, bp, bridgeContract.Address(), spMap, *f, b.bridgeConfigContract.Address())
chainBackfiller := backfill.NewChainBackfiller(uint32(testChainID.Uint64()), b.db, 3, bp, bridgeContract.Address(), spMap, *f, b.bridgeConfigContract.Address(), mbp, messageContract.Address())

// backfill the blocks
err = chainBackfiller.Backfill(b.GetTestContext(), 0, 12)
err = chainBackfiller.Backfill(b.GetTestContext(), 0, 14)
Nil(b.T(), err)
var count int64
bridgeEvents := b.db.UNSAFE_DB().WithContext(b.GetTestContext()).Find(&sql.BridgeEvent{}).Count(&count)
Expand All @@ -150,6 +177,9 @@ func (b *BackfillSuite) TestBackfill() {
swapEvents := b.db.UNSAFE_DB().WithContext(b.GetTestContext()).Find(&sql.SwapEvent{}).Count(&count)
Nil(b.T(), swapEvents.Error)
Equal(b.T(), int64(10), count)
messageEvents := b.db.UNSAFE_DB().WithContext(b.GetTestContext()).Find(&sql.MessageEvent{}).Count(&count)
Nil(b.T(), messageEvents.Error)
Equal(b.T(), int64(3), count)

// Test bridge parity
err = b.depositParity(depositLog, bp, uint32(testChainID.Uint64()))
nautsimon marked this conversation as resolved.
Show resolved Hide resolved
Expand Down Expand Up @@ -194,6 +224,14 @@ func (b *BackfillSuite) TestBackfill() {
Nil(b.T(), err)
err = b.flashLoanParity(flashLoanLog, spA, uint32(testChainID.Uint64()))
Nil(b.T(), err)

// Test message parity
err = b.executedParity(executedLog, mbp, uint32(testChainID.Uint64()))
Nil(b.T(), err)
err = b.messageSentParity(messageSentLog, mbp, uint32(testChainID.Uint64()))
Nil(b.T(), err)
err = b.callRevertedParity(callRevertedLog, mbp, uint32(testChainID.Uint64()))
Nil(b.T(), err)
}

func (b *BackfillSuite) storeTestLog(tx *types.Transaction, chainID uint32, blockNumber uint64) (*types.Log, error) {
Expand Down Expand Up @@ -890,3 +928,91 @@ func (b *BackfillSuite) flashLoanParity(log *types.Log, parser *consumer.SwapPar
Equal(b.T(), feeArray, storedLog.AmountFee)
return nil
}

//nolint:dupl
func (b *BackfillSuite) executedParity(log *types.Log, parser *consumer.MessageParser, chainID uint32) error {
// parse the log
parsedLog, err := parser.Filterer.ParseExecuted(*log)
if err != nil {
return fmt.Errorf("error parsing log: %w", err)
}
var storedLog sql.MessageEvent
var count int64
events := b.db.UNSAFE_DB().WithContext(b.GetTestContext()).Model(&sql.MessageEvent{}).
Where(&sql.MessageEvent{
ContractAddress: log.Address.String(),
ChainID: chainID,
EventType: messageTypes.ExecutedEvent.Int(),
BlockNumber: log.BlockNumber,
TxHash: log.TxHash.String(),

MessageID: gosql.NullString{String: common.Bytes2Hex(parsedLog.MessageId[:]), Valid: true},
SourceChainID: big.NewInt(int64(parsedLog.SrcChainId)),
}).
Find(&storedLog).Count(&count)
if events.Error != nil {
return fmt.Errorf("error querying for event: %w", events.Error)
}
Equal(b.T(), int64(1), count)
Equal(b.T(), big.NewInt(int64(parsedLog.SrcNonce)), storedLog.Nonce)
Equal(b.T(), parsedLog.DstAddress.String(), storedLog.DestinationAddress.String)
return nil
}

//nolint:dupl
func (b *BackfillSuite) messageSentParity(log *types.Log, parser *consumer.MessageParser, chainID uint32) error {
nautsimon marked this conversation as resolved.
Show resolved Hide resolved
// parse the log
parsedLog, err := parser.Filterer.ParseMessageSent(*log)
if err != nil {
return fmt.Errorf("error parsing log: %w", err)
}
var storedLog sql.MessageEvent
var count int64
events := b.db.UNSAFE_DB().WithContext(b.GetTestContext()).Model(&sql.MessageEvent{}).
Where(&sql.MessageEvent{
ContractAddress: log.Address.String(),
ChainID: chainID,
EventType: messageTypes.MessageSentEvent.Int(),
BlockNumber: log.BlockNumber,
TxHash: log.TxHash.String(),

MessageID: gosql.NullString{String: common.Bytes2Hex(parsedLog.MessageId[:]), Valid: true},
SourceChainID: parsedLog.SrcChainID,
}).
Find(&storedLog).Count(&count)
if events.Error != nil {
return fmt.Errorf("error querying for event: %w", events.Error)
}
Equal(b.T(), int64(1), count)
Equal(b.T(), common.Bytes2Hex(parsedLog.Message), storedLog.Message.String)
Equal(b.T(), parsedLog.Fee, storedLog.Fee)
Equal(b.T(), common.Bytes2Hex(parsedLog.Receiver[:]), storedLog.Receiver.String)

return nil
}

//nolint:dupl
func (b *BackfillSuite) callRevertedParity(log *types.Log, parser *consumer.MessageParser, chainID uint32) error {
// parse the log
parsedLog, err := parser.Filterer.ParseCallReverted(*log)
if err != nil {
return fmt.Errorf("error parsing log: %w", err)
}
var storedLog sql.MessageEvent
var count int64
events := b.db.UNSAFE_DB().WithContext(b.GetTestContext()).Model(&sql.MessageEvent{}).
Where(&sql.MessageEvent{
ContractAddress: log.Address.String(),
ChainID: chainID,
EventType: messageTypes.CallRevertedEvent.Int(),
BlockNumber: log.BlockNumber,
TxHash: log.TxHash.String(),
}).
Find(&storedLog).Count(&count)
if events.Error != nil {
return fmt.Errorf("error querying for event: %w", events.Error)
}
Equal(b.T(), int64(1), count)
Equal(b.T(), parsedLog.Reason, storedLog.RevertedReason.String)
return nil
}
Loading
Loading