Rework event handlers

This commit is contained in:
Kirill Fedoseev 2022-04-04 12:21:58 +04:00
parent 871d5f1296
commit 4014000f5b
8 changed files with 121 additions and 70 deletions

View File

@ -123,6 +123,20 @@ func (cfg *Config) init() error {
return nil
}
func (cfg *BridgeSideConfig) ContractAddresses(fromBlock, toBlock uint) []common.Address {
addresses := []common.Address{cfg.Address, cfg.ValidatorContractAddress}
for _, token := range cfg.ErcToNativeTokens {
if token.StartBlock > 0 && toBlock < token.StartBlock {
continue
}
if token.EndBlock > 0 && fromBlock > token.EndBlock {
continue
}
addresses = append(addresses, token.Address)
}
return addresses
}
func ReadConfig() (*Config, error) {
cfg := new(Config)
err := readYamlConfig(cfg)

55
contract/abi/abi.go Normal file
View File

@ -0,0 +1,55 @@
package abi
import (
_ "embed"
"strings"
"github.com/ethereum/go-ethereum/accounts/abi"
)
//go:embed amb.json
var ambJsonABI string
//go:embed erc_to_native.json
var etnJsonABI string
var AMB, ERC_TO_NATIVE abi.ABI
const (
UserRequestForSignature = "event UserRequestForSignature(bytes32 indexed messageId, bytes encodedData)"
LegacyUserRequestForSignature = "event UserRequestForSignature(bytes encodedData)"
UserRequestForAffirmation = "event UserRequestForAffirmation(bytes32 indexed messageId, bytes encodedData)"
LegacyUserRequestForAffirmation = "event UserRequestForAffirmation(bytes encodedData)"
UserRequestForInformation = "event UserRequestForInformation(bytes32 indexed messageId, bytes32 indexed requestSelector, address indexed sender, bytes data)"
SignedForUserRequest = "event SignedForUserRequest(address indexed signer, bytes32 messageHash)"
SignedForAffirmation = "event SignedForAffirmation(address indexed signer, bytes32 messageHash)"
SignedForInformation = "event SignedForInformation(address indexed signer, bytes32 indexed messageId)"
CollectedSignatures = "event CollectedSignatures(address authorityResponsibleForRelay, bytes32 messageHash, uint256 NumberOfCollectedSignatures)"
AffirmationCompleted = "event AffirmationCompleted(address indexed sender, address indexed executor, bytes32 indexed messageId, bool status)"
LegacyAffirmationCompleted = "event AffirmationCompleted(address sender, address executor, bytes32 messageId, bool status)"
RelayedMessage = "event RelayedMessage(address indexed sender, address indexed executor, bytes32 indexed messageId, bool status)"
LegacyRelayedMessage = "event RelayedMessage(address sender, address executor, bytes32 messageId, bool status)"
InformationRetrieved = "event InformationRetrieved(bytes32 indexed messageId, bool status, bool callbackStatus)"
ErcToNativeUserRequestForSignature = "event UserRequestForSignature(address recipient, uint256 value)"
ErcToNativeTransfer = "event Transfer(address indexed from, address indexed to, uint256 value)"
ErcToNativeRelayedMessage = "event RelayedMessage(address recipient, uint256 value, bytes32 transactionHash)"
ErcToNativeUserRequestForAffirmation = "event UserRequestForAffirmation(address recipient, uint256 value)"
ErcToNativeAffirmationCompleted = "event AffirmationCompleted(address recipient, uint256 value, bytes32 transactionHash)"
ErcToNativeSignedForAffirmation = "event SignedForAffirmation(address indexed signer, bytes32 transactionHash)"
ValidatorAdded = "event ValidatorAdded(address indexed validator)"
ValidatorRemoved = "event ValidatorRemoved(address indexed validator)"
)
func init() {
var err error
AMB, err = abi.JSON(strings.NewReader(ambJsonABI))
if err != nil {
panic(err)
}
ERC_TO_NATIVE, err = abi.JSON(strings.NewReader(etnJsonABI))
if err != nil {
panic(err)
}
}

View File

@ -1,28 +0,0 @@
package constants
import (
_ "embed"
"strings"
"github.com/ethereum/go-ethereum/accounts/abi"
)
//go:embed amb.json
var ambJsonABI string
//go:embed erc_to_native.json
var etnJsonABI string
var AMB, ERC_TO_NATIVE abi.ABI
func init() {
var err error
AMB, err = abi.JSON(strings.NewReader(ambJsonABI))
if err != nil {
panic(err)
}
ERC_TO_NATIVE, err = abi.JSON(strings.NewReader(etnJsonABI))
if err != nil {
panic(err)
}
}

View File

@ -3,7 +3,6 @@ package contract
import (
"amb-monitor/entity"
"amb-monitor/ethclient"
"bytes"
"context"
"fmt"
@ -22,9 +21,12 @@ func NewContract(client *ethclient.Client, addr common.Address, abi abi.ABI) *Co
return &Contract{addr, client, abi}
}
func (c *Contract) HasEvent(event string) bool {
_, ok := c.abi.Events[event]
return ok
func (c *Contract) AllEvents() map[string]bool {
events := make(map[string]bool, len(c.abi.Events))
for _, event := range c.abi.Events {
events[event.String()] = true
}
return events
}
func (c *Contract) ValidatorContractAddress(ctx context.Context) (common.Address, error) {
@ -59,7 +61,7 @@ func (c *Contract) ParseLog(log *entity.Log) (string, map[string]interface{}, er
var event *abi.Event
var indexed abi.Arguments
for _, e := range c.abi.Events {
if bytes.Equal(e.ID.Bytes(), log.Topic0.Bytes()) {
if e.ID == *log.Topic0 {
indexed = Indexed(e.Inputs)
if len(indexed) == len(topics) {
event = &e
@ -79,7 +81,7 @@ func (c *Contract) ParseLog(log *entity.Log) (string, map[string]interface{}, er
if err := abi.ParseTopicsIntoMap(m, indexed, topics); err != nil {
return "", nil, fmt.Errorf("can't unpack topics: %w", err)
}
return event.Name, m, nil
return event.String(), m, nil
}
func Indexed(args abi.Arguments) abi.Arguments {

View File

@ -2,7 +2,7 @@ package monitor
import (
"amb-monitor/config"
"amb-monitor/contract/constants"
"amb-monitor/contract/abi"
"amb-monitor/entity"
"amb-monitor/ethclient"
"amb-monitor/repository"
@ -77,7 +77,7 @@ func (p *BridgeEventHandler) HandleErcToNativeTransfer(ctx context.Context, log
return fmt.Errorf("failed to get transaction receipt by hash %s: %w", log.TransactionHash, err)
}
for _, l := range receipt.Logs {
if len(l.Topics) > 0 && l.Topics[0] == constants.ERC_TO_NATIVE.Events["UserRequestForAffirmation"].ID {
if len(l.Topics) > 0 && l.Topics[0] == abi.ERC_TO_NATIVE.Events["UserRequestForAffirmation"].ID {
return nil
}
}

View File

@ -3,7 +3,7 @@ package monitor
import (
"amb-monitor/config"
"amb-monitor/contract"
"amb-monitor/contract/constants"
"amb-monitor/contract/abi"
"amb-monitor/db"
"amb-monitor/entity"
"amb-monitor/ethclient"
@ -63,11 +63,11 @@ func newContractMonitor(ctx context.Context, logger logging.Logger, repo *reposi
if err != nil {
return nil, fmt.Errorf("failed to start eth client: %w", err)
}
abi := constants.AMB
contractAbi := abi.AMB
if bridgeCfg.IsErcToNative {
abi = constants.ERC_TO_NATIVE
contractAbi = abi.ERC_TO_NATIVE
}
bridgeContract := contract.NewContract(client, cfg.Address, abi)
bridgeContract := contract.NewContract(client, cfg.Address, contractAbi)
if cfg.ValidatorContractAddress == (common.Address{}) {
cfg.ValidatorContractAddress, err = bridgeContract.ValidatorContractAddress(ctx)
if err != nil {
@ -137,32 +137,45 @@ func NewMonitor(ctx context.Context, logger logging.Logger, dbConn *db.DB, repo
}
handlers := NewBridgeEventHandler(repo, cfg.ID, homeMonitor.client, foreignMonitor.client, cfg)
if cfg.IsErcToNative {
homeMonitor.eventHandlers["UserRequestForSignature"] = handlers.HandleErcToNativeUserRequestForSignature
homeMonitor.eventHandlers["SignedForAffirmation"] = handlers.HandleErcToNativeSignedForAffirmation
homeMonitor.eventHandlers["AffirmationCompleted"] = handlers.HandleErcToNativeAffirmationCompleted
foreignMonitor.eventHandlers["UserRequestForAffirmation"] = handlers.HandleErcToNativeUserRequestForAffirmation
foreignMonitor.eventHandlers["Transfer"] = handlers.HandleErcToNativeTransfer
foreignMonitor.eventHandlers["RelayedMessage"] = handlers.HandleErcToNativeRelayedMessage
homeMonitor.eventHandlers[abi.ErcToNativeUserRequestForSignature] = handlers.HandleErcToNativeUserRequestForSignature
homeMonitor.eventHandlers[abi.ErcToNativeSignedForAffirmation] = handlers.HandleErcToNativeSignedForAffirmation
homeMonitor.eventHandlers[abi.ErcToNativeAffirmationCompleted] = handlers.HandleErcToNativeAffirmationCompleted
foreignMonitor.eventHandlers[abi.ErcToNativeUserRequestForAffirmation] = handlers.HandleErcToNativeUserRequestForAffirmation
foreignMonitor.eventHandlers[abi.ErcToNativeTransfer] = handlers.HandleErcToNativeTransfer
foreignMonitor.eventHandlers[abi.ErcToNativeRelayedMessage] = handlers.HandleErcToNativeRelayedMessage
} else {
homeMonitor.eventHandlers["UserRequestForSignature"] = handlers.HandleUserRequestForSignature
homeMonitor.eventHandlers["UserRequestForSignature0"] = handlers.HandleLegacyUserRequestForSignature
homeMonitor.eventHandlers["SignedForAffirmation"] = handlers.HandleSignedForUserRequest
homeMonitor.eventHandlers["AffirmationCompleted"] = handlers.HandleAffirmationCompleted
homeMonitor.eventHandlers["AffirmationCompleted0"] = handlers.HandleAffirmationCompleted
homeMonitor.eventHandlers["UserRequestForInformation"] = handlers.HandleUserRequestForInformation
homeMonitor.eventHandlers["SignedForInformation"] = handlers.HandleSignedForInformation
homeMonitor.eventHandlers["InformationRetrieved"] = handlers.HandleInformationRetrieved
foreignMonitor.eventHandlers["UserRequestForAffirmation"] = handlers.HandleUserRequestForAffirmation
foreignMonitor.eventHandlers["UserRequestForAffirmation0"] = handlers.HandleLegacyUserRequestForAffirmation
foreignMonitor.eventHandlers["RelayedMessage"] = handlers.HandleRelayedMessage
foreignMonitor.eventHandlers["RelayedMessage0"] = handlers.HandleRelayedMessage
homeMonitor.eventHandlers[abi.UserRequestForSignature] = handlers.HandleUserRequestForSignature
homeMonitor.eventHandlers[abi.LegacyUserRequestForSignature] = handlers.HandleLegacyUserRequestForSignature
homeMonitor.eventHandlers[abi.SignedForAffirmation] = handlers.HandleSignedForUserRequest
homeMonitor.eventHandlers[abi.AffirmationCompleted] = handlers.HandleAffirmationCompleted
homeMonitor.eventHandlers[abi.LegacyAffirmationCompleted] = handlers.HandleAffirmationCompleted
homeMonitor.eventHandlers[abi.UserRequestForInformation] = handlers.HandleUserRequestForInformation
homeMonitor.eventHandlers[abi.SignedForInformation] = handlers.HandleSignedForInformation
homeMonitor.eventHandlers[abi.InformationRetrieved] = handlers.HandleInformationRetrieved
foreignMonitor.eventHandlers[abi.UserRequestForAffirmation] = handlers.HandleUserRequestForAffirmation
foreignMonitor.eventHandlers[abi.LegacyUserRequestForAffirmation] = handlers.HandleLegacyUserRequestForAffirmation
foreignMonitor.eventHandlers[abi.RelayedMessage] = handlers.HandleRelayedMessage
foreignMonitor.eventHandlers[abi.LegacyRelayedMessage] = handlers.HandleRelayedMessage
}
homeMonitor.eventHandlers[abi.SignedForUserRequest] = handlers.HandleSignedForUserRequest
homeMonitor.eventHandlers[abi.CollectedSignatures] = handlers.HandleCollectedSignatures
homeMonitor.eventHandlers[abi.ValidatorAdded] = handlers.HandleValidatorAdded
homeMonitor.eventHandlers[abi.ValidatorRemoved] = handlers.HandleValidatorRemoved
foreignMonitor.eventHandlers[abi.ValidatorAdded] = handlers.HandleValidatorAdded
foreignMonitor.eventHandlers[abi.ValidatorRemoved] = handlers.HandleValidatorRemoved
homeEvents := homeMonitor.contract.AllEvents()
foreignEvents := homeMonitor.contract.AllEvents()
for e := range homeMonitor.eventHandlers {
if !homeEvents[e] {
return nil, fmt.Errorf("home side contract does not have %s event in its ABI", e)
}
}
for e := range foreignMonitor.eventHandlers {
if !foreignEvents[e] {
return nil, fmt.Errorf("foreign side contract does not have %s event in its ABI", e)
}
}
homeMonitor.eventHandlers["SignedForUserRequest"] = handlers.HandleSignedForUserRequest
homeMonitor.eventHandlers["CollectedSignatures"] = handlers.HandleCollectedSignatures
homeMonitor.eventHandlers["ValidatorAdded"] = handlers.HandleValidatorAdded
homeMonitor.eventHandlers["ValidatorRemoved"] = handlers.HandleValidatorRemoved
foreignMonitor.eventHandlers["ValidatorAdded"] = handlers.HandleValidatorAdded
foreignMonitor.eventHandlers["ValidatorRemoved"] = handlers.HandleValidatorRemoved
return &Monitor{
cfg: cfg,
logger: logger,
@ -211,12 +224,7 @@ func (m *ContractMonitor) LoadUnprocessedLogs(ctx context.Context, fromBlock, to
var logs []*entity.Log
for {
var err error
addresses := []common.Address{m.cfg.Address, m.cfg.ValidatorContractAddress}
if m.bridgeCfg.IsErcToNative {
for _, token := range m.bridgeCfg.Foreign.ErcToNativeTokens {
addresses = append(addresses, token.Address)
}
}
addresses := m.cfg.ContractAddresses(fromBlock, toBlock)
logs, err = m.repo.Logs.FindByBlockRange(ctx, m.client.ChainID, addresses, fromBlock, toBlock)
if err != nil {
m.logger.WithError(err).Error("can't find unprocessed logs in block range")