Contract-watcher add support wormhole connect wrapper contract (#391)

This commit is contained in:
walker-16 2023-06-08 17:53:51 -03:00 committed by GitHub
parent 444c185f38
commit 8679d9c211
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 581 additions and 206 deletions

View File

@ -16,12 +16,12 @@ import (
"go.uber.org/zap"
)
func CreateEVMWatcher(rateLimit int, chainURL string, wb config.WatcherBlockchain, repo *storage.Repository,
func CreateEVMWatcher(rateLimit int, chainURL string, wb config.WatcherBlockchainAddresses, repo *storage.Repository,
logger *zap.Logger) watcher.ContractWatcher {
evmLimiter := ratelimit.New(rateLimit, ratelimit.Per(time.Second))
ankrClient := ankr.NewAnkrSDK(chainURL, evmLimiter)
params := watcher.EVMParams{ChainID: wb.ChainID, Blockchain: wb.Name, ContractAddress: wb.Address,
SizeBlocks: wb.SizeBlocks, WaitSeconds: wb.WaitSeconds, InitialBlock: wb.InitialBlock}
params := watcher.EVMParams{ChainID: wb.ChainID, Blockchain: wb.Name, SizeBlocks: wb.SizeBlocks,
WaitSeconds: wb.WaitSeconds, InitialBlock: wb.InitialBlock, MethodsByAddress: wb.MethodsByAddress}
return watcher.NewEVMWatcher(ankrClient, repo, params, logger)
}
@ -57,28 +57,28 @@ func CreateAptosWatcher(rateLimit int, chainURL string, wb config.WatcherBlockch
return watcher.NewAptosWatcher(aptosClient, params, repo, logger)
}
func CreateOasisWatcher(rateLimit int, chainURL string, wb config.WatcherBlockchain, logger *zap.Logger, repo *storage.Repository) watcher.ContractWatcher {
func CreateOasisWatcher(rateLimit int, chainURL string, wb config.WatcherBlockchainAddresses, logger *zap.Logger, repo *storage.Repository) watcher.ContractWatcher {
oasisLimiter := ratelimit.New(rateLimit, ratelimit.Per(time.Second))
oasisClient := evm.NewEvmSDK(chainURL, oasisLimiter)
params := watcher.EVMParams{
ChainID: wb.ChainID,
Blockchain: wb.Name,
ContractAddress: wb.Address,
SizeBlocks: wb.SizeBlocks,
WaitSeconds: wb.WaitSeconds,
InitialBlock: wb.InitialBlock}
ChainID: wb.ChainID,
Blockchain: wb.Name,
SizeBlocks: wb.SizeBlocks,
WaitSeconds: wb.WaitSeconds,
InitialBlock: wb.InitialBlock,
MethodsByAddress: wb.MethodsByAddress}
return watcher.NewEvmStandarWatcher(oasisClient, params, repo, logger)
}
func CreateMoonbeamWatcher(rateLimit int, chainURL string, wb config.WatcherBlockchain, logger *zap.Logger, repo *storage.Repository) watcher.ContractWatcher {
func CreateMoonbeamWatcher(rateLimit int, chainURL string, wb config.WatcherBlockchainAddresses, logger *zap.Logger, repo *storage.Repository) watcher.ContractWatcher {
moonbeamLimiter := ratelimit.New(rateLimit, ratelimit.Per(time.Second))
moonbeamClient := evm.NewEvmSDK(chainURL, moonbeamLimiter)
params := watcher.EVMParams{
ChainID: wb.ChainID,
Blockchain: wb.Name,
ContractAddress: wb.Address,
SizeBlocks: wb.SizeBlocks,
WaitSeconds: wb.WaitSeconds,
InitialBlock: wb.InitialBlock}
ChainID: wb.ChainID,
Blockchain: wb.Name,
SizeBlocks: wb.SizeBlocks,
WaitSeconds: wb.WaitSeconds,
InitialBlock: wb.InitialBlock,
MethodsByAddress: wb.MethodsByAddress}
return watcher.NewEvmStandarWatcher(moonbeamClient, params, repo, logger)
}

View File

@ -36,12 +36,12 @@ func handleExit() {
}
type watchersConfig struct {
evms []config.WatcherBlockchain
evms []config.WatcherBlockchainAddresses
solana *config.WatcherBlockchain
terra *config.WatcherBlockchain
aptos *config.WatcherBlockchain
oasis *config.WatcherBlockchain
moonbeam *config.WatcherBlockchain
oasis *config.WatcherBlockchainAddresses
moonbeam *config.WatcherBlockchainAddresses
rateLimit rateLimitConfig
}
@ -126,9 +126,9 @@ func newWatchers(config *config.ServiceConfiguration, repo *storage.Repository,
var watchers *watchersConfig
switch config.P2pNetwork {
case domain.P2pMainNet:
watchers = newEVMWatchersForMainnet()
watchers = newWatchersForMainnet()
case domain.P2pTestNet:
watchers = newEVMWatchersForTestnet()
watchers = newWatchersForTestnet()
default:
watchers = &watchersConfig{}
}
@ -139,8 +139,8 @@ func newWatchers(config *config.ServiceConfiguration, repo *storage.Repository,
evmLimiter := ratelimit.New(watchers.rateLimit.evm, ratelimit.Per(time.Second))
ankrClient := ankr.NewAnkrSDK(config.AnkrUrl, evmLimiter)
for _, w := range watchers.evms {
params := watcher.EVMParams{ChainID: w.ChainID, Blockchain: w.Name, ContractAddress: w.Address,
SizeBlocks: w.SizeBlocks, WaitSeconds: w.WaitSeconds, InitialBlock: w.InitialBlock}
params := watcher.EVMParams{ChainID: w.ChainID, Blockchain: w.Name, SizeBlocks: w.SizeBlocks,
WaitSeconds: w.WaitSeconds, InitialBlock: w.InitialBlock, MethodsByAddress: w.MethodsByAddress}
result = append(result, watcher.NewEVMWatcher(ankrClient, repo, params, logger))
}
@ -177,9 +177,9 @@ func newWatchers(config *config.ServiceConfiguration, repo *storage.Repository,
return result
}
func newEVMWatchersForMainnet() *watchersConfig {
func newWatchersForMainnet() *watchersConfig {
return &watchersConfig{
evms: []config.WatcherBlockchain{
evms: []config.WatcherBlockchainAddresses{
config.ETHEREUM_MAINNET,
config.POLYGON_MAINNET,
config.BSC_MAINNET,
@ -202,9 +202,9 @@ func newEVMWatchersForMainnet() *watchersConfig {
}
}
func newEVMWatchersForTestnet() *watchersConfig {
func newWatchersForTestnet() *watchersConfig {
return &watchersConfig{
evms: []config.WatcherBlockchain{
evms: []config.WatcherBlockchainAddresses{
config.ETHEREUM_TESTNET,
config.POLYGON_TESTNET,
config.BSC_TESTNET,

View File

@ -1,41 +1,145 @@
package config
import "github.com/wormhole-foundation/wormhole/sdk/vaa"
import (
"strings"
var ETHEREUM_MAINNET = WatcherBlockchain{
"github.com/wormhole-foundation/wormhole/sdk/vaa"
)
var ETHEREUM_MAINNET = WatcherBlockchainAddresses{
ChainID: vaa.ChainIDEthereum,
Name: "eth",
Address: "0x3ee18B2214AFF97000D974cf647E7C347E8fa585",
SizeBlocks: 100,
WaitSeconds: 10,
InitialBlock: 16820790,
MethodsByAddress: map[string][]BlockchainMethod{
strings.ToLower("0x3ee18B2214AFF97000D974cf647E7C347E8fa585"): {
{
ID: MethodIDCompleteTransfer,
Name: MethodCompleteTransfer,
},
{
ID: MethodIDCompleteAndUnwrapETH,
Name: MethodCompleteAndUnwrapETH,
},
{
ID: MethodIDCreateWrapped,
Name: MethodCreateWrapped,
},
{
ID: MethodIDUpdateWrapped,
Name: MethodUpdateWrapped,
},
},
strings.ToLower("0xcafd2f0a35a4459fa40c0517e17e6fa2939441ca"): {
{
ID: MetehodIDCompleteTransferWithRelay,
Name: MetehodCompleteTransferWithRelay,
},
},
},
}
var POLYGON_MAINNET = WatcherBlockchain{
var POLYGON_MAINNET = WatcherBlockchainAddresses{
ChainID: vaa.ChainIDPolygon,
Name: "polygon",
Address: "0x5a58505a96D1dbf8dF91cB21B54419FC36e93fdE",
SizeBlocks: 100,
WaitSeconds: 10,
InitialBlock: 40307020,
MethodsByAddress: map[string][]BlockchainMethod{
strings.ToLower("0x5a58505a96D1dbf8dF91cB21B54419FC36e93fdE"): {
{
ID: MethodIDCompleteTransfer,
Name: MethodCompleteTransfer,
},
{
ID: MethodIDCompleteAndUnwrapETH,
Name: MethodCompleteAndUnwrapETH,
},
{
ID: MethodIDCreateWrapped,
Name: MethodCreateWrapped,
},
{
ID: MethodIDUpdateWrapped,
Name: MethodUpdateWrapped,
},
},
strings.ToLower("0xcafd2f0a35a4459fa40c0517e17e6fa2939441ca"): {
{
ID: MetehodIDCompleteTransferWithRelay,
Name: MetehodCompleteTransferWithRelay,
},
},
},
}
var BSC_MAINNET = WatcherBlockchain{
var BSC_MAINNET = WatcherBlockchainAddresses{
ChainID: vaa.ChainIDBSC,
Name: "bsc",
Address: "0xB6F6D86a8f9879A9c87f643768d9efc38c1Da6E7",
SizeBlocks: 100,
WaitSeconds: 10,
InitialBlock: 26436320,
MethodsByAddress: map[string][]BlockchainMethod{
strings.ToLower("0xB6F6D86a8f9879A9c87f643768d9efc38c1Da6E7"): {
{
ID: MethodIDCompleteTransfer,
Name: MethodCompleteTransfer,
},
{
ID: MethodIDCompleteAndUnwrapETH,
Name: MethodCompleteAndUnwrapETH,
},
{
ID: MethodIDCreateWrapped,
Name: MethodCreateWrapped,
},
{
ID: MethodIDUpdateWrapped,
Name: MethodUpdateWrapped,
},
},
strings.ToLower("0xcafd2f0a35a4459fa40c0517e17e6fa2939441ca"): {
{
ID: MetehodIDCompleteTransferWithRelay,
Name: MetehodCompleteTransferWithRelay,
},
},
},
}
var FANTOM_MAINNET = WatcherBlockchain{
var FANTOM_MAINNET = WatcherBlockchainAddresses{
ChainID: vaa.ChainIDFantom,
Name: "fantom",
Address: "0x7C9Fc5741288cDFdD83CeB07f3ea7e22618D79D2",
SizeBlocks: 100,
WaitSeconds: 10,
InitialBlock: 57525624,
MethodsByAddress: map[string][]BlockchainMethod{
strings.ToLower("0x7C9Fc5741288cDFdD83CeB07f3ea7e22618D79D2"): {
{
ID: MethodIDCompleteTransfer,
Name: MethodCompleteTransfer,
},
{
ID: MethodIDCompleteAndUnwrapETH,
Name: MethodCompleteAndUnwrapETH,
},
{
ID: MethodIDCreateWrapped,
Name: MethodCreateWrapped,
},
{
ID: MethodIDUpdateWrapped,
Name: MethodUpdateWrapped,
},
},
strings.ToLower("0xcafd2f0a35a4459fa40c0517e17e6fa2939441ca"): {
{
ID: MetehodIDCompleteTransferWithRelay,
Name: MetehodCompleteTransferWithRelay,
},
},
},
}
var SOLANA_MAINNET = WatcherBlockchain{
@ -56,13 +160,38 @@ var TERRA_MAINNET = WatcherBlockchain{
InitialBlock: 3911168,
}
var AVALANCHE_MAINNET = WatcherBlockchain{
var AVALANCHE_MAINNET = WatcherBlockchainAddresses{
ChainID: vaa.ChainIDAvalanche,
Name: "avalanche",
Address: "0x0e082F06FF657D94310cB8cE8B0D9a04541d8052",
SizeBlocks: 100,
WaitSeconds: 10,
InitialBlock: 8237181,
MethodsByAddress: map[string][]BlockchainMethod{
strings.ToLower("0x0e082F06FF657D94310cB8cE8B0D9a04541d8052"): {
{
ID: MethodIDCompleteTransfer,
Name: MethodCompleteTransfer,
},
{
ID: MethodIDCompleteAndUnwrapETH,
Name: MethodCompleteAndUnwrapETH,
},
{
ID: MethodIDCreateWrapped,
Name: MethodCreateWrapped,
},
{
ID: MethodIDUpdateWrapped,
Name: MethodUpdateWrapped,
},
},
strings.ToLower("0xcafd2f0a35a4459fa40c0517e17e6fa2939441ca"): {
{
ID: MetehodIDCompleteTransferWithRelay,
Name: MetehodCompleteTransferWithRelay,
},
},
},
}
var APTOS_MAINNET = WatcherBlockchain{
@ -74,20 +203,64 @@ var APTOS_MAINNET = WatcherBlockchain{
InitialBlock: 1094430,
}
var OASIS_MAINNET = WatcherBlockchain{
var OASIS_MAINNET = WatcherBlockchainAddresses{
ChainID: vaa.ChainIDOasis,
Name: "oasis",
Address: "0x5848C791e09901b40A9Ef749f2a6735b418d7564",
SizeBlocks: 50,
WaitSeconds: 10,
InitialBlock: 1762,
MethodsByAddress: map[string][]BlockchainMethod{
strings.ToLower("0x5848C791e09901b40A9Ef749f2a6735b418d7564"): {
{
ID: MethodIDCompleteTransfer,
Name: MethodCompleteTransfer,
},
{
ID: MethodIDCompleteAndUnwrapETH,
Name: MethodCompleteAndUnwrapETH,
},
{
ID: MethodIDCreateWrapped,
Name: MethodCreateWrapped,
},
{
ID: MethodIDUpdateWrapped,
Name: MethodUpdateWrapped,
},
},
},
}
var MOONBEAM_MAINNET = WatcherBlockchain{
var MOONBEAM_MAINNET = WatcherBlockchainAddresses{
ChainID: vaa.ChainIDMoonbeam,
Name: "moonbeam",
Address: "0xb1731c586ca89a23809861c6103f0b96b3f57d92",
SizeBlocks: 50,
WaitSeconds: 10,
InitialBlock: 1853330,
MethodsByAddress: map[string][]BlockchainMethod{
strings.ToLower("0xb1731c586ca89a23809861c6103f0b96b3f57d92"): {
{
ID: MethodIDCompleteTransfer,
Name: MethodCompleteTransfer,
},
{
ID: MethodIDCompleteAndUnwrapETH,
Name: MethodCompleteAndUnwrapETH,
},
{
ID: MethodIDCreateWrapped,
Name: MethodCreateWrapped,
},
{
ID: MethodIDUpdateWrapped,
Name: MethodUpdateWrapped,
},
},
strings.ToLower("0xcafd2f0a35a4459fa40c0517e17e6fa2939441ca"): {
{
ID: MetehodIDCompleteTransferWithRelay,
Name: MetehodCompleteTransferWithRelay,
},
},
},
}

View File

@ -1,41 +1,145 @@
package config
import "github.com/wormhole-foundation/wormhole/sdk/vaa"
import (
"strings"
var ETHEREUM_TESTNET = WatcherBlockchain{
"github.com/wormhole-foundation/wormhole/sdk/vaa"
)
var ETHEREUM_TESTNET = WatcherBlockchainAddresses{
ChainID: vaa.ChainIDEthereum,
Name: "eth_goerli",
Address: "0xF890982f9310df57d00f659cf4fd87e65adEd8d7",
SizeBlocks: 100,
WaitSeconds: 10,
InitialBlock: 8660321,
MethodsByAddress: map[string][]BlockchainMethod{
strings.ToLower("0xF890982f9310df57d00f659cf4fd87e65adEd8d7"): {
{
ID: MethodIDCompleteTransfer,
Name: MethodCompleteTransfer,
},
{
ID: MethodIDCompleteAndUnwrapETH,
Name: MethodCompleteAndUnwrapETH,
},
{
ID: MethodIDCreateWrapped,
Name: MethodCreateWrapped,
},
{
ID: MethodIDUpdateWrapped,
Name: MethodUpdateWrapped,
},
},
strings.ToLower("0x9563a59C15842a6f322B10f69d1dD88b41f2E97B"): {
{
ID: MetehodIDCompleteTransferWithRelay,
Name: MetehodCompleteTransferWithRelay,
},
},
},
}
var POLYGON_TESTNET = WatcherBlockchain{
var POLYGON_TESTNET = WatcherBlockchainAddresses{
ChainID: vaa.ChainIDPolygon,
Name: "polygon_mumbai",
Address: "0x377D55a7928c046E18eEbb61977e714d2a76472a",
SizeBlocks: 100,
WaitSeconds: 10,
InitialBlock: 33151522,
MethodsByAddress: map[string][]BlockchainMethod{
strings.ToLower("0x377D55a7928c046E18eEbb61977e714d2a76472a"): {
{
ID: MethodIDCompleteTransfer,
Name: MethodCompleteTransfer,
},
{
ID: MethodIDCompleteAndUnwrapETH,
Name: MethodCompleteAndUnwrapETH,
},
{
ID: MethodIDCreateWrapped,
Name: MethodCreateWrapped,
},
{
ID: MethodIDUpdateWrapped,
Name: MethodUpdateWrapped,
},
},
strings.ToLower("0x9563a59C15842a6f322B10f69d1dD88b41f2E97B"): {
{
ID: MetehodIDCompleteTransferWithRelay,
Name: MetehodCompleteTransferWithRelay,
},
},
},
}
var BSC_TESTNET = WatcherBlockchain{
var BSC_TESTNET = WatcherBlockchainAddresses{
ChainID: vaa.ChainIDBSC,
Name: "bsc_testnet_chapel",
Address: "0x9dcF9D205C9De35334D646BeE44b2D2859712A09",
SizeBlocks: 100,
WaitSeconds: 10,
InitialBlock: 28071327,
MethodsByAddress: map[string][]BlockchainMethod{
strings.ToLower("0x9dcF9D205C9De35334D646BeE44b2D2859712A09"): {
{
ID: MethodIDCompleteTransfer,
Name: MethodCompleteTransfer,
},
{
ID: MethodIDCompleteAndUnwrapETH,
Name: MethodCompleteAndUnwrapETH,
},
{
ID: MethodIDCreateWrapped,
Name: MethodCreateWrapped,
},
{
ID: MethodIDUpdateWrapped,
Name: MethodUpdateWrapped,
},
},
strings.ToLower("0x9563a59C15842a6f322B10f69d1dD88b41f2E97B"): {
{
ID: MetehodIDCompleteTransferWithRelay,
Name: MetehodCompleteTransferWithRelay,
},
},
},
}
var FANTOM_TESTNET = WatcherBlockchain{
var FANTOM_TESTNET = WatcherBlockchainAddresses{
ChainID: vaa.ChainIDFantom,
Name: "fantom_testnet",
Address: "0x599CEa2204B4FaECd584Ab1F2b6aCA137a0afbE8",
SizeBlocks: 100,
WaitSeconds: 10,
InitialBlock: 14524466,
MethodsByAddress: map[string][]BlockchainMethod{
strings.ToLower("0x599CEa2204B4FaECd584Ab1F2b6aCA137a0afbE8"): {
{
ID: MethodIDCompleteTransfer,
Name: MethodCompleteTransfer,
},
{
ID: MethodIDCompleteAndUnwrapETH,
Name: MethodCompleteAndUnwrapETH,
},
{
ID: MethodIDCreateWrapped,
Name: MethodCreateWrapped,
},
{
ID: MethodIDUpdateWrapped,
Name: MethodUpdateWrapped,
},
},
strings.ToLower("0x9563a59C15842a6f322B10f69d1dD88b41f2E97B"): {
{
ID: MetehodIDCompleteTransferWithRelay,
Name: MetehodCompleteTransferWithRelay,
},
},
},
}
var SOLANA_TESTNET = WatcherBlockchain{
@ -47,13 +151,38 @@ var SOLANA_TESTNET = WatcherBlockchain{
InitialBlock: 16820790,
}
var AVALANCHE_TESTNET = WatcherBlockchain{
var AVALANCHE_TESTNET = WatcherBlockchainAddresses{
ChainID: vaa.ChainIDAvalanche,
Name: "avalanche_fuji",
Address: "0x61E44E506Ca5659E6c0bba9b678586fA2d729756",
SizeBlocks: 100,
WaitSeconds: 10,
InitialBlock: 11014526,
MethodsByAddress: map[string][]BlockchainMethod{
strings.ToLower("0x61E44E506Ca5659E6c0bba9b678586fA2d729756"): {
{
ID: MethodIDCompleteTransfer,
Name: MethodCompleteTransfer,
},
{
ID: MethodIDCompleteAndUnwrapETH,
Name: MethodCompleteAndUnwrapETH,
},
{
ID: MethodIDCreateWrapped,
Name: MethodCreateWrapped,
},
{
ID: MethodIDUpdateWrapped,
Name: MethodUpdateWrapped,
},
},
strings.ToLower("0x9563a59C15842a6f322B10f69d1dD88b41f2E97B"): {
{
ID: MetehodIDCompleteTransferWithRelay,
Name: MetehodCompleteTransferWithRelay,
},
},
},
}
var APTOS_TESTNET = WatcherBlockchain{
@ -65,20 +194,64 @@ var APTOS_TESTNET = WatcherBlockchain{
InitialBlock: 21522262,
}
var OASIS_TESTNET = WatcherBlockchain{
var OASIS_TESTNET = WatcherBlockchainAddresses{
ChainID: vaa.ChainIDOasis,
Name: "oasis",
Address: "0x88d8004A9BdbfD9D28090A02010C19897a29605c",
SizeBlocks: 50,
WaitSeconds: 10,
InitialBlock: 130400,
MethodsByAddress: map[string][]BlockchainMethod{
strings.ToLower("0x88d8004A9BdbfD9D28090A02010C19897a29605c"): {
{
ID: MethodIDCompleteTransfer,
Name: MethodCompleteTransfer,
},
{
ID: MethodIDCompleteAndUnwrapETH,
Name: MethodCompleteAndUnwrapETH,
},
{
ID: MethodIDCreateWrapped,
Name: MethodCreateWrapped,
},
{
ID: MethodIDUpdateWrapped,
Name: MethodUpdateWrapped,
},
},
},
}
var MOONBEAM_TESTNET = WatcherBlockchain{
var MOONBEAM_TESTNET = WatcherBlockchainAddresses{
ChainID: vaa.ChainIDMoonbeam,
Name: "moonbeam",
Address: "0xbc976D4b9D57E57c3cA52e1Fd136C45FF7955A96",
SizeBlocks: 50,
WaitSeconds: 10,
InitialBlock: 2097310,
MethodsByAddress: map[string][]BlockchainMethod{
strings.ToLower("0xbc976D4b9D57E57c3cA52e1Fd136C45FF7955A96"): {
{
ID: MethodIDCompleteTransfer,
Name: MethodCompleteTransfer,
},
{
ID: MethodIDCompleteAndUnwrapETH,
Name: MethodCompleteAndUnwrapETH,
},
{
ID: MethodIDCreateWrapped,
Name: MethodCreateWrapped,
},
{
ID: MethodIDUpdateWrapped,
Name: MethodUpdateWrapped,
},
},
strings.ToLower("0x9563a59C15842a6f322B10f69d1dD88b41f2E97B"): {
{
ID: MetehodIDCompleteTransferWithRelay,
Name: MetehodCompleteTransferWithRelay,
},
},
},
}

View File

@ -2,6 +2,31 @@ package config
import "github.com/wormhole-foundation/wormhole/sdk/vaa"
const (
//Method names for wormhole token bridge contract.
MethodCompleteTransfer = "completeTransfer"
MethodWrapAndTransfer = "wrapAndTransfer"
MethodTransferTokens = "transferTokens"
MethodAttestToken = "attestToken"
MethodCompleteAndUnwrapETH = "completeAndUnwrapETH"
MethodCreateWrapped = "createWrapped"
MethodUpdateWrapped = "updateWrapped"
MethodUnkown = "unknown"
//Method name for wormhole connect wrapped contract.
MetehodCompleteTransferWithRelay = "completeTransferWithRelay"
//Method ids for wormhole token bridge contract
MethodIDCompleteTransfer = "0xc6878519"
MethodIDWrapAndTransfer = "0x9981509f"
MethodIDTransferTokens = "0x0f5287b0"
MethodIDAttestToken = "0xc48fa115"
MethodIDCompleteAndUnwrapETH = "0xff200cde"
MethodIDCreateWrapped = "0xe8059810"
MethodIDUpdateWrapped = "0xf768441f"
//Method id for wormhole connect wrapped contract.
MetehodIDCompleteTransferWithRelay = "0x2f25e25f"
)
type WatcherBlockchain struct {
ChainID vaa.ChainID
Name string
@ -10,3 +35,18 @@ type WatcherBlockchain struct {
WaitSeconds uint16
InitialBlock int64
}
type WatcherBlockchainAddresses struct {
ChainID vaa.ChainID
Name string
SizeBlocks uint8
WaitSeconds uint16
// Initial block indicates for the supported contracts, the oldest block from which to start processing.
InitialBlock int64
MethodsByAddress map[string][]BlockchainMethod
}
type BlockchainMethod struct {
ID string
Name string
}

View File

@ -15,7 +15,7 @@ func WithBlochchain(blockchain string) MaultichainOption {
}
}
func WithContract(address string) MaultichainOption {
func WithContract(address []string) MaultichainOption {
return func(h *TransactionsByAddressRequest) {
h.RequestParams.Address = address
}
@ -56,16 +56,16 @@ func NewTransactionsByAddressRequest(opts ...MaultichainOption) *TransactionsByA
}
type RequestParams struct {
Address string `json:"address"`
Blockchain string `json:"blockchain"`
FromBlock int64 `json:"fromBlock,omitempty"`
ToBlock int64 `json:"toBlock,omitempty"`
FromTimestamp int64 `json:"fromTimestamp,omitempty"`
ToTimestamp int64 `json:"toTimestamp,omitempty"`
IncludeLogs bool `json:"includeLogs,omitempty"`
DescOrder bool `json:"descOrder,omitempty"`
PageSize int64 `json:"pageSize,omitempty"`
PageToken string `json:"pageToken,omitempty"`
Address []string `json:"address"`
Blockchain string `json:"blockchain"`
FromBlock int64 `json:"fromBlock,omitempty"`
ToBlock int64 `json:"toBlock,omitempty"`
FromTimestamp int64 `json:"fromTimestamp,omitempty"`
ToTimestamp int64 `json:"toTimestamp,omitempty"`
IncludeLogs bool `json:"includeLogs,omitempty"`
DescOrder bool `json:"descOrder,omitempty"`
PageSize int64 `json:"pageSize,omitempty"`
PageToken string `json:"pageToken,omitempty"`
}
type TransactionsByAddressResponse struct {

View File

@ -4,8 +4,10 @@ import (
"context"
"encoding/hex"
"strconv"
"strings"
"time"
"github.com/wormhole-foundation/wormhole-explorer/contract-watcher/config"
"github.com/wormhole-foundation/wormhole-explorer/contract-watcher/storage"
"github.com/wormhole-foundation/wormhole-explorer/contract-watcher/support"
"github.com/wormhole-foundation/wormhole/sdk/vaa"
@ -13,37 +15,26 @@ import (
)
const (
//Method names
MethodCompleteTransfer = "completeTransfer"
MethodWrapAndTransfer = "wrapAndTransfer"
MethodTransferTokens = "transferTokens"
MethodAttestToken = "attestToken"
MethodCompleteAndUnwrapETH = "completeAndUnwrapETH"
MethodCreateWrapped = "createWrapped"
MethodUpdateWrapped = "updateWrapped"
MethodUnkown = "unknown"
//Method ids
MethodIDCompleteTransfer = "0xc6878519"
MethodIDWrapAndTransfer = "0x9981509f"
MethodIDTransferTokens = "0x0f5287b0"
MethodIDAttestToken = "0xc48fa115"
MethodIDCompleteAndUnwrapETH = "0xff200cde"
MethodIDCreateWrapped = "0xe8059810"
MethodIDUpdateWrapped = "0xf768441f"
//Transaction status
TxStatusSuccess = "0x1"
TxStatusFailReverted = "0x0"
)
type EVMParams struct {
ChainID vaa.ChainID
Blockchain string
ContractAddress string
SizeBlocks uint8
WaitSeconds uint16
InitialBlock int64
ChainID vaa.ChainID
Blockchain string
SizeBlocks uint8
WaitSeconds uint16
InitialBlock int64
MethodsByAddress map[string][]config.BlockchainMethod
}
type EVMAddressesParams struct {
ChainID vaa.ChainID
Blockchain string
SizeBlocks uint8
WaitSeconds uint16
InitialBlock int64
}
type EvmGetStatusFunc func() (string, error)
@ -70,31 +61,12 @@ func getTxStatus(status string) string {
}
}
// get executed method by input
// completeTransfer, completeAndUnwrapETH, createWrapped receive a VAA as input
func getMethodByInput(input string) string {
// get method ID from transaction input
func getMethodIDByInput(input string) string {
if len(input) < 10 {
return MethodUnkown
}
method := input[0:10]
switch method {
case MethodIDCompleteTransfer:
return MethodCompleteTransfer
case MethodIDWrapAndTransfer:
return MethodWrapAndTransfer
case MethodIDTransferTokens:
return MethodTransferTokens
case MethodIDAttestToken:
return MethodAttestToken
case MethodIDCompleteAndUnwrapETH:
return MethodCompleteAndUnwrapETH
case MethodIDCreateWrapped:
return MethodCreateWrapped
case MethodIDUpdateWrapped:
return MethodUpdateWrapped
default:
return MethodUnkown
return config.MethodUnkown
}
return input[0:10]
}
// get the input and extract the method signature and VAA
@ -133,50 +105,59 @@ func getTimestamp(s string, logger *zap.Logger) *time.Time {
return &tm
}
func processTransaction(ctx context.Context, chainID vaa.ChainID, tx *EvmTransaction, repository *storage.Repository, logger *zap.Logger) {
method := getMethodByInput(tx.Input)
func processTransaction(ctx context.Context, chainID vaa.ChainID, tx *EvmTransaction, methodsByAddress map[string][]config.BlockchainMethod, repository *storage.Repository, logger *zap.Logger) {
// get methodID from the transaction.
txMethod := getMethodIDByInput(tx.Input)
log := logger.With(
zap.String("txHash", tx.Hash),
zap.String("method", method),
zap.String("method", txMethod),
zap.String("block", tx.BlockNumber))
log.Debug("new tx")
switch method {
case MethodCompleteTransfer, MethodCompleteAndUnwrapETH, MethodCreateWrapped, MethodUpdateWrapped:
vaa, err := parseInput(tx.Input)
if err != nil {
log.Error("cannot parse VAA", zap.Error(err))
return
}
// get evm blockchain status code
txStatusCode, err := tx.Status()
if err != nil {
log.Error("cannot get tx status", zap.Error(err))
return
}
updatedAt := time.Now()
globalTx := storage.TransactionUpdate{
ID: vaa.MessageID(),
Destination: storage.DestinationTx{
ChainID: chainID,
Status: getTxStatus(txStatusCode),
Method: getMethodByInput(tx.Input),
TxHash: support.Remove0x(tx.Hash),
To: tx.To,
From: tx.From,
BlockNumber: getBlockNumber(tx.BlockNumber, log),
Timestamp: getTimestamp(tx.BlockTimestamp, log),
UpdatedAt: &updatedAt,
},
}
// update global transaction and check if it should be updated.
updateGlobalTransaction(ctx, globalTx, repository, log)
case MethodUnkown:
// get methods by address.
methods, ok := methodsByAddress[strings.ToLower(tx.To)]
if !ok {
log.Debug("method unkown")
return
}
for _, method := range methods {
if method.ID == txMethod {
// get vaa from transaction input
vaa, err := parseInput(tx.Input)
if err != nil {
log.Error("cannot parse VAA", zap.Error(err))
return
}
// get evm blockchain status code
txStatusCode, err := tx.Status()
if err != nil {
log.Error("cannot get tx status", zap.Error(err))
return
}
updatedAt := time.Now()
globalTx := storage.TransactionUpdate{
ID: vaa.MessageID(),
Destination: storage.DestinationTx{
ChainID: chainID,
Status: getTxStatus(txStatusCode),
Method: method.Name,
TxHash: support.Remove0x(tx.Hash),
To: tx.To,
From: tx.From,
BlockNumber: getBlockNumber(tx.BlockNumber, log),
Timestamp: getTimestamp(tx.BlockTimestamp, log),
UpdatedAt: &updatedAt,
},
}
// update global transaction and check if it should be updated.
updateGlobalTransaction(ctx, globalTx, repository, log)
break
}
}
}

View File

@ -2,10 +2,12 @@ package watcher
import (
"context"
"strings"
"sync"
"time"
"github.com/avast/retry-go"
"github.com/wormhole-foundation/wormhole-explorer/contract-watcher/config"
"github.com/wormhole-foundation/wormhole-explorer/contract-watcher/internal/evm"
"github.com/wormhole-foundation/wormhole-explorer/contract-watcher/storage"
"github.com/wormhole-foundation/wormhole/sdk/vaa"
@ -18,38 +20,36 @@ const (
)
type EvmStandarWatcher struct {
client *evm.EvmSDK
chainID vaa.ChainID
blockchain string
contractAddress string
maxBlocks uint64
waitSeconds uint16
initialBlock int64
repository *storage.Repository
logger *zap.Logger
close chan bool
wg sync.WaitGroup
}
type EvmStandarParams struct {
ChainID vaa.ChainID
Blockchain string
ContractAddress string
SizeBlocks uint8
WaitSeconds uint16
InitialBlock uint64
client *evm.EvmSDK
chainID vaa.ChainID
blockchain string
contractAddress []string
methodsByAddress map[string][]config.BlockchainMethod
maxBlocks uint64
waitSeconds uint16
initialBlock int64
repository *storage.Repository
logger *zap.Logger
close chan bool
wg sync.WaitGroup
}
func NewEvmStandarWatcher(client *evm.EvmSDK, params EVMParams, repo *storage.Repository, logger *zap.Logger) *EvmStandarWatcher {
addresses := make([]string, 0, len(params.MethodsByAddress))
for address := range params.MethodsByAddress {
addresses = append(addresses, address)
}
return &EvmStandarWatcher{
client: client,
chainID: params.ChainID,
blockchain: params.Blockchain,
contractAddress: params.ContractAddress,
maxBlocks: uint64(params.SizeBlocks),
waitSeconds: params.WaitSeconds,
initialBlock: params.InitialBlock,
repository: repo,
logger: logger.With(zap.String("blockchain", params.Blockchain), zap.Uint16("chainId", uint16(params.ChainID))),
client: client,
chainID: params.ChainID,
blockchain: params.Blockchain,
contractAddress: addresses,
methodsByAddress: params.MethodsByAddress,
maxBlocks: uint64(params.SizeBlocks),
waitSeconds: params.WaitSeconds,
initialBlock: params.InitialBlock,
repository: repo,
logger: logger.With(zap.String("blockchain", params.Blockchain), zap.Uint16("chainId", uint16(params.ChainID))),
}
}
@ -131,7 +131,8 @@ func (w *EvmStandarWatcher) processBlock(ctx context.Context, fromBlock uint64,
for _, tx := range blockResult.Transactions {
// only process transactions to the contract address.
if w.contractAddress != tx.To {
_, ok := w.methodsByAddress[strings.ToLower(tx.To)]
if !ok {
continue
}
@ -168,7 +169,7 @@ func (w *EvmStandarWatcher) processBlock(ctx context.Context, fromBlock uint64,
BlockTimestamp: blockResult.Timestamp,
Input: tx.Input,
}
processTransaction(ctx, w.chainID, evmTx, w.repository, w.logger)
processTransaction(ctx, w.chainID, evmTx, w.methodsByAddress, w.repository, w.logger)
}
if updateWatcherBlock {

View File

@ -7,6 +7,7 @@ import (
"sync"
"time"
"github.com/wormhole-foundation/wormhole-explorer/contract-watcher/config"
"github.com/wormhole-foundation/wormhole-explorer/contract-watcher/internal/ankr"
"github.com/wormhole-foundation/wormhole-explorer/contract-watcher/storage"
"github.com/wormhole-foundation/wormhole/sdk/vaa"
@ -14,30 +15,36 @@ import (
)
type EVMWatcher struct {
client *ankr.AnkrSDK
chainID vaa.ChainID
blockchain string
contractAddress string
sizeBlocks uint8
waitSeconds uint16
initialBlock int64
repository *storage.Repository
logger *zap.Logger
close chan bool
wg sync.WaitGroup
client *ankr.AnkrSDK
chainID vaa.ChainID
blockchain string
contractAddress []string
methodsByAddress map[string][]config.BlockchainMethod
sizeBlocks uint8
waitSeconds uint16
initialBlock int64
repository *storage.Repository
logger *zap.Logger
close chan bool
wg sync.WaitGroup
}
func NewEVMWatcher(client *ankr.AnkrSDK, repo *storage.Repository, params EVMParams, logger *zap.Logger) *EVMWatcher {
addresses := make([]string, 0, len(params.MethodsByAddress))
for address := range params.MethodsByAddress {
addresses = append(addresses, address)
}
return &EVMWatcher{
client: client,
chainID: params.ChainID,
blockchain: params.Blockchain,
contractAddress: params.ContractAddress,
sizeBlocks: params.SizeBlocks,
waitSeconds: params.WaitSeconds,
initialBlock: params.InitialBlock,
repository: repo,
logger: logger.With(zap.String("blockchain", params.Blockchain), zap.Uint16("chainId", uint16(params.ChainID))),
client: client,
chainID: params.ChainID,
blockchain: params.Blockchain,
contractAddress: addresses,
methodsByAddress: params.MethodsByAddress,
sizeBlocks: params.SizeBlocks,
waitSeconds: params.WaitSeconds,
initialBlock: params.InitialBlock,
repository: repo,
logger: logger.With(zap.String("blockchain", params.Blockchain), zap.Uint16("chainId", uint16(params.ChainID))),
}
}
@ -142,7 +149,7 @@ func (w *EVMWatcher) processBlock(ctx context.Context, currentBlock int64, lastB
BlockTimestamp: tx.Timestamp,
Input: tx.Input,
}
processTransaction(ctx, w.chainID, evmTx, w.repository, w.logger)
processTransaction(ctx, w.chainID, evmTx, w.methodsByAddress, w.repository, w.logger)
lastBlockNumberHex = tx.BlockNumber
}