Skip to content

Commit

Permalink
Refactor so wrappedNativeAddress is passed by CLI
Browse files Browse the repository at this point in the history
  • Loading branch information
johnsaigle committed Dec 16, 2024
1 parent 845b428 commit 9cce4ec
Show file tree
Hide file tree
Showing 8 changed files with 47 additions and 38 deletions.
2 changes: 2 additions & 0 deletions devnet/tx-verifier.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ spec:
mountPath: /logs
command:
["/bin/sh", "-c"]
# See `ethereum/.env.test` and related shell scripts for how these values are configured in localnet testing.
args:
- |
exec /guardiand \
Expand All @@ -31,6 +32,7 @@ spec:
--rpcUrl ws://eth-devnet:8545 \
--coreContract 0xC89Ce4735882C9F0f0FE26686c53074E09B0D550 \
--tokenContract 0x0290FB167208Af455bB137780163b7B7a9a10C16 \
--wrappedNativeContract 0xDDb64fE46a91D46ee29420539FC25FD07c5FEa3E \
--logLevel=info \
2> /logs/error.log \
- name: tx-verifier-monitor
Expand Down
4 changes: 2 additions & 2 deletions node/Makefile
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
.PHONY test
.PHONY: test
test:
# Use this command on amd64 systems
go test -v -ldflags '-extldflags "-Wl,--allow-multiple-definition" ' ./...

.PHONY test-arm64
.PHONY: test-arm64
test-arm64:
# Use this command on arm64, otherwise you will encounter linker errors.
# It's not perfect: it will fail due to 'undefined symbols' errors
Expand Down
22 changes: 8 additions & 14 deletions node/cmd/transfer-verifier/transfer-verifier-evm.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ var (
evmCoreContract *string
// Contract address of the token bridge.
evmTokenBridgeContract *string
// Contract address of the wrapped native asset, e.g. WETH for Ethereum
wrappedNativeContract *string
// Height difference between pruning windows (in blocks).
pruneHeightDelta *uint64
)
Expand All @@ -41,11 +43,13 @@ func init() {
evmRpc = TransferVerifierCmdEvm.Flags().String("rpcUrl", "ws://localhost:8546", "RPC url")
evmCoreContract = TransferVerifierCmdEvm.Flags().String("coreContract", "", "core bridge address")
evmTokenBridgeContract = TransferVerifierCmdEvm.Flags().String("tokenContract", "", "token bridge")
evmTokenBridgeContract = TransferVerifierCmdEvm.Flags().String("wrappedNativeContract", "", "wrapped native address (e.g. WETH on Ethereum)")
pruneHeightDelta = TransferVerifierCmdEvm.Flags().Uint64("pruneHeightDelta", 10, "The number of blocks for which to retain transaction receipts. Defaults to 10 blocks.")

TransferVerifierCmd.MarkFlagRequired("rpcUrl")
TransferVerifierCmd.MarkFlagRequired("coreContract")
TransferVerifierCmd.MarkFlagRequired("tokenContract")
TransferVerifierCmd.MarkFlagRequired("wrappedNativeContract")
}

