diff --git a/config/config.go b/config/config.go index d478c8a8..a8cf92bd 100644 --- a/config/config.go +++ b/config/config.go @@ -6,9 +6,7 @@ package config import ( "crypto/ecdsa" "encoding/hex" - "errors" "fmt" - "math/big" "net/url" "os" @@ -28,10 +26,6 @@ const ( cChainIdentifierString = "C" ) -var ( - ErrInvalidPrivateKey = errors.New("failed to set private key string") -) - type MessageProtocolConfig struct { MessageFormat string `mapstructure:"message-format" json:"message-format"` Settings map[string]interface{} `mapstructure:"settings" json:"settings"` @@ -399,17 +393,12 @@ func (s *SourceSubnet) GetNodeWSEndpoint() string { // Get the private key and derive the wallet address from a relayer's configured private key for a given destination subnet. func (s *DestinationSubnet) GetRelayerAccountInfo() (*ecdsa.PrivateKey, common.Address, error) { - var ok bool - pk := new(ecdsa.PrivateKey) - pk.D, ok = new(big.Int).SetString(s.AccountPrivateKey, 16) - if !ok { - return nil, common.Address{}, ErrInvalidPrivateKey - } - pk.PublicKey.Curve = crypto.S256() - pk.PublicKey.X, pk.PublicKey.Y = pk.PublicKey.Curve.ScalarBaseMult(pk.D.Bytes()) - pkBytes := pk.PublicKey.X.Bytes() - pkBytes = append(pkBytes, pk.PublicKey.Y.Bytes()...) - return pk, common.BytesToAddress(crypto.Keccak256(pkBytes)), nil + pk, err := crypto.HexToECDSA(s.AccountPrivateKey) + if err != nil { + return nil, common.Address{}, err + } + + return pk, crypto.PubkeyToAddress(pk.PublicKey), nil } // diff --git a/config/config_test.go b/config/config_test.go index 2c53cd12..7e241e3c 100644 --- a/config/config_test.go +++ b/config/config_test.go @@ -6,6 +6,7 @@ package config import ( "crypto/ecdsa" "encoding/json" + "errors" "fmt" "math/big" "os" @@ -245,7 +246,7 @@ func TestGetRelayerAccountInfo(t *testing.T) { D: big.NewInt(-5567472993773453273), }, addr: common.HexToAddress("0x8db97C7cEcE249c2b98bDC0226Cc4C2A57BF52FC"), - err: ErrInvalidPrivateKey, + err: errors.New("invalid hex character 'x' in private key"), }, }, { @@ -258,7 +259,7 @@ func TestGetRelayerAccountInfo(t *testing.T) { D: big.NewInt(-5567472993773453273), }, addr: common.HexToAddress("0x8db97C7cEcE249c2b98bDC0226Cc4C2A57BF52FC"), - err: ErrInvalidPrivateKey, + err: errors.New("invalid hex character 'i' in private key"), }, }, } diff --git a/go.mod b/go.mod index fcd08a44..f8baafed 100644 --- a/go.mod +++ b/go.mod @@ -8,8 +8,8 @@ require ( github.com/ava-labs/subnet-evm v0.5.10 github.com/ava-labs/teleporter v0.0.0-20240108172200-f03f526e5312 github.com/ethereum/go-ethereum v1.12.0 - github.com/onsi/ginkgo/v2 v2.14.0 - github.com/onsi/gomega v1.30.0 + github.com/onsi/ginkgo/v2 v2.15.0 + github.com/onsi/gomega v1.31.0 github.com/pkg/errors v0.9.1 github.com/prometheus/client_golang v1.18.0 github.com/spf13/pflag v1.0.5 diff --git a/go.sum b/go.sum index 7433696b..72a0668c 100644 --- a/go.sum +++ b/go.sum @@ -451,16 +451,16 @@ github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vv github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU= github.com/onsi/ginkgo/v2 v2.1.3/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c= -github.com/onsi/ginkgo/v2 v2.14.0 h1:vSmGj2Z5YPb9JwCWT6z6ihcUvDhuXLc3sJiqd3jMKAY= -github.com/onsi/ginkgo/v2 v2.14.0/go.mod h1:JkUdW7JkN0V6rFvsHcJ478egV3XH9NxpD27Hal/PhZw= +github.com/onsi/ginkgo/v2 v2.15.0 h1:79HwNRBAZHOEwrczrgSOPy+eFTTlIGELKy5as+ClttY= +github.com/onsi/ginkgo/v2 v2.15.0/go.mod h1:HlxMHtYF57y6Dpf+mc5529KKmSq9h2FpCF+/ZkwUxKM= github.com/onsi/gomega v1.4.1/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY= github.com/onsi/gomega v1.19.0/go.mod h1:LY+I3pBVzYsTBU1AnDwOSxaYi9WoWiqgwooUqq9yPro= -github.com/onsi/gomega v1.30.0 h1:hvMK7xYz4D3HapigLTeGdId/NcfQx1VHMJc60ew99+8= -github.com/onsi/gomega v1.30.0/go.mod h1:9sxs+SwGrKI0+PWe4Fxa9tFQQBG5xSsSbMXOI8PPpoQ= +github.com/onsi/gomega v1.31.0 h1:54UJxxj6cPInHS3a35wm6BK/F9nHYueZ1NVujHDrnXE= +github.com/onsi/gomega v1.31.0/go.mod h1:DW9aCi7U6Yi40wNVAvT6kzFnEVEI5n3DloYBiKiT6zk= github.com/otiai10/copy v1.11.0 h1:OKBD80J/mLBrwnzXqGtFCzprFSGioo30JcmR4APsNwc= github.com/otiai10/copy v1.11.0/go.mod h1:rSaLseMUsZFFbsFGc7wCJnnkTAvdc5L6VWxPE4308Ww= github.com/otiai10/mint v1.5.1 h1:XaPLeE+9vGbuyEHem1JNk3bYc7KKqyI/na0/mLd/Kks= diff --git a/messages/message_manager.go b/messages/message_manager.go index 908ccc6d..0dc85aeb 100644 --- a/messages/message_manager.go +++ b/messages/message_manager.go @@ -35,14 +35,15 @@ type MessageManager interface { // Note that DestinationClients may be invoked concurrently by many MessageManagers, so it is assumed that they are implemented in a thread-safe way func NewMessageManager( logger logging.Logger, - messageProtocolAddress common.Hash, + messageProtocolAddress common.Address, messageProtocolConfig config.MessageProtocolConfig, destinationClients map[ids.ID]vms.DestinationClient, ) (MessageManager, error) { format := messageProtocolConfig.MessageFormat switch config.ParseMessageProtocol(format) { case config.TELEPORTER: - return teleporter.NewMessageManager(logger, + return teleporter.NewMessageManager( + logger, messageProtocolAddress, messageProtocolConfig, destinationClients, diff --git a/messages/teleporter/message_manager.go b/messages/teleporter/message_manager.go index f5187501..6fae140d 100644 --- a/messages/teleporter/message_manager.go +++ b/messages/teleporter/message_manager.go @@ -29,7 +29,7 @@ const ( type messageManager struct { messageConfig Config - protocolAddress common.Hash + protocolAddress common.Address // We parse teleporter messages in ShouldSendMessage, cache them to be reused in SendMessage // The cache is keyed by the Warp message ID, NOT the Teleporter message ID @@ -41,7 +41,7 @@ type messageManager struct { func NewMessageManager( logger logging.Logger, - messageProtocolAddress common.Hash, + messageProtocolAddress common.Address, messageProtocolConfig config.MessageProtocolConfig, destinationClients map[ids.ID]vms.DestinationClient, ) (*messageManager, error) { @@ -284,7 +284,7 @@ func (m *messageManager) getTeleporterMessenger(destinationClient vms.Destinatio } // Get the teleporter messenger contract - teleporterMessenger, err := teleportermessenger.NewTeleporterMessenger(common.BytesToAddress(m.protocolAddress[:]), client) + teleporterMessenger, err := teleportermessenger.NewTeleporterMessenger(m.protocolAddress, client) if err != nil { panic("Failed to get teleporter messenger contract") } diff --git a/messages/teleporter/message_manager_test.go b/messages/teleporter/message_manager_test.go index 2bac41b5..bd436ced 100644 --- a/messages/teleporter/message_manager_test.go +++ b/messages/teleporter/message_manager_test.go @@ -30,7 +30,7 @@ type CallContractChecker struct { } var ( - messageProtocolAddress = common.HexToHash("0xd81545385803bCD83bd59f58Ba2d2c0562387F83") + messageProtocolAddress = common.HexToAddress("0xd81545385803bCD83bd59f58Ba2d2c0562387F83") messageProtocolConfig = config.MessageProtocolConfig{ MessageFormat: config.TELEPORTER.String(), Settings: map[string]interface{}{ @@ -211,13 +211,12 @@ func TestShouldSendMessage(t *testing.T) { ethClient := mock_evm.NewMockClient(ctrl) mockClient.EXPECT().Client().Return(ethClient).Times(test.clientTimes) mockClient.EXPECT().SenderAddress().Return(test.senderAddressResult).Times(test.senderAddressTimes) - protocolAddress := common.BytesToAddress(messageProtocolAddress[:]) if test.calculateMessageIDCall != nil { - messageIDInput := interfaces.CallMsg{From: bind.CallOpts{}.From, To: &protocolAddress, Data: test.calculateMessageIDCall.input} + messageIDInput := interfaces.CallMsg{From: bind.CallOpts{}.From, To: &messageProtocolAddress, Data: test.calculateMessageIDCall.input} ethClient.EXPECT().CallContract(gomock.Any(), gomock.Eq(messageIDInput), gomock.Any()).Return(test.calculateMessageIDCall.expectedResult, nil).Times(test.calculateMessageIDCall.times) } if test.messageReceivedCall != nil { - messageReceivedInput := interfaces.CallMsg{From: bind.CallOpts{}.From, To: &protocolAddress, Data: test.messageReceivedCall.input} + messageReceivedInput := interfaces.CallMsg{From: bind.CallOpts{}.From, To: &messageProtocolAddress, Data: test.messageReceivedCall.input} ethClient.EXPECT().CallContract(gomock.Any(), gomock.Eq(messageReceivedInput), gomock.Any()).Return(test.messageReceivedCall.expectedResult, nil).Times(test.messageReceivedCall.times) } diff --git a/relayer/relayer.go b/relayer/relayer.go index 70b32c2e..6987044e 100644 --- a/relayer/relayer.go +++ b/relayer/relayer.go @@ -53,7 +53,7 @@ type Relayer struct { sourceBlockchainID ids.ID responseChan chan message.InboundMessage contractMessage vms.ContractMessage - messageManagers map[common.Hash]messages.MessageManager + messageManagers map[common.Address]messages.MessageManager logger logging.Logger metrics *MessageRelayerMetrics db database.RelayerDatabase @@ -110,10 +110,10 @@ func NewRelayer( } // Create message managers for each supported message protocol - messageManagers := make(map[common.Hash]messages.MessageManager) - for address, config := range sourceSubnetInfo.MessageContracts { - addressHash := common.HexToHash(address) - messageManager, err := messages.NewMessageManager(logger, addressHash, config, filteredDestinationClients) + messageManagers := make(map[common.Address]messages.MessageManager) + for addressStr, config := range sourceSubnetInfo.MessageContracts { + address := common.HexToAddress(addressStr) + messageManager, err := messages.NewMessageManager(logger, address, config, filteredDestinationClients) if err != nil { logger.Error( "Failed to create message manager", @@ -121,7 +121,7 @@ func NewRelayer( ) return nil, err } - messageManagers[addressHash] = messageManager + messageManagers[address] = messageManager } rpcEndpoint := sourceSubnetInfo.GetNodeRPCEndpoint() diff --git a/vms/evm/subscriber.go b/vms/evm/subscriber.go index b369a200..1f930474 100644 --- a/vms/evm/subscriber.go +++ b/vms/evm/subscriber.go @@ -101,7 +101,8 @@ func (s *subscriber) NewWarpLogInfo(log types.Log, isCatchUpMessage bool) (*vmty } return &vmtypes.WarpLogInfo{ - SourceAddress: log.Topics[1], + // BytesToAddress takes the last 20 bytes of the byte array if it is longer than 20 bytes + SourceAddress: common.BytesToAddress(log.Topics[1][:]), SourceTxID: log.TxHash[:], UnsignedMsgBytes: log.Data, BlockNumber: log.BlockNumber, diff --git a/vms/vmtypes/message_info.go b/vms/vmtypes/message_info.go index 6a004685..d910f116 100644 --- a/vms/vmtypes/message_info.go +++ b/vms/vmtypes/message_info.go @@ -11,7 +11,7 @@ import ( // describes the transaction information emitted by the source chain, // including the Warp Message payload bytes type WarpLogInfo struct { - SourceAddress common.Hash + SourceAddress common.Address SourceTxID []byte UnsignedMsgBytes []byte BlockNumber uint64