ABI tests
This commit is contained in:
parent
c2548e248c
commit
1e5fb85fae
|
@ -1,60 +1,91 @@
|
|||
package abi
|
||||
|
||||
//nolint:golint
|
||||
import (
|
||||
_ "embed"
|
||||
"errors"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/ethereum/go-ethereum/accounts/abi"
|
||||
gethabi "github.com/ethereum/go-ethereum/accounts/abi"
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
|
||||
"github.com/poanetwork/tokenbridge-monitor/entity"
|
||||
)
|
||||
|
||||
//go:embed amb.json
|
||||
var arbitraryMessageJSONABI string
|
||||
type ABI struct {
|
||||
gethabi.ABI
|
||||
}
|
||||
|
||||
//go:embed erc_to_native.json
|
||||
var ercToNativeJSONABI string
|
||||
type Event struct {
|
||||
gethabi.Event
|
||||
}
|
||||
|
||||
var (
|
||||
ArbitraryMessageABI = MustReadABI(arbitraryMessageJSONABI)
|
||||
ErcToNativeABI = MustReadABI(ercToNativeJSONABI)
|
||||
)
|
||||
var ErrInvalidEvent = errors.New("invalid event")
|
||||
|
||||
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)"
|
||||
)
|
||||
|
||||
var (
|
||||
ErcToNativeTransferEventSignature = ErcToNativeABI.Events["Transfer"].ID
|
||||
ErcToNativeUserRequestForAffirmationEventSignature = ErcToNativeABI.Events["UserRequestForAffirmation"].ID
|
||||
)
|
||||
|
||||
func MustReadABI(rawJSON string) abi.ABI {
|
||||
res, err := abi.JSON(strings.NewReader(rawJSON))
|
||||
func MustReadABI(rawJSON string) ABI {
|
||||
res, err := gethabi.JSON(strings.NewReader(rawJSON))
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return res
|
||||
return ABI{res}
|
||||
}
|
||||
|
||||
func (abi *ABI) AllEvents() map[string]bool {
|
||||
events := make(map[string]bool, len(abi.Events))
|
||||
for _, event := range abi.Events {
|
||||
events[event.String()] = true
|
||||
}
|
||||
return events
|
||||
}
|
||||
|
||||
func (abi *ABI) FindMatchingEventABI(topics []common.Hash) *Event {
|
||||
for _, e := range abi.Events {
|
||||
if e.ID == topics[0] {
|
||||
indexed := Indexed(e.Inputs)
|
||||
if len(indexed) == len(topics)-1 {
|
||||
return &Event{e}
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (abi *ABI) ParseLog(log *entity.Log) (string, map[string]interface{}, error) {
|
||||
topics := log.Topics()
|
||||
if len(topics) == 0 {
|
||||
return "", nil, fmt.Errorf("cannot process event without topics: %w", ErrInvalidEvent)
|
||||
}
|
||||
event := abi.FindMatchingEventABI(topics)
|
||||
if event == nil {
|
||||
return "", nil, nil
|
||||
}
|
||||
|
||||
res, err := event.DecodeLogData(topics, log.Data)
|
||||
if err != nil {
|
||||
return "", nil, fmt.Errorf("can't decode event log data: %w", err)
|
||||
}
|
||||
return event.String(), res, nil
|
||||
}
|
||||
|
||||
func (event *Event) DecodeLogData(topics []common.Hash, data []byte) (map[string]interface{}, error) {
|
||||
indexed := Indexed(event.Inputs)
|
||||
values := make(map[string]interface{})
|
||||
if len(indexed) < len(event.Inputs) {
|
||||
if err := event.Inputs.UnpackIntoMap(values, data); err != nil {
|
||||
return nil, fmt.Errorf("can't unpack data: %w", err)
|
||||
}
|
||||
}
|
||||
if err := gethabi.ParseTopicsIntoMap(values, indexed, topics[1:]); err != nil {
|
||||
return nil, fmt.Errorf("can't unpack topics: %w", err)
|
||||
}
|
||||
return values, nil
|
||||
}
|
||||
|
||||
func Indexed(args gethabi.Arguments) gethabi.Arguments {
|
||||
var indexed gethabi.Arguments
|
||||
for _, arg := range args {
|
||||
if arg.Indexed {
|
||||
indexed = append(indexed, arg)
|
||||
}
|
||||
}
|
||||
return indexed
|
||||
}
|
||||
|
|
|
@ -0,0 +1,133 @@
|
|||
package abi_test
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
_ "embed"
|
||||
"math/big"
|
||||
"testing"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/crypto"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/poanetwork/tokenbridge-monitor/contract/abi"
|
||||
"github.com/poanetwork/tokenbridge-monitor/entity"
|
||||
)
|
||||
|
||||
//go:embed test_abi.json
|
||||
var testJSONABI string
|
||||
|
||||
var (
|
||||
transferTopic = crypto.Keccak256Hash([]byte("Transfer(address,address,uint256)"))
|
||||
testEventTopic = crypto.Keccak256Hash([]byte("TestEvent(uint256,uint256)"))
|
||||
testIndexedEventTopic = crypto.Keccak256Hash([]byte("TestIndexedEvent(uint256,uint256)"))
|
||||
aliceAddr = common.HexToAddress("0x01")
|
||||
alice = aliceAddr.Hash()
|
||||
bobAddr = common.HexToAddress("0x02")
|
||||
bob = bobAddr.Hash()
|
||||
)
|
||||
|
||||
func TestABI_AllEvents(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
testABI := abi.MustReadABI(testJSONABI)
|
||||
|
||||
allEvents := testABI.AllEvents()
|
||||
require.Equal(t, map[string]bool{
|
||||
"event Transfer(address indexed sender, address indexed receiver, uint256 value)": true,
|
||||
"event TestEvent(uint256 a, uint256 b)": true,
|
||||
"event TestIndexedEvent(uint256 indexed a, uint256 indexed b)": true,
|
||||
}, allEvents)
|
||||
}
|
||||
|
||||
func TestABI_FindMatchingEventABI(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
testABI := abi.MustReadABI(testJSONABI)
|
||||
|
||||
event := testABI.FindMatchingEventABI([]common.Hash{transferTopic, alice, bob})
|
||||
require.NotNil(t, event)
|
||||
require.Equal(t, "Transfer", event.Name)
|
||||
event = testABI.FindMatchingEventABI([]common.Hash{transferTopic, alice})
|
||||
require.Nil(t, event)
|
||||
event = testABI.FindMatchingEventABI([]common.Hash{transferTopic, alice, bob, alice})
|
||||
require.Nil(t, event)
|
||||
event = testABI.FindMatchingEventABI([]common.Hash{testEventTopic})
|
||||
require.NotNil(t, event)
|
||||
require.Equal(t, "TestEvent", event.Name)
|
||||
}
|
||||
|
||||
func TestABI_ParseLog(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
testABI := abi.MustReadABI(testJSONABI)
|
||||
|
||||
value := big.NewInt(100)
|
||||
valueHash := common.BigToHash(value)
|
||||
logData := valueHash.Bytes()
|
||||
|
||||
t.Run("should parse valid transfer event", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
log := &entity.Log{Topic0: &transferTopic, Topic1: &alice, Topic2: &bob, Data: logData}
|
||||
event, data, err := testABI.ParseLog(log)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, "event Transfer(address indexed sender, address indexed receiver, uint256 value)", event)
|
||||
require.Equal(t, map[string]interface{}{
|
||||
"sender": aliceAddr,
|
||||
"receiver": bobAddr,
|
||||
"value": value,
|
||||
}, data)
|
||||
})
|
||||
|
||||
t.Run("should not parse anonymous event", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
log := &entity.Log{Data: logData}
|
||||
event, data, err := testABI.ParseLog(log)
|
||||
require.ErrorIs(t, err, abi.ErrInvalidEvent)
|
||||
require.Empty(t, event)
|
||||
require.Empty(t, data)
|
||||
})
|
||||
|
||||
t.Run("should skip unknown event", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
log := &entity.Log{Topic0: &transferTopic, Data: logData}
|
||||
event, data, err := testABI.ParseLog(log)
|
||||
require.NoError(t, err)
|
||||
require.Empty(t, event)
|
||||
require.Empty(t, data)
|
||||
})
|
||||
|
||||
t.Run("should decode event without indexed fields", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
log := &entity.Log{Topic0: &testEventTopic, Data: bytes.Repeat(logData, 2)}
|
||||
event, data, err := testABI.ParseLog(log)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, "event TestEvent(uint256 a, uint256 b)", event)
|
||||
require.Equal(t, map[string]interface{}{
|
||||
"a": value,
|
||||
"b": value,
|
||||
}, data)
|
||||
})
|
||||
|
||||
t.Run("should decode event with only indexed fields", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
log := &entity.Log{Topic0: &testIndexedEventTopic, Topic1: &valueHash, Topic2: &valueHash}
|
||||
event, data, err := testABI.ParseLog(log)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, "event TestIndexedEvent(uint256 indexed a, uint256 indexed b)", event)
|
||||
require.Equal(t, map[string]interface{}{
|
||||
"a": value,
|
||||
"b": value,
|
||||
}, data)
|
||||
})
|
||||
|
||||
t.Run("should fail to decode event with incompatible ABI", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
log := &entity.Log{Topic0: &testEventTopic, Data: logData}
|
||||
event, data, err := testABI.ParseLog(log)
|
||||
require.Error(t, err)
|
||||
require.Contains(t, err.Error(), "length insufficient")
|
||||
require.Empty(t, event)
|
||||
require.Empty(t, data)
|
||||
})
|
||||
}
|
|
@ -0,0 +1,77 @@
|
|||
[
|
||||
{
|
||||
"constant": true,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "testMethod",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"anonymous": false,
|
||||
"inputs": [
|
||||
{
|
||||
"indexed": true,
|
||||
"name": "sender",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"indexed": true,
|
||||
"name": "receiver",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"indexed": false,
|
||||
"name": "value",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "Transfer",
|
||||
"type": "event"
|
||||
},
|
||||
{
|
||||
"anonymous": false,
|
||||
"inputs": [
|
||||
{
|
||||
"indexed": false,
|
||||
"name": "a",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"indexed": false,
|
||||
"name": "b",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "TestEvent",
|
||||
"type": "event"
|
||||
},
|
||||
{
|
||||
"anonymous": false,
|
||||
"inputs": [
|
||||
{
|
||||
"indexed": true,
|
||||
"name": "a",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"indexed": true,
|
||||
"name": "b",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "TestIndexedEvent",
|
||||
"type": "event"
|
||||
}
|
||||
]
|
|
@ -8,6 +8,7 @@ import (
|
|||
|
||||
"github.com/poanetwork/tokenbridge-monitor/config"
|
||||
"github.com/poanetwork/tokenbridge-monitor/contract/abi"
|
||||
"github.com/poanetwork/tokenbridge-monitor/contract/bridgeabi"
|
||||
"github.com/poanetwork/tokenbridge-monitor/ethclient"
|
||||
)
|
||||
|
||||
|
@ -16,16 +17,14 @@ type BridgeContract struct {
|
|||
}
|
||||
|
||||
func NewBridgeContract(client ethclient.Client, addr common.Address, mode config.BridgeMode) *BridgeContract {
|
||||
var contract *Contract
|
||||
switch mode {
|
||||
case config.BridgeModeArbitraryMessage:
|
||||
contract = NewContract(client, addr, abi.ArbitraryMessageABI)
|
||||
case config.BridgeModeErcToNative:
|
||||
contract = NewContract(client, addr, abi.ErcToNativeABI)
|
||||
default:
|
||||
contract = NewContract(client, addr, abi.ArbitraryMessageABI)
|
||||
return &BridgeContract{NewContract(client, addr, getBridgeABI(mode))}
|
||||
}
|
||||
return &BridgeContract{contract}
|
||||
|
||||
func getBridgeABI(mode config.BridgeMode) abi.ABI {
|
||||
if mode == config.BridgeModeErcToNative {
|
||||
return bridgeabi.ErcToNativeABI
|
||||
}
|
||||
return bridgeabi.ArbitraryMessageABI
|
||||
}
|
||||
|
||||
func (c *BridgeContract) ValidatorContractAddress(ctx context.Context) (common.Address, error) {
|
||||
|
|
|
@ -0,0 +1,49 @@
|
|||
package bridgeabi
|
||||
|
||||
//nolint:golint
|
||||
import (
|
||||
_ "embed"
|
||||
|
||||
"github.com/poanetwork/tokenbridge-monitor/contract/abi"
|
||||
)
|
||||
|
||||
//go:embed amb.json
|
||||
var arbitraryMessageJSONABI string
|
||||
|
||||
//go:embed erc_to_native.json
|
||||
var ercToNativeJSONABI string
|
||||
|
||||
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)"
|
||||
)
|
||||
|
||||
var (
|
||||
ArbitraryMessageABI = abi.MustReadABI(arbitraryMessageJSONABI)
|
||||
ErcToNativeABI = abi.MustReadABI(ercToNativeJSONABI)
|
||||
|
||||
ErcToNativeTransferEventSignature = ErcToNativeABI.Events["Transfer"].ID
|
||||
ErcToNativeUserRequestForAffirmationEventSignature = ErcToNativeABI.Events["UserRequestForAffirmation"].ID
|
||||
)
|
|
@ -0,0 +1,16 @@
|
|||
package bridgeabi_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/poanetwork/tokenbridge-monitor/contract/bridgeabi"
|
||||
)
|
||||
|
||||
func TestEventSignatures(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
require.NotZero(t, bridgeabi.ErcToNativeTransferEventSignature)
|
||||
require.NotZero(t, bridgeabi.ErcToNativeUserRequestForAffirmationEventSignature)
|
||||
}
|
|
@ -5,38 +5,29 @@ import (
|
|||
"fmt"
|
||||
|
||||
"github.com/ethereum/go-ethereum"
|
||||
"github.com/ethereum/go-ethereum/accounts/abi"
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
|
||||
"github.com/poanetwork/tokenbridge-monitor/entity"
|
||||
"github.com/poanetwork/tokenbridge-monitor/contract/abi"
|
||||
"github.com/poanetwork/tokenbridge-monitor/ethclient"
|
||||
)
|
||||
|
||||
type Contract struct {
|
||||
address common.Address
|
||||
client ethclient.Client
|
||||
abi abi.ABI
|
||||
Address common.Address
|
||||
ABI abi.ABI
|
||||
}
|
||||
|
||||
func NewContract(client ethclient.Client, addr common.Address, abi abi.ABI) *Contract {
|
||||
return &Contract{addr, client, abi}
|
||||
}
|
||||
|
||||
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
|
||||
return &Contract{client, addr, abi}
|
||||
}
|
||||
|
||||
func (c *Contract) Call(ctx context.Context, method string, args ...interface{}) ([]byte, error) {
|
||||
data, err := c.abi.Pack(method, args...)
|
||||
data, err := c.ABI.Pack(method, args...)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("cannot encode abi calldata: %w", err)
|
||||
}
|
||||
res, err := c.client.CallContract(ctx, ethereum.CallMsg{
|
||||
To: &c.address,
|
||||
To: &c.Address,
|
||||
Data: data,
|
||||
})
|
||||
if err != nil {
|
||||
|
@ -44,7 +35,3 @@ func (c *Contract) Call(ctx context.Context, method string, args ...interface{})
|
|||
}
|
||||
return res, nil
|
||||
}
|
||||
|
||||
func (c *Contract) ParseLog(log *entity.Log) (string, map[string]interface{}, error) {
|
||||
return ParseLog(c.abi, log)
|
||||
}
|
||||
|
|
|
@ -1,66 +0,0 @@
|
|||
package contract
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"github.com/ethereum/go-ethereum/accounts/abi"
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
|
||||
"github.com/poanetwork/tokenbridge-monitor/entity"
|
||||
)
|
||||
|
||||
var ErrInvalidEvent = errors.New("invalid event")
|
||||
|
||||
func Indexed(args abi.Arguments) abi.Arguments {
|
||||
var indexed abi.Arguments
|
||||
for _, arg := range args {
|
||||
if arg.Indexed {
|
||||
indexed = append(indexed, arg)
|
||||
}
|
||||
}
|
||||
return indexed
|
||||
}
|
||||
|
||||
func FindMatchingEventABI(contractABI abi.ABI, topics []common.Hash) *abi.Event {
|
||||
for _, e := range contractABI.Events {
|
||||
if e.ID == topics[0] {
|
||||
indexed := Indexed(e.Inputs)
|
||||
if len(indexed) == len(topics)-1 {
|
||||
return &e
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func DecodeEventLog(event *abi.Event, topics []common.Hash, data []byte) (map[string]interface{}, error) {
|
||||
indexed := Indexed(event.Inputs)
|
||||
values := make(map[string]interface{})
|
||||
if len(indexed) < len(event.Inputs) {
|
||||
if err := event.Inputs.UnpackIntoMap(values, data); err != nil {
|
||||
return nil, fmt.Errorf("can't unpack data: %w", err)
|
||||
}
|
||||
}
|
||||
if err := abi.ParseTopicsIntoMap(values, indexed, topics[1:]); err != nil {
|
||||
return nil, fmt.Errorf("can't unpack topics: %w", err)
|
||||
}
|
||||
return values, nil
|
||||
}
|
||||
|
||||
func ParseLog(contractABI abi.ABI, log *entity.Log) (string, map[string]interface{}, error) {
|
||||
topics := log.Topics()
|
||||
if len(topics) == 0 {
|
||||
return "", nil, fmt.Errorf("cannot process event without topics: %w", ErrInvalidEvent)
|
||||
}
|
||||
event := FindMatchingEventABI(contractABI, topics)
|
||||
if event == nil {
|
||||
return "", nil, nil
|
||||
}
|
||||
|
||||
res, err := DecodeEventLog(event, topics, log.Data)
|
||||
if err != nil {
|
||||
return "", nil, fmt.Errorf("can't decode event log: %w", err)
|
||||
}
|
||||
return event.String(), res, nil
|
||||
}
|
|
@ -118,7 +118,7 @@ func (m *ContractMonitor) RegisterEventHandler(event string, handler EventHandle
|
|||
}
|
||||
|
||||
func (m *ContractMonitor) VerifyEventHandlersABI() error {
|
||||
events := m.contract.AllEvents()
|
||||
events := m.contract.ABI.AllEvents()
|
||||
for e := range m.eventHandlers {
|
||||
if !events[e] {
|
||||
return fmt.Errorf("contract does not have %s event in its ABI: %w", e, ErrIncompatibleABI)
|
||||
|
@ -466,7 +466,7 @@ func (m *ContractMonitor) tryToProcessLogsBatch(ctx context.Context, batch *Logs
|
|||
"block_number": batch.BlockNumber,
|
||||
}).Debug("processing logs batch")
|
||||
for _, log := range batch.Logs {
|
||||
event, data, err := m.contract.ParseLog(log)
|
||||
event, data, err := m.contract.ABI.ParseLog(log)
|
||||
if err != nil {
|
||||
return fmt.Errorf("can't parse log: %w", err)
|
||||
}
|
||||
|
|
|
@ -10,7 +10,7 @@ import (
|
|||
"github.com/ethereum/go-ethereum/crypto"
|
||||
|
||||
"github.com/poanetwork/tokenbridge-monitor/config"
|
||||
"github.com/poanetwork/tokenbridge-monitor/contract/abi"
|
||||
"github.com/poanetwork/tokenbridge-monitor/contract/bridgeabi"
|
||||
"github.com/poanetwork/tokenbridge-monitor/db"
|
||||
"github.com/poanetwork/tokenbridge-monitor/entity"
|
||||
"github.com/poanetwork/tokenbridge-monitor/ethclient"
|
||||
|
@ -96,7 +96,7 @@ func (p *BridgeEventHandler) HandleErcToNativeTransfer(ctx context.Context, log
|
|||
FromBlock: &log.BlockNumber,
|
||||
ToBlock: &log.BlockNumber,
|
||||
TxHash: &log.TransactionHash,
|
||||
Topic0: &abi.ErcToNativeUserRequestForAffirmationEventSignature,
|
||||
Topic0: &bridgeabi.ErcToNativeUserRequestForAffirmationEventSignature,
|
||||
}
|
||||
logs, err := p.repo.Logs.Find(ctx, filter)
|
||||
if err != nil {
|
||||
|
@ -153,7 +153,7 @@ func (p *BridgeEventHandler) HandleErcToNativeUserRequestForAffirmation(ctx cont
|
|||
FromBlock: &log.BlockNumber,
|
||||
ToBlock: &log.BlockNumber,
|
||||
TxHash: &log.TransactionHash,
|
||||
Topic0: &abi.ErcToNativeTransferEventSignature,
|
||||
Topic0: &bridgeabi.ErcToNativeTransferEventSignature,
|
||||
Topic2: hashPtr(p.cfg.Foreign.Address.Hash()),
|
||||
DataLength: uintPtr(32),
|
||||
}
|
||||
|
|
|
@ -5,7 +5,7 @@ import (
|
|||
"fmt"
|
||||
|
||||
"github.com/poanetwork/tokenbridge-monitor/config"
|
||||
"github.com/poanetwork/tokenbridge-monitor/contract/abi"
|
||||
"github.com/poanetwork/tokenbridge-monitor/contract/bridgeabi"
|
||||
"github.com/poanetwork/tokenbridge-monitor/db"
|
||||
"github.com/poanetwork/tokenbridge-monitor/ethclient"
|
||||
"github.com/poanetwork/tokenbridge-monitor/logging"
|
||||
|
@ -63,42 +63,42 @@ func NewMonitor(ctx context.Context, logger logging.Logger, dbConn *db.DB, repo
|
|||
|
||||
func (m *Monitor) RegisterErcToNativeEventHandlers() {
|
||||
handlers := NewBridgeEventHandler(m.repo, m.cfg, m.homeMonitor.client)
|
||||
m.homeMonitor.RegisterEventHandler(abi.ErcToNativeUserRequestForSignature, handlers.HandleErcToNativeUserRequestForSignature)
|
||||
m.homeMonitor.RegisterEventHandler(abi.SignedForUserRequest, handlers.HandleSignedForUserRequest)
|
||||
m.homeMonitor.RegisterEventHandler(abi.CollectedSignatures, handlers.HandleCollectedSignatures)
|
||||
m.homeMonitor.RegisterEventHandler(abi.ErcToNativeSignedForAffirmation, handlers.HandleErcToNativeSignedForAffirmation)
|
||||
m.homeMonitor.RegisterEventHandler(abi.ErcToNativeAffirmationCompleted, handlers.HandleErcToNativeAffirmationCompleted)
|
||||
m.homeMonitor.RegisterEventHandler(abi.ValidatorAdded, handlers.HandleValidatorAdded)
|
||||
m.homeMonitor.RegisterEventHandler(abi.ValidatorRemoved, handlers.HandleValidatorRemoved)
|
||||
m.homeMonitor.RegisterEventHandler(bridgeabi.ErcToNativeUserRequestForSignature, handlers.HandleErcToNativeUserRequestForSignature)
|
||||
m.homeMonitor.RegisterEventHandler(bridgeabi.SignedForUserRequest, handlers.HandleSignedForUserRequest)
|
||||
m.homeMonitor.RegisterEventHandler(bridgeabi.CollectedSignatures, handlers.HandleCollectedSignatures)
|
||||
m.homeMonitor.RegisterEventHandler(bridgeabi.ErcToNativeSignedForAffirmation, handlers.HandleErcToNativeSignedForAffirmation)
|
||||
m.homeMonitor.RegisterEventHandler(bridgeabi.ErcToNativeAffirmationCompleted, handlers.HandleErcToNativeAffirmationCompleted)
|
||||
m.homeMonitor.RegisterEventHandler(bridgeabi.ValidatorAdded, handlers.HandleValidatorAdded)
|
||||
m.homeMonitor.RegisterEventHandler(bridgeabi.ValidatorRemoved, handlers.HandleValidatorRemoved)
|
||||
|
||||
m.foreignMonitor.RegisterEventHandler(abi.ErcToNativeUserRequestForAffirmation, handlers.HandleErcToNativeUserRequestForAffirmation)
|
||||
m.foreignMonitor.RegisterEventHandler(abi.ErcToNativeTransfer, handlers.HandleErcToNativeTransfer)
|
||||
m.foreignMonitor.RegisterEventHandler(abi.ErcToNativeRelayedMessage, handlers.HandleErcToNativeRelayedMessage)
|
||||
m.foreignMonitor.RegisterEventHandler(abi.ValidatorAdded, handlers.HandleValidatorAdded)
|
||||
m.foreignMonitor.RegisterEventHandler(abi.ValidatorRemoved, handlers.HandleValidatorRemoved)
|
||||
m.foreignMonitor.RegisterEventHandler(bridgeabi.ErcToNativeUserRequestForAffirmation, handlers.HandleErcToNativeUserRequestForAffirmation)
|
||||
m.foreignMonitor.RegisterEventHandler(bridgeabi.ErcToNativeTransfer, handlers.HandleErcToNativeTransfer)
|
||||
m.foreignMonitor.RegisterEventHandler(bridgeabi.ErcToNativeRelayedMessage, handlers.HandleErcToNativeRelayedMessage)
|
||||
m.foreignMonitor.RegisterEventHandler(bridgeabi.ValidatorAdded, handlers.HandleValidatorAdded)
|
||||
m.foreignMonitor.RegisterEventHandler(bridgeabi.ValidatorRemoved, handlers.HandleValidatorRemoved)
|
||||
}
|
||||
|
||||
func (m *Monitor) RegisterAMBEventHandlers() {
|
||||
handlers := NewBridgeEventHandler(m.repo, m.cfg, m.homeMonitor.client)
|
||||
m.homeMonitor.RegisterEventHandler(abi.UserRequestForSignature, handlers.HandleUserRequestForSignature)
|
||||
m.homeMonitor.RegisterEventHandler(abi.LegacyUserRequestForSignature, handlers.HandleLegacyUserRequestForSignature)
|
||||
m.homeMonitor.RegisterEventHandler(abi.SignedForUserRequest, handlers.HandleSignedForUserRequest)
|
||||
m.homeMonitor.RegisterEventHandler(abi.CollectedSignatures, handlers.HandleCollectedSignatures)
|
||||
m.homeMonitor.RegisterEventHandler(abi.SignedForAffirmation, handlers.HandleSignedForUserRequest)
|
||||
m.homeMonitor.RegisterEventHandler(abi.AffirmationCompleted, handlers.HandleAffirmationCompleted)
|
||||
m.homeMonitor.RegisterEventHandler(abi.LegacyAffirmationCompleted, handlers.HandleAffirmationCompleted)
|
||||
m.homeMonitor.RegisterEventHandler(abi.UserRequestForInformation, handlers.HandleUserRequestForInformation)
|
||||
m.homeMonitor.RegisterEventHandler(abi.SignedForInformation, handlers.HandleSignedForInformation)
|
||||
m.homeMonitor.RegisterEventHandler(abi.InformationRetrieved, handlers.HandleInformationRetrieved)
|
||||
m.homeMonitor.RegisterEventHandler(abi.ValidatorAdded, handlers.HandleValidatorAdded)
|
||||
m.homeMonitor.RegisterEventHandler(abi.ValidatorRemoved, handlers.HandleValidatorRemoved)
|
||||
m.homeMonitor.RegisterEventHandler(bridgeabi.UserRequestForSignature, handlers.HandleUserRequestForSignature)
|
||||
m.homeMonitor.RegisterEventHandler(bridgeabi.LegacyUserRequestForSignature, handlers.HandleLegacyUserRequestForSignature)
|
||||
m.homeMonitor.RegisterEventHandler(bridgeabi.SignedForUserRequest, handlers.HandleSignedForUserRequest)
|
||||
m.homeMonitor.RegisterEventHandler(bridgeabi.CollectedSignatures, handlers.HandleCollectedSignatures)
|
||||
m.homeMonitor.RegisterEventHandler(bridgeabi.SignedForAffirmation, handlers.HandleSignedForUserRequest)
|
||||
m.homeMonitor.RegisterEventHandler(bridgeabi.AffirmationCompleted, handlers.HandleAffirmationCompleted)
|
||||
m.homeMonitor.RegisterEventHandler(bridgeabi.LegacyAffirmationCompleted, handlers.HandleAffirmationCompleted)
|
||||
m.homeMonitor.RegisterEventHandler(bridgeabi.UserRequestForInformation, handlers.HandleUserRequestForInformation)
|
||||
m.homeMonitor.RegisterEventHandler(bridgeabi.SignedForInformation, handlers.HandleSignedForInformation)
|
||||
m.homeMonitor.RegisterEventHandler(bridgeabi.InformationRetrieved, handlers.HandleInformationRetrieved)
|
||||
m.homeMonitor.RegisterEventHandler(bridgeabi.ValidatorAdded, handlers.HandleValidatorAdded)
|
||||
m.homeMonitor.RegisterEventHandler(bridgeabi.ValidatorRemoved, handlers.HandleValidatorRemoved)
|
||||
|
||||
m.foreignMonitor.RegisterEventHandler(abi.UserRequestForAffirmation, handlers.HandleUserRequestForAffirmation)
|
||||
m.foreignMonitor.RegisterEventHandler(abi.LegacyUserRequestForAffirmation, handlers.HandleLegacyUserRequestForAffirmation)
|
||||
m.foreignMonitor.RegisterEventHandler(abi.RelayedMessage, handlers.HandleRelayedMessage)
|
||||
m.foreignMonitor.RegisterEventHandler(abi.LegacyRelayedMessage, handlers.HandleRelayedMessage)
|
||||
m.foreignMonitor.RegisterEventHandler(abi.ValidatorAdded, handlers.HandleValidatorAdded)
|
||||
m.foreignMonitor.RegisterEventHandler(abi.ValidatorRemoved, handlers.HandleValidatorRemoved)
|
||||
m.foreignMonitor.RegisterEventHandler(bridgeabi.UserRequestForAffirmation, handlers.HandleUserRequestForAffirmation)
|
||||
m.foreignMonitor.RegisterEventHandler(bridgeabi.LegacyUserRequestForAffirmation, handlers.HandleLegacyUserRequestForAffirmation)
|
||||
m.foreignMonitor.RegisterEventHandler(bridgeabi.RelayedMessage, handlers.HandleRelayedMessage)
|
||||
m.foreignMonitor.RegisterEventHandler(bridgeabi.LegacyRelayedMessage, handlers.HandleRelayedMessage)
|
||||
m.foreignMonitor.RegisterEventHandler(bridgeabi.ValidatorAdded, handlers.HandleValidatorAdded)
|
||||
m.foreignMonitor.RegisterEventHandler(bridgeabi.ValidatorRemoved, handlers.HandleValidatorRemoved)
|
||||
}
|
||||
|
||||
func (m *Monitor) Start(ctx context.Context) {
|
||||
|
|
Loading…
Reference in New Issue