Skip to content
This repository was archived by the owner on Jul 13, 2022. It is now read-only.

Commit 8cee3ff

Browse files
Add support for parsing hex values in config (#728)
* Add support for parsing hex values in config * Remove unnecessary helpers * Use a hex value for the minGasPrice in unit tests * Fix error wrapping lint errors
1 parent 9585bc8 commit 8cee3ff

File tree

3 files changed

+121
-21
lines changed

3 files changed

+121
-21
lines changed

chains/ethereum/config.go

+18-21
Original file line numberDiff line numberDiff line change
@@ -111,36 +111,33 @@ func parseChainConfig(chainCfg *core.ChainConfig) (*Config, error) {
111111
}
112112

113113
if gasPrice, ok := chainCfg.Opts[MaxGasPriceOpt]; ok {
114-
price := big.NewInt(0)
115-
_, pass := price.SetString(gasPrice, 10)
116-
if pass {
117-
config.maxGasPrice = price
118-
delete(chainCfg.Opts, MaxGasPriceOpt)
119-
} else {
120-
return nil, errors.New("unable to parse max gas price")
114+
price, parseErr := utils.ParseUint256OrHex(&gasPrice)
115+
if parseErr != nil {
116+
return nil, fmt.Errorf("unable to parse max gas price, %w", parseErr)
121117
}
118+
119+
config.maxGasPrice = price
120+
delete(chainCfg.Opts, MaxGasPriceOpt)
122121
}
123122

124123
if minGasPrice, ok := chainCfg.Opts[MinGasPriceOpt]; ok {
125-
price := big.NewInt(0)
126-
_, pass := price.SetString(minGasPrice, 10)
127-
if pass {
128-
config.minGasPrice = price
129-
delete(chainCfg.Opts, MinGasPriceOpt)
130-
} else {
131-
return nil, errors.New("unable to parse min gas price")
124+
price, parseErr := utils.ParseUint256OrHex(&minGasPrice)
125+
if parseErr != nil {
126+
return nil, fmt.Errorf("unable to parse min gas price, %w", parseErr)
132127
}
128+
129+
config.minGasPrice = price
130+
delete(chainCfg.Opts, MinGasPriceOpt)
133131
}
134132

135133
if gasLimit, ok := chainCfg.Opts[GasLimitOpt]; ok {
136-
limit := big.NewInt(0)
137-
_, pass := limit.SetString(gasLimit, 10)
138-
if pass {
139-
config.gasLimit = limit
140-
delete(chainCfg.Opts, GasLimitOpt)
141-
} else {
142-
return nil, errors.New("unable to parse gas limit")
134+
limit, parseErr := utils.ParseUint256OrHex(&gasLimit)
135+
if parseErr != nil {
136+
return nil, fmt.Errorf("unable to parse gas limit, %w", parseErr)
143137
}
138+
139+
config.gasLimit = limit
140+
delete(chainCfg.Opts, GasLimitOpt)
144141
}
145142

146143
if gasMultiplier, ok := chainCfg.Opts[GasMultiplier]; ok {

chains/ethereum/config_test.go

+65
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import (
88
"reflect"
99
"testing"
1010

11+
utils "github.com/ChainSafe/ChainBridge/shared/ethereum"
1112
"github.com/ChainSafe/chainbridge-utils/core"
1213
"github.com/ethereum/go-ethereum/common"
1314
)
@@ -71,6 +72,70 @@ func TestParseChainConfig(t *testing.T) {
7172
}
7273
}
7374

75+
// TestParseChainConfigHex tests the parseChainConfig with hex values
76+
func TestParseChainConfigHex(t *testing.T) {
77+
commonHexValue := "0x1234"
78+
expectedHex, parseErr := utils.ParseUint256OrHex(&commonHexValue)
79+
if parseErr != nil {
80+
t.Fatalf("unable to parse value %s, %v", commonHexValue, parseErr)
81+
}
82+
83+
input := core.ChainConfig{
84+
Name: "chain",
85+
Id: 1,
86+
Endpoint: "endpoint",
87+
From: "0x0",
88+
KeystorePath: "./keys",
89+
Insecure: false,
90+
Opts: map[string]string{
91+
"bridge": "0x1234",
92+
"erc20Handler": "0x1234",
93+
"erc721Handler": "0x1234",
94+
"genericHandler": "0x1234",
95+
"gasLimit": commonHexValue,
96+
"gasMultiplier": "1",
97+
"maxGasPrice": commonHexValue,
98+
"minGasPrice": commonHexValue,
99+
"http": "true",
100+
"startBlock": "10",
101+
"blockConfirmations": "50",
102+
"egsApiKey": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", // fake key
103+
"egsSpeed": "fast",
104+
},
105+
}
106+
107+
out, err := parseChainConfig(&input)
108+
109+
if err != nil {
110+
t.Fatal(err)
111+
}
112+
113+
expected := Config{
114+
name: "chain",
115+
id: 1,
116+
endpoint: "endpoint",
117+
from: "0x0",
118+
keystorePath: "./keys",
119+
bridgeContract: common.HexToAddress("0x1234"),
120+
erc20HandlerContract: common.HexToAddress("0x1234"),
121+
erc721HandlerContract: common.HexToAddress("0x1234"),
122+
genericHandlerContract: common.HexToAddress("0x1234"),
123+
gasLimit: expectedHex,
124+
maxGasPrice: expectedHex,
125+
minGasPrice: expectedHex,
126+
gasMultiplier: big.NewFloat(1),
127+
http: true,
128+
startBlock: big.NewInt(10),
129+
blockConfirmations: big.NewInt(50),
130+
egsApiKey: "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
131+
egsSpeed: "fast",
132+
}
133+
134+
if !reflect.DeepEqual(&expected, out) {
135+
t.Fatalf("Output not expected.\n\tExpected: %#v\n\tGot: %#v\n", &expected, out)
136+
}
137+
}
138+
74139
//TestParseChainConfig tests parseChainConfig with all handlerContracts provided
75140
func TestParseChainConfigWithNoBlockConfirmations(t *testing.T) {
76141

shared/ethereum/generic.go

+38
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,10 @@
44
package utils
55

66
import (
7+
"fmt"
8+
"math/big"
9+
"strings"
10+
711
"github.com/ChainSafe/ChainBridge/bindings/GenericHandler"
812
"github.com/ChainSafe/chainbridge-utils/msg"
913
"github.com/ethereum/go-ethereum/common"
@@ -31,3 +35,37 @@ func GetGenericResourceAddress(client *Client, handler common.Address, rId msg.R
3135
}
3236
return addr, nil
3337
}
38+
39+
const (
40+
decimalBase = 10
41+
hexBase = 16
42+
)
43+
44+
// valueToBig converts a string value to a *big.Int in the provided base
45+
func valueToBig(value string, base int) (*big.Int, error) {
46+
val, ok := new(big.Int).SetString(value, base)
47+
if !ok {
48+
return nil, fmt.Errorf("unable to parse value")
49+
}
50+
51+
return val, nil
52+
}
53+
54+
// ParseUint256OrHex parses a string value as either a base 10 number
55+
// or as a hex value
56+
func ParseUint256OrHex(value *string) (*big.Int, error) {
57+
// Check if the value is valid
58+
if value == nil {
59+
return nil, fmt.Errorf("invalid value")
60+
}
61+
62+
// Check if the value is hex
63+
if strings.HasPrefix(*value, "0x") {
64+
// Hex value, remove the prefix and parse it
65+
clipped := (*value)[2:]
66+
return valueToBig(clipped, hexBase)
67+
}
68+
69+
// Decimal number, parse it
70+
return valueToBig(*value, decimalBase)
71+
}

0 commit comments

Comments
 (0)