From a6d25e901066b0a6921aaa7fd2be300ed8fa512a Mon Sep 17 00:00:00 2001 From: Yukai Date: Thu, 26 May 2022 16:40:12 +0100 Subject: [PATCH 1/9] Add P-Chain address derivation support --- cmd/server/main.go | 21 ++++++++++++------ mapper/types.go | 8 +++++-- service/helper.go | 38 ++++++++++++++++++++++++++++++--- service/service_construction.go | 37 ++++++++++++++++++++++++++------ 4 files changed, 86 insertions(+), 18 deletions(-) diff --git a/cmd/server/main.go b/cmd/server/main.go index 9d143c48..2cffb38a 100644 --- a/cmd/server/main.go +++ b/cmd/server/main.go @@ -111,17 +111,24 @@ func main() { cfg.NetworkName = networkName } - network := &types.NetworkIdentifier{ + networkP := &types.NetworkIdentifier{ + Blockchain: service.BlockchainName, + Network: cfg.NetworkName, + SubNetworkIdentifier: &types.SubNetworkIdentifier{ + Network: "P", + }, + } + networkC := &types.NetworkIdentifier{ Blockchain: service.BlockchainName, Network: cfg.NetworkName, } asserter, err := asserter.NewServer( - mapper.OperationTypes, // supported operation types - true, // historical balance lookup - []*types.NetworkIdentifier{network}, // supported networks - []string{}, // call methods - false, // mempool coins + mapper.OperationTypes, // supported operation types + true, // historical balance lookup + []*types.NetworkIdentifier{networkP, networkC}, // supported networks + []string{}, // call methods + false, // mempool coins ) if err != nil { log.Fatal("server asserter init error:", err) @@ -130,7 +137,7 @@ func main() { serviceConfig := &service.Config{ Mode: cfg.Mode, ChainID: big.NewInt(cfg.ChainID), - NetworkID: network, + NetworkID: networkC, GenesisBlockHash: cfg.GenesisBlockHash, AvaxAssetID: assetID, AP5Activation: AP5Activation, diff --git a/mapper/types.go b/mapper/types.go index 542a6934..f3f3f989 100644 --- a/mapper/types.go +++ b/mapper/types.go @@ -2,21 +2,25 @@ package mapper import ( "github.com/ava-labs/coreth/params" - "github.com/ethereum/go-ethereum/common" - "github.com/coinbase/rosetta-sdk-go/types" + "github.com/ethereum/go-ethereum/common" ) const ( MainnetChainID = 43114 MainnetAssetID = "FvwEAhmxKfeiG8SnEvq42hc6whRyY3EFYAvebMqDNDGCgxN5Z" + MainnetNetwork = "Mainnet" FujiChainID = 43113 FujiAssetID = "U8iRqJoiJm8xZHAacmvYyZVwqQx6uDNtQeP3CQ6fcgQk3JqnK" + FujiNetwork = "Fuji" ContractAddressMetadata = "contractAddress" IndexTransferredMetadata = "indexTransferred" + PChainNetworkIdentifier = "P" + PChainIDAlias = "P" + OpCall = "CALL" OpFee = "FEE" OpCreate = "CREATE" diff --git a/service/helper.go b/service/helper.go index bb89bdfe..59456643 100644 --- a/service/helper.go +++ b/service/helper.go @@ -6,11 +6,13 @@ import ( "math/big" "strings" - "github.com/ava-labs/avalanche-rosetta/client" - "github.com/coinbase/rosetta-sdk-go/types" - + "github.com/ava-labs/avalanchego/utils/constants" ethtypes "github.com/ava-labs/coreth/core/types" + "github.com/coinbase/rosetta-sdk-go/types" ethcommon "github.com/ethereum/go-ethereum/common" + + "github.com/ava-labs/avalanche-rosetta/client" + "github.com/ava-labs/avalanche-rosetta/mapper" ) const ( @@ -104,3 +106,33 @@ func ChecksumAddress(address string) (string, bool) { return addr.Address().Hex(), true } + +// isPChain checks network identifier to make sure sub-network identifier set to "P" +func isPChain(networkIdentifier *types.NetworkIdentifier) bool { + if networkIdentifier.SubNetworkIdentifier != nil && + networkIdentifier.SubNetworkIdentifier.Network == mapper.PChainNetworkIdentifier { + return true + } + + return false +} + +// getAliasAndHRP fetches chain id alias and hrp for address formatting. +// Right now only P chain id alias is supported +func getAliasAndHRP(networkIdentifier *types.NetworkIdentifier) (string, string, *types.Error) { + var chainIDAlias, hrp string + if !isPChain(networkIdentifier) { + return "", "", makeError(errNotImplemented.Code, "only support P chain alias", false) + } + chainIDAlias = mapper.PChainIDAlias + switch networkIdentifier.Network { + case mapper.FujiNetwork: + hrp = constants.GetHRP(constants.FujiID) + case mapper.MainnetNetwork: + hrp = constants.GetHRP(constants.MainnetID) + default: + return "", "", makeError(errNotImplemented.Code, "can't recognize network", false) + } + + return chainIDAlias, hrp, nil +} diff --git a/service/service_construction.go b/service/service_construction.go index 61d6c88b..772161e8 100644 --- a/service/service_construction.go +++ b/service/service_construction.go @@ -6,20 +6,21 @@ import ( "fmt" "math/big" + "github.com/ava-labs/avalanchego/utils/crypto" + "github.com/ava-labs/avalanchego/utils/formatting/address" + ethtypes "github.com/ava-labs/coreth/core/types" + "github.com/ava-labs/coreth/interfaces" "github.com/coinbase/rosetta-sdk-go/parser" "github.com/coinbase/rosetta-sdk-go/server" "github.com/coinbase/rosetta-sdk-go/types" "github.com/coinbase/rosetta-sdk-go/utils" - "golang.org/x/crypto/sha3" - - ethtypes "github.com/ava-labs/coreth/core/types" - "github.com/ava-labs/coreth/interfaces" ethcommon "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/hexutil" + ethcrypto "github.com/ethereum/go-ethereum/crypto" + "golang.org/x/crypto/sha3" "github.com/ava-labs/avalanche-rosetta/client" "github.com/ava-labs/avalanche-rosetta/mapper" - "github.com/ethereum/go-ethereum/common/hexutil" - ethcrypto "github.com/ethereum/go-ethereum/crypto" ) const ( @@ -222,6 +223,30 @@ func (s ConstructionService) ConstructionDerive( ctx context.Context, req *types.ConstructionDeriveRequest, ) (*types.ConstructionDeriveResponse, *types.Error) { + if isPChain(req.NetworkIdentifier) { + fac := crypto.FactorySECP256K1R{} + pub, err := fac.ToPublicKey(req.PublicKey.Bytes) + if err != nil { + return nil, wrapError(errInvalidInput, err) + } + + chainIDAlias, hrp, getErr := getAliasAndHRP(req.NetworkIdentifier) + if err != nil { + return nil, getErr + } + + addr, err := address.Format(chainIDAlias, hrp, pub.Address().Bytes()) + if err != nil { + return nil, wrapError(errInvalidInput, err) + } + + return &types.ConstructionDeriveResponse{ + AccountIdentifier: &types.AccountIdentifier{ + Address: addr, + }, + }, nil + } + if req.PublicKey == nil { return nil, wrapError(errInvalidInput, "public key is not provided") } From 93d0551ac15eb12b7fa7765a59a7a842eaf25957 Mon Sep 17 00:00:00 2001 From: Yukai Date: Thu, 26 May 2022 16:50:30 +0100 Subject: [PATCH 2/9] Replace P chain network identifier --- cmd/server/main.go | 2 +- cmd/test/main.go | 60 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 61 insertions(+), 1 deletion(-) create mode 100644 cmd/test/main.go diff --git a/cmd/server/main.go b/cmd/server/main.go index 2cffb38a..cd9a48df 100644 --- a/cmd/server/main.go +++ b/cmd/server/main.go @@ -115,7 +115,7 @@ func main() { Blockchain: service.BlockchainName, Network: cfg.NetworkName, SubNetworkIdentifier: &types.SubNetworkIdentifier{ - Network: "P", + Network: mapper.PChainNetworkIdentifier, }, } networkC := &types.NetworkIdentifier{ diff --git a/cmd/test/main.go b/cmd/test/main.go new file mode 100644 index 00000000..c0bffc0f --- /dev/null +++ b/cmd/test/main.go @@ -0,0 +1,60 @@ +package main + +// import ( +// "context" +// "crypto/tls" +// "fmt" +// "net" +// "net/http" +// "time" + +// rosettaclient "github.cbhq.net/c3/keychain/pkg/rosetta" +// "github.com/coinbase/rosetta-sdk-go/types" + +// "github.com/ava-labs/avalanchego/utils/crypto" +// ) + +// func main() { +// fmt.Println("test") +// rosettaClient := newRosettaClient() +// factory := crypto.FactorySECP256K1R{} +// priv, nil := factory.NewPrivateKey() +// res, err := rosettaClient.DeriveFromPublicKey(context.Background(), &types.ConstructionDeriveRequest{ +// NetworkIdentifier: &types.NetworkIdentifier{ +// Blockchain: "Avalanche", +// Network: "Fuji", +// SubNetworkIdentifier: &types.SubNetworkIdentifier{ +// Network: "P", +// }, +// }, +// PublicKey: &types.PublicKey{ +// Bytes: priv.PublicKey().Bytes(), +// CurveType: types.Secp256r1, +// }, +// }) +// if err != nil { +// panic(err) +// } +// fmt.Println(res) +// } + +// func newRosettaClient() *rosettaclient.Client { +// var ( +// dialer = &net.Dialer{Timeout: 10} +// // #nosec G402 +// tlsConfig = &tls.Config{InsecureSkipVerify: true} +// url = "https://localhost:8080" +// httpClient = &http.Client{ +// Timeout: 10 * time.Second, +// Transport: &http.Transport{ +// Dial: dialer.Dial, +// TLSHandshakeTimeout: 10 * time.Second, +// TLSClientConfig: tlsConfig, +// }, +// } +// ) + +// return rosettaclient.NewClient(httpClient, url, false) +// } + +// // curl --data '{"network_identifier":{"blockchain":"Avalanche","network":"Fuji", "sub_network_identifier":{"network":"P"}},"public_key":{"hex_bytes":"02d95fcfa4321a1291bd8b387635fe0c3b9fa6d243153387fbe298a467b0c2ab32","curve_type":"secp256r1"}}' --header "Content-Type: application/json" --request POST 0.0.0.0:8080/construction/derive | jq . From 813304e75b0e3f376e0f2914e73327157a527d51 Mon Sep 17 00:00:00 2001 From: Yukai Date: Thu, 26 May 2022 16:51:48 +0100 Subject: [PATCH 3/9] remove test file --- cmd/test/main.go | 60 ------------------------------------------------ 1 file changed, 60 deletions(-) delete mode 100644 cmd/test/main.go diff --git a/cmd/test/main.go b/cmd/test/main.go deleted file mode 100644 index c0bffc0f..00000000 --- a/cmd/test/main.go +++ /dev/null @@ -1,60 +0,0 @@ -package main - -// import ( -// "context" -// "crypto/tls" -// "fmt" -// "net" -// "net/http" -// "time" - -// rosettaclient "github.cbhq.net/c3/keychain/pkg/rosetta" -// "github.com/coinbase/rosetta-sdk-go/types" - -// "github.com/ava-labs/avalanchego/utils/crypto" -// ) - -// func main() { -// fmt.Println("test") -// rosettaClient := newRosettaClient() -// factory := crypto.FactorySECP256K1R{} -// priv, nil := factory.NewPrivateKey() -// res, err := rosettaClient.DeriveFromPublicKey(context.Background(), &types.ConstructionDeriveRequest{ -// NetworkIdentifier: &types.NetworkIdentifier{ -// Blockchain: "Avalanche", -// Network: "Fuji", -// SubNetworkIdentifier: &types.SubNetworkIdentifier{ -// Network: "P", -// }, -// }, -// PublicKey: &types.PublicKey{ -// Bytes: priv.PublicKey().Bytes(), -// CurveType: types.Secp256r1, -// }, -// }) -// if err != nil { -// panic(err) -// } -// fmt.Println(res) -// } - -// func newRosettaClient() *rosettaclient.Client { -// var ( -// dialer = &net.Dialer{Timeout: 10} -// // #nosec G402 -// tlsConfig = &tls.Config{InsecureSkipVerify: true} -// url = "https://localhost:8080" -// httpClient = &http.Client{ -// Timeout: 10 * time.Second, -// Transport: &http.Transport{ -// Dial: dialer.Dial, -// TLSHandshakeTimeout: 10 * time.Second, -// TLSClientConfig: tlsConfig, -// }, -// } -// ) - -// return rosettaclient.NewClient(httpClient, url, false) -// } - -// // curl --data '{"network_identifier":{"blockchain":"Avalanche","network":"Fuji", "sub_network_identifier":{"network":"P"}},"public_key":{"hex_bytes":"02d95fcfa4321a1291bd8b387635fe0c3b9fa6d243153387fbe298a467b0c2ab32","curve_type":"secp256r1"}}' --header "Content-Type: application/json" --request POST 0.0.0.0:8080/construction/derive | jq . From 1a9db6f69471703d5862979f00c17e7e9f94b71c Mon Sep 17 00:00:00 2001 From: Yukai Date: Tue, 7 Jun 2022 11:25:31 -0700 Subject: [PATCH 4/9] Add test case --- service/helper.go | 3 ++- service/service_construction.go | 2 +- service/service_construction_test.go | 27 +++++++++++++++++++++++++++ 3 files changed, 30 insertions(+), 2 deletions(-) diff --git a/service/helper.go b/service/helper.go index 59456643..20d98b3a 100644 --- a/service/helper.go +++ b/service/helper.go @@ -109,7 +109,8 @@ func ChecksumAddress(address string) (string, bool) { // isPChain checks network identifier to make sure sub-network identifier set to "P" func isPChain(networkIdentifier *types.NetworkIdentifier) bool { - if networkIdentifier.SubNetworkIdentifier != nil && + if networkIdentifier != nil && + networkIdentifier.SubNetworkIdentifier != nil && networkIdentifier.SubNetworkIdentifier.Network == mapper.PChainNetworkIdentifier { return true } diff --git a/service/service_construction.go b/service/service_construction.go index 772161e8..b99638a1 100644 --- a/service/service_construction.go +++ b/service/service_construction.go @@ -231,7 +231,7 @@ func (s ConstructionService) ConstructionDerive( } chainIDAlias, hrp, getErr := getAliasAndHRP(req.NetworkIdentifier) - if err != nil { + if getErr != nil { return nil, getErr } diff --git a/service/service_construction_test.go b/service/service_construction_test.go index 065b30da..d8be8a61 100644 --- a/service/service_construction_test.go +++ b/service/service_construction_test.go @@ -285,6 +285,33 @@ func TestConstructionDerive(t *testing.T) { resp.AccountIdentifier.Address, ) }) + + t.Run("p-chain address", func(t *testing.T) { + src := "02e0d4392cfa224d4be19db416b3cf62e90fb2b7015e7b62a95c8cb490514943f6" + b, _ := hex.DecodeString(src) + + resp, err := service.ConstructionDerive( + context.Background(), + &types.ConstructionDeriveRequest{ + NetworkIdentifier: &types.NetworkIdentifier{ + Network: mapper.FujiNetwork, + SubNetworkIdentifier: &types.SubNetworkIdentifier{ + Network: mapper.PChainNetworkIdentifier, + }, + }, + PublicKey: &types.PublicKey{ + Bytes: b, + CurveType: types.Secp256k1, + }, + }, + ) + assert.Nil(t, err) + assert.Equal( + t, + "P-fuji15f9g0h5xkr5cp47n6u3qxj6yjtzzzrdr23a3tl", + resp.AccountIdentifier.Address, + ) + }) } func forceMarshalMap(t *testing.T, i interface{}) map[string]interface{} { From c2ea9d0fa3ff7eed639b163135c4b6232e8a5ed9 Mon Sep 17 00:00:00 2001 From: Yukai Date: Tue, 7 Jun 2022 13:36:55 -0700 Subject: [PATCH 5/9] Add pchain client --- mapper/helper.go | 39 ++++++++++++++++++++++- service/chain/p/client.go | 46 ++++++++++++++++++++++++++++ service/helper.go | 33 -------------------- service/service_construction.go | 28 +++++------------ service/service_construction_test.go | 5 ++- 5 files changed, 95 insertions(+), 56 deletions(-) create mode 100644 service/chain/p/client.go diff --git a/mapper/helper.go b/mapper/helper.go index ef8a2e7c..70eaea6a 100644 --- a/mapper/helper.go +++ b/mapper/helper.go @@ -1,6 +1,12 @@ package mapper -import "strings" +import ( + "errors" + "strings" + + "github.com/ava-labs/avalanchego/utils/constants" + "github.com/coinbase/rosetta-sdk-go/types" +) // EqualFoldContains checks if the array contains the string regardless of casing func EqualFoldContains(arr []string, str string) bool { @@ -11,3 +17,34 @@ func EqualFoldContains(arr []string, str string) bool { } return false } + +// IsPChain checks network identifier to make sure sub-network identifier set to "P" +func IsPChain(networkIdentifier *types.NetworkIdentifier) bool { + if networkIdentifier != nil && + networkIdentifier.SubNetworkIdentifier != nil && + networkIdentifier.SubNetworkIdentifier.Network == PChainNetworkIdentifier { + return true + } + + return false +} + +// GetAliasAndHRP fetches chain id alias and hrp for address formatting. +// Right now only P chain id alias is supported +func GetAliasAndHRP(networkIdentifier *types.NetworkIdentifier) (string, string, error) { + var chainIDAlias, hrp string + if !IsPChain(networkIdentifier) { + return "", "", errors.New("only support P chain alias") + } + chainIDAlias = PChainIDAlias + switch networkIdentifier.Network { + case FujiNetwork: + hrp = constants.GetHRP(constants.FujiID) + case MainnetNetwork: + hrp = constants.GetHRP(constants.MainnetID) + default: + return "", "", errors.New("can't recognize network") + } + + return chainIDAlias, hrp, nil +} diff --git a/service/chain/p/client.go b/service/chain/p/client.go new file mode 100644 index 00000000..7a2f48a2 --- /dev/null +++ b/service/chain/p/client.go @@ -0,0 +1,46 @@ +package p + +import ( + "context" + + "github.com/ava-labs/avalanche-rosetta/mapper" + "github.com/ava-labs/avalanchego/utils/crypto" + "github.com/ava-labs/avalanchego/utils/formatting/address" + "github.com/coinbase/rosetta-sdk-go/types" +) + +type Client struct { + fac crypto.FactorySECP256K1R +} + +func NewClient() *Client { + return &Client{ + fac: crypto.FactorySECP256K1R{}, + } +} + +func (c *Client) DeriveAddress( + ctx context.Context, + req *types.ConstructionDeriveRequest, +) (*types.ConstructionDeriveResponse, error) { + pub, err := c.fac.ToPublicKey(req.PublicKey.Bytes) + if err != nil { + return nil, err + } + + chainIDAlias, hrp, getErr := mapper.GetAliasAndHRP(req.NetworkIdentifier) + if getErr != nil { + return nil, getErr + } + + addr, err := address.Format(chainIDAlias, hrp, pub.Address().Bytes()) + if err != nil { + return nil, err + } + + return &types.ConstructionDeriveResponse{ + AccountIdentifier: &types.AccountIdentifier{ + Address: addr, + }, + }, nil +} diff --git a/service/helper.go b/service/helper.go index 20d98b3a..76aed46c 100644 --- a/service/helper.go +++ b/service/helper.go @@ -6,13 +6,11 @@ import ( "math/big" "strings" - "github.com/ava-labs/avalanchego/utils/constants" ethtypes "github.com/ava-labs/coreth/core/types" "github.com/coinbase/rosetta-sdk-go/types" ethcommon "github.com/ethereum/go-ethereum/common" "github.com/ava-labs/avalanche-rosetta/client" - "github.com/ava-labs/avalanche-rosetta/mapper" ) const ( @@ -106,34 +104,3 @@ func ChecksumAddress(address string) (string, bool) { return addr.Address().Hex(), true } - -// isPChain checks network identifier to make sure sub-network identifier set to "P" -func isPChain(networkIdentifier *types.NetworkIdentifier) bool { - if networkIdentifier != nil && - networkIdentifier.SubNetworkIdentifier != nil && - networkIdentifier.SubNetworkIdentifier.Network == mapper.PChainNetworkIdentifier { - return true - } - - return false -} - -// getAliasAndHRP fetches chain id alias and hrp for address formatting. -// Right now only P chain id alias is supported -func getAliasAndHRP(networkIdentifier *types.NetworkIdentifier) (string, string, *types.Error) { - var chainIDAlias, hrp string - if !isPChain(networkIdentifier) { - return "", "", makeError(errNotImplemented.Code, "only support P chain alias", false) - } - chainIDAlias = mapper.PChainIDAlias - switch networkIdentifier.Network { - case mapper.FujiNetwork: - hrp = constants.GetHRP(constants.FujiID) - case mapper.MainnetNetwork: - hrp = constants.GetHRP(constants.MainnetID) - default: - return "", "", makeError(errNotImplemented.Code, "can't recognize network", false) - } - - return chainIDAlias, hrp, nil -} diff --git a/service/service_construction.go b/service/service_construction.go index b99638a1..ac3b294a 100644 --- a/service/service_construction.go +++ b/service/service_construction.go @@ -6,8 +6,6 @@ import ( "fmt" "math/big" - "github.com/ava-labs/avalanchego/utils/crypto" - "github.com/ava-labs/avalanchego/utils/formatting/address" ethtypes "github.com/ava-labs/coreth/core/types" "github.com/ava-labs/coreth/interfaces" "github.com/coinbase/rosetta-sdk-go/parser" @@ -21,6 +19,7 @@ import ( "github.com/ava-labs/avalanche-rosetta/client" "github.com/ava-labs/avalanche-rosetta/mapper" + "github.com/ava-labs/avalanche-rosetta/service/chain/p" ) const ( @@ -34,6 +33,7 @@ const ( type ConstructionService struct { config *Config client client.Client + p *p.Client } // NewConstructionService returns a new construction servicer @@ -41,6 +41,7 @@ func NewConstructionService(config *Config, client client.Client) server.Constru return &ConstructionService{ config: config, client: client, + p: p.NewClient(), } } @@ -223,28 +224,13 @@ func (s ConstructionService) ConstructionDerive( ctx context.Context, req *types.ConstructionDeriveRequest, ) (*types.ConstructionDeriveResponse, *types.Error) { - if isPChain(req.NetworkIdentifier) { - fac := crypto.FactorySECP256K1R{} - pub, err := fac.ToPublicKey(req.PublicKey.Bytes) + if mapper.IsPChain(req.NetworkIdentifier) { + res, err := s.p.DeriveAddress(ctx, req) if err != nil { - return nil, wrapError(errInvalidInput, err) - } - - chainIDAlias, hrp, getErr := getAliasAndHRP(req.NetworkIdentifier) - if getErr != nil { - return nil, getErr + return nil, wrapError(errInternalError, "p chain address derivation failed") } - addr, err := address.Format(chainIDAlias, hrp, pub.Address().Bytes()) - if err != nil { - return nil, wrapError(errInvalidInput, err) - } - - return &types.ConstructionDeriveResponse{ - AccountIdentifier: &types.AccountIdentifier{ - Address: addr, - }, - }, nil + return res, nil } if req.PublicKey == nil { diff --git a/service/service_construction_test.go b/service/service_construction_test.go index d8be8a61..0b18de78 100644 --- a/service/service_construction_test.go +++ b/service/service_construction_test.go @@ -9,6 +9,7 @@ import ( "github.com/ava-labs/avalanche-rosetta/mapper" mocks "github.com/ava-labs/avalanche-rosetta/mocks/client" + "github.com/ava-labs/avalanche-rosetta/service/chain/p" "github.com/ava-labs/coreth/interfaces" "github.com/coinbase/rosetta-sdk-go/types" @@ -238,7 +239,9 @@ func TestContructionHash(t *testing.T) { } func TestConstructionDerive(t *testing.T) { - service := ConstructionService{} + service := ConstructionService{ + p: p.NewClient(), + } t.Run("no public key", func(t *testing.T) { resp, err := service.ConstructionDerive( From 79c1a54636979c3b359b77dba32017d04df9ff39 Mon Sep 17 00:00:00 2001 From: Yukai Date: Wed, 8 Jun 2022 10:26:27 -0700 Subject: [PATCH 6/9] Comments --- cmd/server/main.go | 13 ++++++++----- service/service_construction.go | 8 ++++---- 2 files changed, 12 insertions(+), 9 deletions(-) diff --git a/cmd/server/main.go b/cmd/server/main.go index cd9a48df..3bb7fadb 100644 --- a/cmd/server/main.go +++ b/cmd/server/main.go @@ -124,11 +124,14 @@ func main() { } asserter, err := asserter.NewServer( - mapper.OperationTypes, // supported operation types - true, // historical balance lookup - []*types.NetworkIdentifier{networkP, networkC}, // supported networks - []string{}, // call methods - false, // mempool coins + mapper.OperationTypes, // supported operation types + true, // historical balance lookup + []*types.NetworkIdentifier{ // supported networks + networkP, + networkC, + }, + []string{}, // call methods + false, // mempool coins ) if err != nil { log.Fatal("server asserter init error:", err) diff --git a/service/service_construction.go b/service/service_construction.go index ac3b294a..b10e8d9f 100644 --- a/service/service_construction.go +++ b/service/service_construction.go @@ -224,6 +224,10 @@ func (s ConstructionService) ConstructionDerive( ctx context.Context, req *types.ConstructionDeriveRequest, ) (*types.ConstructionDeriveResponse, *types.Error) { + if req.PublicKey == nil { + return nil, wrapError(errInvalidInput, "public key is not provided") + } + if mapper.IsPChain(req.NetworkIdentifier) { res, err := s.p.DeriveAddress(ctx, req) if err != nil { @@ -233,10 +237,6 @@ func (s ConstructionService) ConstructionDerive( return res, nil } - if req.PublicKey == nil { - return nil, wrapError(errInvalidInput, "public key is not provided") - } - key, err := ethcrypto.DecompressPubkey(req.PublicKey.Bytes) if err != nil { return nil, wrapError(errInvalidInput, err) From 653c8f898350a38ac139b091494493ca20be6590 Mon Sep 17 00:00:00 2001 From: Yukai Date: Wed, 8 Jun 2022 10:29:11 -0700 Subject: [PATCH 7/9] Align comments --- cmd/server/main.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/cmd/server/main.go b/cmd/server/main.go index 3bb7fadb..c93f8ac6 100644 --- a/cmd/server/main.go +++ b/cmd/server/main.go @@ -124,14 +124,14 @@ func main() { } asserter, err := asserter.NewServer( - mapper.OperationTypes, // supported operation types - true, // historical balance lookup + mapper.OperationTypes, // supported operation types + true, // historical balance lookup []*types.NetworkIdentifier{ // supported networks networkP, networkC, }, - []string{}, // call methods - false, // mempool coins + []string{}, // call methods + false, // mempool coins ) if err != nil { log.Fatal("server asserter init error:", err) From 48b596a522da98a2b9539e86c28d35b37758c3e2 Mon Sep 17 00:00:00 2001 From: Yukai Date: Fri, 10 Jun 2022 11:51:26 -0700 Subject: [PATCH 8/9] lint --- cmd/server/main.go | 8 ++++---- mapper/helper.go | 21 ++++++++++----------- 2 files changed, 14 insertions(+), 15 deletions(-) diff --git a/cmd/server/main.go b/cmd/server/main.go index c93f8ac6..f2a41cce 100644 --- a/cmd/server/main.go +++ b/cmd/server/main.go @@ -124,14 +124,14 @@ func main() { } asserter, err := asserter.NewServer( - mapper.OperationTypes, // supported operation types - true, // historical balance lookup + mapper.OperationTypes, // supported operation types + true, // historical balance lookup []*types.NetworkIdentifier{ // supported networks networkP, networkC, }, - []string{}, // call methods - false, // mempool coins + []string{}, // call methods + false, // mempool coins ) if err != nil { log.Fatal("server asserter init error:", err) diff --git a/mapper/helper.go b/mapper/helper.go index 70eaea6a..b78b4c4d 100644 --- a/mapper/helper.go +++ b/mapper/helper.go @@ -8,6 +8,9 @@ import ( "github.com/coinbase/rosetta-sdk-go/types" ) +var errUnsupportedChain = errors.New("unsupported chain") +var errUnsupportedNetwork = errors.New("unsupported network") + // EqualFoldContains checks if the array contains the string regardless of casing func EqualFoldContains(arr []string, str string) bool { for _, a := range arr { @@ -20,31 +23,27 @@ func EqualFoldContains(arr []string, str string) bool { // IsPChain checks network identifier to make sure sub-network identifier set to "P" func IsPChain(networkIdentifier *types.NetworkIdentifier) bool { - if networkIdentifier != nil && + return networkIdentifier != nil && networkIdentifier.SubNetworkIdentifier != nil && - networkIdentifier.SubNetworkIdentifier.Network == PChainNetworkIdentifier { - return true - } - - return false + networkIdentifier.SubNetworkIdentifier.Network == PChainNetworkIdentifier } // GetAliasAndHRP fetches chain id alias and hrp for address formatting. // Right now only P chain id alias is supported func GetAliasAndHRP(networkIdentifier *types.NetworkIdentifier) (string, string, error) { - var chainIDAlias, hrp string if !IsPChain(networkIdentifier) { - return "", "", errors.New("only support P chain alias") + return "", "", errUnsupportedChain } - chainIDAlias = PChainIDAlias + + var hrp string switch networkIdentifier.Network { case FujiNetwork: hrp = constants.GetHRP(constants.FujiID) case MainnetNetwork: hrp = constants.GetHRP(constants.MainnetID) default: - return "", "", errors.New("can't recognize network") + return "", "", errUnsupportedNetwork } - return chainIDAlias, hrp, nil + return PChainIDAlias, hrp, nil } From c08bf460cf210c9b05c0a6e03a15874b181a059e Mon Sep 17 00:00:00 2001 From: Yukai Date: Fri, 10 Jun 2022 12:57:43 -0700 Subject: [PATCH 9/9] fix --- mapper/helper.go | 8 +++++--- mapper/types.go | 1 - 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/mapper/helper.go b/mapper/helper.go index b78b4c4d..5aef98dc 100644 --- a/mapper/helper.go +++ b/mapper/helper.go @@ -8,8 +8,10 @@ import ( "github.com/coinbase/rosetta-sdk-go/types" ) -var errUnsupportedChain = errors.New("unsupported chain") -var errUnsupportedNetwork = errors.New("unsupported network") +var ( + errUnsupportedChain = errors.New("unsupported chain") + errUnsupportedNetwork = errors.New("unsupported network") +) // EqualFoldContains checks if the array contains the string regardless of casing func EqualFoldContains(arr []string, str string) bool { @@ -45,5 +47,5 @@ func GetAliasAndHRP(networkIdentifier *types.NetworkIdentifier) (string, string, return "", "", errUnsupportedNetwork } - return PChainIDAlias, hrp, nil + return PChainNetworkIdentifier, hrp, nil } diff --git a/mapper/types.go b/mapper/types.go index f3f3f989..02782a67 100644 --- a/mapper/types.go +++ b/mapper/types.go @@ -19,7 +19,6 @@ const ( IndexTransferredMetadata = "indexTransferred" PChainNetworkIdentifier = "P" - PChainIDAlias = "P" OpCall = "CALL" OpFee = "FEE"