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

Commit 0e91dad

Browse files
author
Silas Davis
committed
Allow overriding of ChainID
Also fix encoding of ChainID return values in web3 This allows integration with eth tooling like metamask that expects a numeric ChainID serialised in base 10 to a string in order to sign transactions Signed-off-by: Silas Davis <[email protected]>
1 parent 513b4c0 commit 0e91dad

File tree

18 files changed

+69
-55
lines changed

18 files changed

+69
-55
lines changed

bcm/blockchain.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -183,7 +183,7 @@ func (bc *Blockchain) GenesisDoc() genesis.GenesisDoc {
183183
}
184184

185185
func (bc *Blockchain) ChainID() string {
186-
return bc.genesisDoc.ChainID()
186+
return bc.genesisDoc.GetChainID()
187187
}
188188

189189
func (bc *Blockchain) LastBlockHeight() uint64 {

cmd/burrow/commands/config_options.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -115,8 +115,8 @@ func (opts *configOptions) obtainBurrowConfig() (*config.BurrowConfig, error) {
115115
}
116116
if *opts.initMonikerOpt == "" {
117117
chainIDHeader := ""
118-
if conf.GenesisDoc != nil && conf.GenesisDoc.ChainID() != "" {
119-
chainIDHeader = conf.GenesisDoc.ChainID() + "_"
118+
if conf.GenesisDoc != nil && conf.GenesisDoc.GetChainID() != "" {
119+
chainIDHeader = conf.GenesisDoc.GetChainID() + "_"
120120
}
121121
if conf.ValidatorAddress != nil {
122122
// Set a default moniker... since we can at this stage of config completion and it is required for start

config/config.go

+3
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package config
33
import (
44
"fmt"
55

6+
"github.com/alecthomas/jsonschema"
67
"github.com/hyperledger/burrow/config/source"
78
"github.com/hyperledger/burrow/consensus/tendermint"
89
"github.com/hyperledger/burrow/crypto"
@@ -32,6 +33,8 @@ type BurrowConfig struct {
3233
Logging *logconfig.LoggingConfig `json:",omitempty" toml:",omitempty"`
3334
}
3435

36+
var burrowConfigSchema = jsonschema.Reflect(&BurrowConfig{})
37+
3538
func DefaultBurrowConfig() *BurrowConfig {
3639
return &BurrowConfig{
3740
BurrowDir: ".burrow",

config/config_test.go

+7-2
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
package config
22

33
import (
4-
"fmt"
54
"testing"
65

6+
"github.com/hyperledger/burrow/config/source"
77
"github.com/hyperledger/burrow/genesis"
8+
"github.com/stretchr/testify/require"
89
)
910

1011
func TestBurrowConfigSerialise(t *testing.T) {
@@ -13,5 +14,9 @@ func TestBurrowConfigSerialise(t *testing.T) {
1314
ChainName: "Foo",
1415
},
1516
}
16-
fmt.Println(conf.JSONString())
17+
confOut := new(BurrowConfig)
18+
jsonString := conf.JSONString()
19+
err := source.FromJSONString(jsonString, confOut)
20+
require.NoError(t, err)
21+
require.Equal(t, jsonString, confOut.JSONString())
1722
}

consensus/tendermint/tendermint.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ func DeriveGenesisDoc(burrowGenesisDoc *genesis.GenesisDoc, appHash []byte) *tmT
102102
consensusParams.Block.TimeIotaMs = 1
103103

104104
return &tmTypes.GenesisDoc{
105-
ChainID: burrowGenesisDoc.ChainID(),
105+
ChainID: burrowGenesisDoc.GetChainID(),
106106
GenesisTime: burrowGenesisDoc.GenesisTime,
107107
Validators: validators,
108108
AppHash: appHash,

execution/exec/stream_event_test.go

+5-5
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ import (
1717
var genesisDoc, accounts, _ = genesis.NewDeterministicGenesis(345234523).GenesisDoc(10, 0)
1818

1919
func TestTxExecution(t *testing.T) {
20-
txe := NewTxExecution(txs.Enclose(genesisDoc.ChainID(), newCallTx(0, 1)))
20+
txe := NewTxExecution(txs.Enclose(genesisDoc.GetChainID(), newCallTx(0, 1)))
2121

2222
stack := new(TxStack)
2323
var txeOut *TxExecution
@@ -38,17 +38,17 @@ func TestConsumeBlockExecution(t *testing.T) {
3838
height := int64(234242)
3939
be := &BlockExecution{
4040
Header: &tmproto.Header{
41-
ChainID: genesisDoc.ChainID(),
41+
ChainID: genesisDoc.GetChainID(),
4242
AppHash: crypto.Keccak256([]byte("hashily")),
4343
Time: time.Now(),
4444
Height: height,
4545
},
4646
Height: uint64(height),
4747
}
4848
be.AppendTxs(
49-
NewTxExecution(txs.Enclose(genesisDoc.ChainID(), newCallTx(0, 3))),
50-
NewTxExecution(txs.Enclose(genesisDoc.ChainID(), newCallTx(0, 2))),
51-
NewTxExecution(txs.Enclose(genesisDoc.ChainID(), newCallTx(2, 1))),
49+
NewTxExecution(txs.Enclose(genesisDoc.GetChainID(), newCallTx(0, 3))),
50+
NewTxExecution(txs.Enclose(genesisDoc.GetChainID(), newCallTx(0, 2))),
51+
NewTxExecution(txs.Enclose(genesisDoc.GetChainID(), newCallTx(2, 1))),
5252
)
5353

5454
stack := NewBlockAccumulator()

execution/execution.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ type Params struct {
9797

9898
func ParamsFromGenesis(genesisDoc *genesis.GenesisDoc) Params {
9999
return Params{
100-
ChainID: genesisDoc.ChainID(),
100+
ChainID: genesisDoc.GetChainID(),
101101
ProposalThreshold: genesisDoc.Params.ProposalThreshold,
102102
}
103103
}

execution/execution_test.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ var logger = logging.NewNoopLogger()
5353
var deterministicGenesis = genesis.NewDeterministicGenesis(34059836243380576)
5454
var testGenesisDoc, testPrivAccounts, _ = deterministicGenesis.
5555
GenesisDoc(3, 1)
56-
var testChainID = testGenesisDoc.ChainID()
56+
var testChainID = testGenesisDoc.GetChainID()
5757

5858
func TestSendFails(t *testing.T) {
5959
stateDB, err := dbm.NewDB("state", dbBackend, dbDir)

genesis/genesis.go

+12-11
Original file line numberDiff line numberDiff line change
@@ -54,17 +54,18 @@ type params struct {
5454
}
5555

5656
type GenesisDoc struct {
57-
GenesisTime time.Time
58-
ChainName string
59-
AppHash binary.HexBytes `json:",omitempty" toml:",omitempty"`
60-
Params params `json:",omitempty" toml:",omitempty"`
61-
Salt []byte `json:",omitempty" toml:",omitempty"`
57+
GenesisTime time.Time
58+
ChainName string
59+
// Ordinarily we derive this from the genesis hash but to support explicit Ethereum ChainID it may be set
60+
ChainID string `json:",omitempty" toml:",omitempty"`
61+
AppHash binary.HexBytes
62+
Params params `json:",omitempty" toml:",omitempty"`
63+
Salt []byte `json:",omitempty" toml:",omitempty"`
6264
GlobalPermissions permission.AccountPermissions
6365
Accounts []Account
6466
Validators []Validator
6567
// memo
66-
hash []byte
67-
chainID string
68+
hash []byte
6869
}
6970

7071
func (genesisDoc *GenesisDoc) GlobalPermissionsAccount() *acm.Account {
@@ -115,11 +116,11 @@ func (genesisDoc *GenesisDoc) ShortHash() []byte {
115116
return genesisDoc.Hash()[:ShortHashSuffixBytes]
116117
}
117118

118-
func (genesisDoc *GenesisDoc) ChainID() string {
119-
if genesisDoc.chainID == "" {
120-
genesisDoc.chainID = fmt.Sprintf("%s-%X", genesisDoc.ChainName, genesisDoc.ShortHash())
119+
func (genesisDoc *GenesisDoc) GetChainID() string {
120+
if genesisDoc.ChainID == "" {
121+
genesisDoc.ChainID = fmt.Sprintf("%s-%X", genesisDoc.ChainName, genesisDoc.ShortHash())
121122
}
122-
return genesisDoc.chainID
123+
return genesisDoc.ChainID
123124
}
124125

125126
//------------------------------------------------------------

integration/governance/governance_test.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -226,12 +226,12 @@ func TestGovernance(t *testing.T) {
226226
})
227227

228228
setSequence(t, qcli, tx)
229-
_, err := localSignAndBroadcastSync(t, tcli1, genesisDoc.ChainID(), genesisAccounts[0], tx)
229+
_, err := localSignAndBroadcastSync(t, tcli1, genesisDoc.GetChainID(), genesisAccounts[0], tx)
230230
require.NoError(t, err)
231231

232232
// Make it a different Tx hash so it can enter cache but keep sequence number
233233
tx.AccountUpdates[0].Amounts = balance.New().Power(power).Native(1)
234-
_, err = localSignAndBroadcastSync(t, tcli2, genesisDoc.ChainID(), genesisAccounts[0], tx)
234+
_, err = localSignAndBroadcastSync(t, tcli2, genesisDoc.GetChainID(), genesisAccounts[0], tx)
235235
require.Error(t, err)
236236
assert.Contains(t, err.Error(), "invalid sequence")
237237
})

integration/rpcinfo/info_server_test.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ func TestInfoServer(t *testing.T) {
5454
resp, err := infoclient.Status(rpcClient)
5555
require.NoError(t, err)
5656
assert.Contains(t, resp.GetNodeInfo().GetMoniker(), "node")
57-
assert.Equal(t, rpctest.GenesisDoc.ChainID(), resp.NodeInfo.Network,
57+
assert.Equal(t, rpctest.GenesisDoc.GetChainID(), resp.NodeInfo.Network,
5858
"ChainID should match NodeInfo.Network")
5959
})
6060

integration/rpcquery/query_server_test.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ func TestQueryServer(t *testing.T) {
3131
status, err := cli.Status(context.Background(), &rpcquery.StatusParam{})
3232
require.NoError(t, err)
3333
assert.Equal(t, rpctest.PrivateAccounts[0].GetPublicKey(), status.ValidatorInfo.PublicKey)
34-
assert.Equal(t, rpctest.GenesisDoc.ChainID(), status.ChainID)
34+
assert.Equal(t, rpctest.GenesisDoc.GetChainID(), status.ChainID)
3535
for i := 0; i < 3; i++ {
3636
// Unless we get lucky this is an error
3737
_, err = cli.Status(context.Background(), &rpcquery.StatusParam{

integration/rpctest/helpers.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -154,7 +154,7 @@ func MakeDefaultCallTx(t *testing.T, client rpc.Client, addr *crypto.Address, co
154154
fee uint64) *txs.Envelope {
155155
sequence := GetSequence(t, client, PrivateAccounts[0].GetAddress())
156156
tx := payload.NewCallTxWithSequence(PrivateAccounts[0].GetPublicKey(), addr, code, amt, gasLim, fee, sequence+1)
157-
txEnv := txs.Enclose(GenesisDoc.ChainID(), tx)
157+
txEnv := txs.Enclose(GenesisDoc.GetChainID(), tx)
158158
require.NoError(t, txEnv.Sign(PrivateAccounts[0]))
159159
return txEnv
160160
}

integration/rpctransact/transact_server_test.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ func TestTransactServer(t *testing.T) {
6262
})
6363
require.NoError(t, err)
6464
amount := uint64(2123)
65-
txEnv := txs.Enclose(rpctest.GenesisDoc.ChainID(), &payload.SendTx{
65+
txEnv := txs.Enclose(rpctest.GenesisDoc.GetChainID(), &payload.SendTx{
6666
Inputs: []*payload.TxInput{{
6767
Address: inputAddress,
6868
Sequence: acc.Sequence + 1,
@@ -120,7 +120,7 @@ func TestTransactServer(t *testing.T) {
120120
// We should see the sign bytes embedded
121121
if !assert.Contains(t, string(bs), fmt.Sprintf("{\"ChainID\":\"%s\",\"Type\":\"CallTx\","+
122122
"\"Payload\":{\"Input\":{\"Address\":\"E80BB91C2F0F4C3C39FC53E89BF8416B219BE6E4\",\"Amount\":230},"+
123-
"\"Data\":\"0203060403\"}}", rpctest.GenesisDoc.ChainID())) {
123+
"\"Data\":\"0203060403\"}}", rpctest.GenesisDoc.GetChainID())) {
124124
fmt.Println(string(bs))
125125
}
126126
})

rpc/web3/eth_service.go

+16-13
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ type EthService struct {
4545
keyClient keys.KeyClient
4646
keyStore *keys.FilesystemKeyStore
4747
config *tmConfig.Config
48+
chainID *big.Int
4849
logger *logging.Logger
4950
}
5051

@@ -63,16 +64,18 @@ func NewEthService(
6364
keyClient := keys.NewLocalKeyClient(keyStore, logger)
6465

6566
return &EthService{
66-
accounts,
67-
events,
68-
blockchain,
69-
validators,
70-
nodeView,
71-
trans,
72-
keyClient,
73-
keyStore,
74-
tmConfig.DefaultConfig(),
75-
logger,
67+
accounts: accounts,
68+
events: events,
69+
blockchain: blockchain,
70+
validators: validators,
71+
nodeView: nodeView,
72+
trans: trans,
73+
keyClient: keyClient,
74+
keyStore: keyStore,
75+
config: tmConfig.DefaultConfig(),
76+
// Ethereum expects ChainID to be an integer value
77+
chainID: crypto.GetEthChainID(blockchain.ChainID()),
78+
logger: logger,
7679
}
7780
}
7881

@@ -119,7 +122,7 @@ func (srv *EthService) NetPeerCount() (*NetPeerCountResult, error) {
119122
// this is typically a small int (where 1 == Ethereum mainnet)
120123
func (srv *EthService) NetVersion() (*NetVersionResult, error) {
121124
return &NetVersionResult{
122-
ChainID: crypto.GetEthChainID(srv.blockchain.ChainID()).String(),
125+
ChainID: HexEncoder.BigInt(srv.chainID),
123126
}, nil
124127
}
125128

@@ -133,7 +136,7 @@ func (srv *EthService) EthProtocolVersion() (*EthProtocolVersionResult, error) {
133136
// EthChainId returns the chainID
134137
func (srv *EthService) EthChainId() (*EthChainIdResult, error) {
135138
return &EthChainIdResult{
136-
ChainId: srv.blockchain.ChainID(),
139+
ChainId: HexEncoder.BigInt(srv.chainID),
137140
}, nil
138141
}
139142

@@ -568,7 +571,7 @@ func (srv *EthService) EthSendRawTransaction(req *EthSendRawTransactionParams) (
568571
return nil, d.Err()
569572
}
570573

571-
rawTx := txs.NewEthRawTx(srv.blockchain.ChainID())
574+
rawTx := txs.NewEthRawTx(srv.chainID)
572575
err := rlp.Decode(data, rawTx)
573576
if err != nil {
574577
return nil, err

rpc/web3/eth_service_test.go

+10-8
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,6 @@ import (
88
"testing"
99
"time"
1010

11-
"github.com/hyperledger/burrow/rpc/web3"
12-
"github.com/hyperledger/burrow/txs"
13-
"github.com/hyperledger/burrow/txs/payload"
14-
1511
"github.com/hyperledger/burrow/acm/balance"
1612
"github.com/hyperledger/burrow/crypto"
1713
"github.com/hyperledger/burrow/execution/evm/abi"
@@ -20,17 +16,23 @@ import (
2016
"github.com/hyperledger/burrow/logging"
2117
"github.com/hyperledger/burrow/project"
2218
"github.com/hyperledger/burrow/rpc"
19+
"github.com/hyperledger/burrow/rpc/web3"
20+
"github.com/hyperledger/burrow/txs"
21+
"github.com/hyperledger/burrow/txs/payload"
2322
"github.com/stretchr/testify/require"
2423
)
2524

2625
var d = new(web3.HexDecoder).Must()
2726

27+
// Check we can force set a decimal ChainID
28+
const chainID = "15321"
29+
2830
func TestWeb3Service(t *testing.T) {
2931
ctx := context.Background()
3032
genesisAccounts := integration.MakePrivateAccounts("burrow", 1)
3133
genesisAccounts = append(genesisAccounts, integration.MakeEthereumAccounts("ethereum", 3)...)
3234
genesisDoc := integration.TestGenesisDoc(genesisAccounts, 0)
33-
35+
genesisDoc.ChainID = chainID
3436
config, _ := integration.NewTestConfig(genesisDoc)
3537
logger := logging.NewNoopLogger()
3638
kern, err := integration.TestKernel(genesisAccounts[0], genesisAccounts, config)
@@ -91,7 +93,7 @@ func TestWeb3Service(t *testing.T) {
9193
t.Run("NetVersion", func(t *testing.T) {
9294
result, err := eth.NetVersion()
9395
require.NoError(t, err)
94-
require.Equal(t, crypto.GetEthChainID(genesisDoc.ChainID()).String(), result.ChainID)
96+
require.Equal(t, web3.HexEncoder.BigInt(crypto.GetEthChainID(genesisDoc.GetChainID())), result.ChainID)
9597
})
9698

9799
t.Run("EthProtocolVersion", func(t *testing.T) {
@@ -104,7 +106,7 @@ func TestWeb3Service(t *testing.T) {
104106
result, err := eth.EthChainId()
105107
require.NoError(t, err)
106108
doc := config.GenesisDoc
107-
require.Equal(t, doc.ChainID(), result.ChainId)
109+
require.Equal(t, web3.HexEncoder.BigInt(crypto.GetEthChainID(doc.GetChainID())), result.ChainId)
108110
})
109111
})
110112

@@ -118,7 +120,7 @@ func TestWeb3Service(t *testing.T) {
118120
before := acc.GetBalance()
119121

120122
t.Run("EthSendRawTransaction", func(t *testing.T) {
121-
txEnv := txs.Enclose(genesisDoc.ChainID(), &payload.CallTx{
123+
txEnv := txs.Enclose(chainID, &payload.CallTx{
122124
Input: &payload.TxInput{
123125
Address: sender.GetAddress(),
124126
Amount: 1,

rpc/web3/hex.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ func (e *hexEncoder) BytesTrim(bs []byte) string {
9999
return "0x" + str
100100
}
101101

102-
func (e *hexEncoder) BigInt(x big.Int) string {
102+
func (e *hexEncoder) BigInt(x *big.Int) string {
103103
return e.BytesTrim(x.Bytes())
104104
}
105105

txs/ethereum_tx.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,8 @@ type EthRawTx struct {
2626
chainID *big.Int
2727
}
2828

29-
func NewEthRawTx(chainID string) *EthRawTx {
30-
return &EthRawTx{chainID: crypto.GetEthChainID(chainID)}
29+
func NewEthRawTx(chainID *big.Int) *EthRawTx {
30+
return &EthRawTx{chainID: chainID}
3131
}
3232

3333
func EthRawTxFromEnvelope(txEnv *Envelope) (*EthRawTx, error) {

0 commit comments

Comments
 (0)