// Note: logger.Error should be reserved only for conditions that break the
Expand Down Expand Up @@ -93,19 +97,10 @@ func runTransferVerifierEvm(cmd *cobra.Command, args []string) {

logger.Info("Starting EVM transfer verifier")

// Verify CLI parameters
if *evmRpc == "" || *evmCoreContract == "" || *evmTokenBridgeContract == "" {
logger.Fatal(
"One or more CLI parameters are empty",
zap.String("rpc", *evmRpc),
zap.String("coreContract", *evmCoreContract),
zap.String("tokenContract", *evmTokenBridgeContract),
)
}

logger.Debug("EVM rpc connection", zap.String("url", *evmRpc))
logger.Debug("EVM core contract", zap.String("address", *evmCoreContract))
logger.Debug("EVM token bridge contract", zap.String("address", *evmTokenBridgeContract))
logger.Debug("EVM wrapped native asset contract", zap.String("address", *wrappedNativeContract))
logger.Debug("EVM prune config",
zap.Uint64("height delta", *pruneHeightDelta))

Expand All @@ -124,10 +119,9 @@ func runTransferVerifierEvm(cmd *cobra.Command, args []string) {
transferVerifier, err := txverifier.NewTransferVerifier(
evmConnector,
&txverifier.TVAddresses{
CoreBridgeAddr: common.HexToAddress(*evmCoreContract),
TokenBridgeAddr: common.HexToAddress(*evmTokenBridgeContract),
// TODO: should be a CLI parameter so that we could support other EVM chains
WrappedNativeAddr: txverifier.WETH_ADDRESS,
CoreBridgeAddr: common.HexToAddress(*evmCoreContract),
TokenBridgeAddr: common.HexToAddress(*evmTokenBridgeContract),
WrappedNativeAddr: common.HexToAddress(*wrappedNativeContract),
},
*pruneHeightDelta,
logger,
Expand Down
30 changes: 19 additions & 11 deletions node/pkg/transfer-verifier/transfer-verifier-evm-structs.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,10 +51,8 @@ var (
// Fixed addresses
var (
// https://etherscan.io/token/0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2
WETH_ADDRESS = common.HexToAddress("c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2")
ZERO_ADDRESS = common.BytesToAddress([]byte{0x00})
ZERO_ADDRESS_VAA = VAAAddrFrom(ZERO_ADDRESS)
NATIVE_CHAIN_ID vaa.ChainID = 2
ZERO_ADDRESS = common.BytesToAddress([]byte{0x00})
ZERO_ADDRESS_VAA = VAAAddrFrom(ZERO_ADDRESS)
)

// EVM chain constants
Expand Down Expand Up @@ -83,6 +81,8 @@ type TVAddresses struct {
// TransferVerifier contains configuration values for verifying transfers.
type TransferVerifier[E evmClient, C connector] struct {
Addresses *TVAddresses
// The chainId being monitored
chain vaa.ChainID
// Wormhole connector for wrapping contract-specific interactions
logger zap.Logger
// Corresponds to the connector interface for EVM chains
Expand Down Expand Up @@ -114,15 +114,19 @@ type TransferVerifier[E evmClient, C connector] struct {

func NewTransferVerifier(connector connectors.Connector, tvAddrs *TVAddresses, pruneHeightDelta uint64, logger *zap.Logger) (*TransferVerifier[*ethClient.Client, connectors.Connector], error) {
// Retrieve the NATIVE_CHAIN_ID from the connector.
chainId, err := connector.Client().ChainID(context.Background())
chainIdFromClient, err := connector.Client().ChainID(context.Background())
if err != nil {
return nil, fmt.Errorf("failed to get chain ID: %w", err)
}

NATIVE_CHAIN_ID = vaa.ChainID(chainId.Uint64())
chainId, chainIdConvertErr := vaa.ChainIDFromString(chainIdFromClient.String())
if chainIdConvertErr != nil {
return nil, fmt.Errorf("Failed to parse chainId from string returned by connector client: %w", chainIdConvertErr)
}

return &TransferVerifier[*ethClient.Client, connectors.Connector]{
Addresses: tvAddrs,
chain: chainId,
logger: *logger,
evmConnector: connector,
client: connector.Client(),
Expand Down Expand Up @@ -291,7 +295,8 @@ func (d *NativeDeposit) String() string {
)
}

func DepositFrom(log *types.Log) (deposit *NativeDeposit, err error) {
// DepositFromLog() creates a NativeDeposit struct given a log and chain ID.
func DepositFromLog(log *types.Log, chainId vaa.ChainID) (deposit *NativeDeposit, err error) {
dest, amount := parseWNativeDepositEvent(log.Topics, log.Data)

if amount == nil {
Expand All @@ -300,7 +305,7 @@ func DepositFrom(log *types.Log) (deposit *NativeDeposit, err error) {

deposit = &NativeDeposit{
TokenAddress: log.Address,
TokenChain: NATIVE_CHAIN_ID, // always equal to Ethereum for native deposits
TokenChain: chainId,
Receiver: dest,
Amount: amount,
}
Expand Down Expand Up @@ -373,7 +378,8 @@ func (t *ERC20Transfer) String() string {
)
}

func ERC20TransferFrom(log *types.Log) (transfer *ERC20Transfer, err error) {
// ERC20TransferFromLog() creates an ERC20Transfer struct given a log and chain ID.
func ERC20TransferFromLog(log *types.Log, chainId vaa.ChainID) (transfer *ERC20Transfer, err error) {
from, to, amount := parseERC20TransferEvent(log.Topics, log.Data)

// Ensure From address is not empty. The To address is allowed to be empty when funds are being burned.
Expand All @@ -387,8 +393,8 @@ func ERC20TransferFrom(log *types.Log) (transfer *ERC20Transfer, err error) {

transfer = &ERC20Transfer{
TokenAddress: log.Address,
// Initially, set Token's chain to this chain. This will be updated by making an RPC call later.
TokenChain: NATIVE_CHAIN_ID,
// Initially, set Token's chain to the chain being monitored. This will be updated by making an RPC call later.
TokenChain: chainId,
From: from,
To: to,
Amount: amount,
Expand Down Expand Up @@ -663,6 +669,8 @@ func (tv *TransferVerifier[ethClient, connector]) unwrapIfWrapped(
return tokenAddressNative, nil
}

// chainId() calls the chainId() function on the contract at the supplied address. To get the chain ID being monitored
// by the Transfer Verifier, use the field TransferVerifier.chain.
func (tv *TransferVerifier[ethClient, Connector]) chainId(
addr common.Address,
) (vaa.ChainID, error) {
Expand Down
12 changes: 9 additions & 3 deletions node/pkg/transfer-verifier/transfer-verifier-evm-structs_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,12 @@ import (
"github.com/wormhole-foundation/wormhole/sdk/vaa"
)

var (
// Mainnet values
WETH_ADDRESS = common.HexToAddress("c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2")
NATIVE_CHAIN_ID vaa.ChainID = 2
)

func TestRelevantDeposit(t *testing.T) {
t.Parallel()

Expand Down Expand Up @@ -749,7 +755,7 @@ func TestDepositFrom(t *testing.T) {
t.Run(name, func(t *testing.T) {
t.Parallel() // marks each test case as capable of running in parallel with each other

deposit, err := DepositFrom(&test.log)
deposit, err := DepositFromLog(&test.log, NATIVE_CHAIN_ID)
assert.Equal(t, test.expected, deposit)
require.NoError(t, err)
})
Expand Down Expand Up @@ -816,7 +822,7 @@ func TestParseERC20TransferFrom(t *testing.T) {
t.Run(name, func(t *testing.T) {
t.Parallel() // marks each test case as capable of running in parallel with each other

transfer, err := ERC20TransferFrom(&test.log)
transfer, err := ERC20TransferFromLog(&test.log, NATIVE_CHAIN_ID)
assert.Equal(t, test.expected, transfer)
require.NoError(t, err)
})
Expand Down Expand Up @@ -846,7 +852,7 @@ func TestParseERC20TransferFrom(t *testing.T) {
t.Run(name, func(t *testing.T) {
t.Parallel() // marks each test case as capable of running in parallel with each other

transfer, err := ERC20TransferFrom(&test.log)
transfer, err := ERC20TransferFromLog(&test.log, NATIVE_CHAIN_ID)
require.Error(t, err)
assert.Nil(t, transfer)
})
Expand Down
6 changes: 3 additions & 3 deletions node/pkg/transfer-verifier/transfer-verifier-evm.go
Original file line number Diff line number Diff line change
Expand Up @@ -286,7 +286,7 @@ func (tv *TransferVerifier[evmClient, connector]) ParseReceipt(
for _, log := range receipt.Logs {
switch log.Topics[0] {
case common.HexToHash(EVENTHASH_WETH_DEPOSIT):
deposit, depositErr := DepositFrom(log)
deposit, depositErr := DepositFromLog(log, tv.chain)

if depositErr != nil {
tv.logger.Error("error when parsing Deposit from log",
Expand All @@ -300,7 +300,7 @@ func (tv *TransferVerifier[evmClient, connector]) ParseReceipt(
tv.logger.Debug("adding deposit", zap.String("deposit", deposit.String()))
deposits = append(deposits, deposit)
case common.HexToHash(EVENTHASH_ERC20_TRANSFER):
transfer, transferErr := ERC20TransferFrom(log)
transfer, transferErr := ERC20TransferFromLog(log, tv.chain)

if transferErr != nil {
tv.logger.Error("error when parsing ERC20 Transfer from log",
Expand Down Expand Up @@ -586,7 +586,7 @@ func (tv *TransferVerifier[ethClient, connector]) fetchLogMessageDetails(details

// If the token was minted on the chain monitored by this program, set its OriginAddress equal to OriginAddressRaw.
var originAddress common.Address
if details.TokenChain == NATIVE_CHAIN_ID {
if details.TokenChain == tv.chain {
// The token was minted on this chain.
originAddress = common.BytesToAddress(details.OriginAddressRaw)
tv.logger.Debug("token is native. no need to unwrap",
Expand Down
6 changes: 1 addition & 5 deletions node/pkg/transfer-verifier/transfer-verifier-evm_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ func setup() *mockConnections {
TokenBridgeAddr: tokenBridgeAddr,
WrappedNativeAddr: nativeAddr,
},
chain: NATIVE_CHAIN_ID,
evmConnector: &mockConnector{},
client: &mockClient{},
logger: *logger,
Expand Down Expand Up @@ -187,7 +188,6 @@ func TestParseReceiptHappyPath(t *testing.T) {
},
}
for name, test := range tests {
test := test // NOTE: uncomment for Go < 1.22, see /doc/faq#closures_and_goroutines
t.Run(name, func(t *testing.T) {

transferReceipt, err := mocks.transferVerifier.ParseReceipt(test.receipt)
Expand Down Expand Up @@ -316,7 +316,6 @@ func TestParseReceiptErrors(t *testing.T) {
// },
}
for name, test := range tests {
test := test // NOTE: uncomment for Go < 1.22, see /doc/faq#closures_and_goroutines
t.Run(name, func(t *testing.T) {

receipt, err := mocks.transferVerifier.ParseReceipt(test.receipt)
Expand Down Expand Up @@ -373,7 +372,6 @@ func TestParseERC20TransferEvent(t *testing.T) {
}

for name, test := range tests {
test := test // NOTE: uncomment for Go < 1.22, see /doc/faq#closures_and_goroutines
t.Run(name, func(t *testing.T) {
t.Parallel() // marks each test case as capable of running in parallel with each other

Expand Down Expand Up @@ -430,7 +428,6 @@ func TestParseWNativeDepositEvent(t *testing.T) {
}

for name, test := range tests {
test := test // NOTE: uncomment for Go < 1.22, see /doc/faq#closures_and_goroutines
t.Run(name, func(t *testing.T) {
t.Parallel() // marks each test case as capable of running in parallel with each other

Expand Down Expand Up @@ -673,7 +670,6 @@ func TestProcessReceipt(t *testing.T) {
}

for name, test := range tests {
test := test // NOTE: uncomment for Go < 1.22, see /doc/faq#closures_and_goroutines
t.Run(name, func(t *testing.T) {

summary, err := mocks.transferVerifier.ProcessReceipt(test.transferReceipt)
Expand Down
3 changes: 3 additions & 0 deletions scripts/transfer-verifier-localnet.sh
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,11 @@ set -xeuo pipefail
# mainnet
# CORE_CONTRACT="0x98f3c9e6E3fAce36bAAd05FE09d375Ef1464288B"
# TOKEN_BRIDGE_CONTRACT="0x3ee18B2214AFF97000D974cf647E7C347E8fa585"
# WRAPPED_NATIVE_CONTRACT="0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2"
# devnet
CORE_CONTRACT="0xC89Ce4735882C9F0f0FE26686c53074E09B0D550"
TOKEN_BRIDGE_CONTRACT="0x0290FB167208Af455bB137780163b7B7a9a10C16"
WRAPPED_NATIVE_CONTRACT="0xDDb64fE46a91D46ee29420539FC25FD07c5FEa3E"

# Needs to be websockets so that the eth connector can get notifications
ETH_RPC_DEVNET="ws://localhost:8545" # from Tilt, via Anvil
Expand All @@ -25,4 +27,5 @@ LOG_LEVEL="debug"
--rpcUrl "${RPC}" \
--coreContract "${CORE_CONTRACT}" \
--tokenContract "${TOKEN_BRIDGE_CONTRACT}" \
--wrappedNativeContract "${WRAPPED_NATIVE_CONTRACT}" \
--logLevel "${LOG_LEVEL}"

0 comments on commit 9cce4ec

Please sign in to comment.