diff --git a/account/account.go b/account/account.go index 03b9d3eb5..081dc1063 100644 --- a/account/account.go +++ b/account/account.go @@ -12,13 +12,13 @@ import ( // Signable is an interface for all signable things. // It typically removes signatures before serializing. type Signable interface { - WriteSignBytes(w io.Writer, n *int64, err *error) + WriteSignBytes(chainID string, w io.Writer, n *int64, err *error) } // SignBytes is a convenience method for getting the bytes to sign of a Signable. -func SignBytes(o Signable) []byte { +func SignBytes(chainID string, o Signable) []byte { buf, n, err := new(bytes.Buffer), new(int64), new(error) - o.WriteSignBytes(buf, n, err) + o.WriteSignBytes(chainID, buf, n, err) if *err != nil { panic(err) } @@ -26,8 +26,8 @@ func SignBytes(o Signable) []byte { } // HashSignBytes is a convenience method for getting the hash of the bytes of a signable -func HashSignBytes(o Signable) []byte { - return merkle.HashFromBinary(SignBytes(o)) +func HashSignBytes(chainID string, o Signable) []byte { + return merkle.HashFromBinary(SignBytes(chainID, o)) } //----------------------------------------------------------------------------- diff --git a/account/priv_account.go b/account/priv_account.go index ccd702b1f..ad4fc650b 100644 --- a/account/priv_account.go +++ b/account/priv_account.go @@ -52,8 +52,8 @@ func GenPrivAccountFromKey(privKeyBytes [64]byte) *PrivAccount { } } -func (privAccount *PrivAccount) Sign(o Signable) Signature { - return privAccount.PrivKey.Sign(SignBytes(o)) +func (privAccount *PrivAccount) Sign(chainID string, o Signable) Signature { + return privAccount.PrivKey.Sign(SignBytes(chainID, o)) } func (privAccount *PrivAccount) String() string { diff --git a/alert/alert.go b/alert/alert.go index 70393dd7b..c47633091 100644 --- a/alert/alert.go +++ b/alert/alert.go @@ -15,7 +15,7 @@ func Alert(message string) { log.Error(" ALERT \n" + message) now := time.Now().Unix() if now-lastAlertUnix > int64(config.GetInt("alert_min_interval")) { - message = fmt.Sprintf("%v:%v", config.GetString("network"), message) + message = fmt.Sprintf("%v:%v", config.GetString("chain_id"), message) if alertCountSince > 0 { message = fmt.Sprintf("%v (+%v more since)", message, alertCountSince) alertCountSince = 0 diff --git a/blockchain/reactor.go b/blockchain/reactor.go index e48da66f9..322ed5c32 100644 --- a/blockchain/reactor.go +++ b/blockchain/reactor.go @@ -232,7 +232,7 @@ FOR_LOOP: firstPartsHeader := firstParts.Header() // Finally, verify the first block using the second's validation. err := bcR.state.BondedValidators.VerifyValidation( - first.Hash(), firstPartsHeader, first.Height, second.Validation) + bcR.state.ChainID, first.Hash(), firstPartsHeader, first.Height, second.Validation) if err != nil { log.Debug("error in validation", "error", err) bcR.pool.RedoRequest(first.Height) diff --git a/cmd/tendermint/gen_tx.go b/cmd/tendermint/gen_tx.go index 687339bed..d499fad81 100644 --- a/cmd/tendermint/gen_tx.go +++ b/cmd/tendermint/gen_tx.go @@ -110,6 +110,6 @@ func gen_tx() { } // Sign - tx.Inputs[0].Signature = srcPrivKey.Sign(account.SignBytes(tx)) + tx.Inputs[0].Signature = srcPrivKey.Sign(account.SignBytes(config.GetString("chain_id"), tx)) fmt.Printf("Signed tx: %X\n", binary.BinaryBytes(tx)) } diff --git a/config/tendermint/config.go b/config/tendermint/config.go index 32be222a1..17dbfc9e3 100644 --- a/config/tendermint/config.go +++ b/config/tendermint/config.go @@ -51,13 +51,13 @@ func GetConfig(rootDir string) cfg.Config { } // Set defaults or panic - if !mapConfig.IsSet("network") { - Exit("Must set 'network'") + if mapConfig.IsSet("chain_id") { + Exit("Cannot set 'chain_id' via config.toml") } if mapConfig.IsSet("version") { Exit("Cannot set 'version' via config.toml") } - // mapConfig.SetDefault("network", "tendermint_testnet0") + mapConfig.SetDefault("chain_id", "tendermint_testnet_5") mapConfig.SetDefault("version", "0.3.0") // JAE: changed merkle tree persistence format for merkle proofs. mapConfig.SetDefault("genesis_file", rootDir+"/genesis.json") mapConfig.SetDefault("moniker", "anonymous") @@ -82,7 +82,6 @@ func ensureDefault(mapConfig cfg.MapConfig, key string, value interface{}) { var defaultConfigTmpl = `# This is a TOML config file. # For more information, see https://github.com/toml-lang/toml -network = "tendermint_testnet_5" moniker = "__MONIKER__" node_laddr = "0.0.0.0:46656" seeds = "goldenalchemist.chaintest.net:46656" @@ -98,6 +97,7 @@ func defaultConfig(moniker string) (defaultConfig string) { } var defaultGenesis = `{ + "chain_id": "tendermint_testnet_5", "accounts": [ { "address": "F81CB9ED0A868BD961C4F5BBC0E39B763B89FCB6", diff --git a/config/tendermint_test/config.go b/config/tendermint_test/config.go index 7f78a3c2c..418f026dc 100644 --- a/config/tendermint_test/config.go +++ b/config/tendermint_test/config.go @@ -60,13 +60,13 @@ func GetConfig(rootDir string) cfg.Config { } // Set defaults or panic - if !mapConfig.IsSet("network") { - Exit("Must set 'network'") + if mapConfig.IsSet("chain_id") { + Exit("Cannot set 'chain_id' via config.toml") } if mapConfig.IsSet("version") { Exit("Cannot set 'version' via config.toml") } - // mapConfig.SetDefault("network", "tendermint_testnet0") + mapConfig.SetDefault("chain_id", "tendermint_test") mapConfig.SetDefault("version", "0.3.0") mapConfig.SetDefault("genesis_file", rootDir+"/genesis.json") mapConfig.SetDefault("moniker", "anonymous") @@ -90,7 +90,6 @@ func ensureDefault(mapConfig cfg.MapConfig, key string, value interface{}) { var defaultConfigTmpl = `# This is a TOML config file. # For more information, see https://github.com/toml-lang/toml -network = "tendermint_test" moniker = "__MONIKER__" node_laddr = "0.0.0.0:36656" seeds = "" @@ -106,6 +105,7 @@ func defaultConfig(moniker string) (defaultConfig string) { } var defaultGenesis = `{ + "chain_id" : "tendermint_test", "accounts": [ { "address": "1D7A91CB32F758A02EBB9BE1FB6F8DEE56F90D42", diff --git a/consensus/pol.go b/consensus/pol.go index 433a6992f..7314eb48e 100644 --- a/consensus/pol.go +++ b/consensus/pol.go @@ -38,7 +38,7 @@ func (pol *POL) Verify(valSet *sm.ValidatorSet) error { } talliedVotingPower := uint64(0) - prevoteDoc := account.SignBytes(&types.Vote{ + prevoteDoc := account.SignBytes(config.GetString("chain_id"), &types.Vote{ Height: pol.Height, Round: pol.Round, Type: types.VoteTypePrevote, BlockHash: pol.BlockHash, BlockParts: pol.BlockParts, @@ -55,7 +55,7 @@ func (pol *POL) Verify(valSet *sm.ValidatorSet) error { // Commit vote? if vote.Round < pol.Round { - voteDoc = account.SignBytes(&types.Vote{ + voteDoc = account.SignBytes(config.GetString("chain_id"), &types.Vote{ Height: pol.Height, Round: vote.Round, Type: types.VoteTypeCommit, BlockHash: pol.BlockHash, BlockParts: pol.BlockParts, diff --git a/consensus/pol_test.go b/consensus/pol_test.go index db55bd5d2..5b56969d8 100644 --- a/consensus/pol_test.go +++ b/consensus/pol_test.go @@ -3,8 +3,8 @@ package consensus import ( "github.com/tendermint/tendermint/binary" . "github.com/tendermint/tendermint/common" - sm "github.com/tendermint/tendermint/state" _ "github.com/tendermint/tendermint/config/tendermint_test" + sm "github.com/tendermint/tendermint/state" "github.com/tendermint/tendermint/types" "bytes" @@ -18,7 +18,7 @@ import ( // Returns the POLVoteSignature pointer, so you can modify it afterwards. func signAddPOLVoteSignature(val *sm.PrivValidator, valSet *sm.ValidatorSet, vote *types.Vote, pol *POL) *POLVoteSignature { vote = vote.Copy() - err := val.SignVote(vote) + err := val.SignVote(config.GetString("chain_id"), vote) if err != nil { panic(err) } diff --git a/consensus/state.go b/consensus/state.go index 6b6d4ae24..de7b5fd20 100644 --- a/consensus/state.go +++ b/consensus/state.go @@ -536,7 +536,7 @@ func (cs *ConsensusState) updateToState(state *sm.State, contiguous bool) { Address: cs.privValidator.Address, Height: cs.Height, } - err := cs.privValidator.SignRebondTx(rebondTx) + err := cs.privValidator.SignRebondTx(cs.state.ChainID, rebondTx) if err == nil { err := cs.mempoolReactor.BroadcastTx(rebondTx) if err != nil { @@ -656,7 +656,7 @@ func (cs *ConsensusState) RunActionPropose(height uint, round uint) { txs := cs.mempoolReactor.Mempool.GetProposalTxs() block = &types.Block{ Header: &types.Header{ - Network: config.GetString("network"), + ChainID: cs.state.ChainID, Height: cs.Height, Time: time.Now(), Fees: 0, // TODO fees @@ -688,7 +688,7 @@ func (cs *ConsensusState) RunActionPropose(height uint, round uint) { // Make proposal proposal := NewProposal(cs.Height, cs.Round, blockParts.Header(), polParts.Header()) - err := cs.privValidator.SignProposal(proposal) + err := cs.privValidator.SignProposal(cs.state.ChainID, proposal) if err == nil { log.Info("Signed and set proposal", "height", cs.Height, "round", cs.Round, "proposal", proposal) log.Debug(Fmt("Signed and set proposal block: %v", block)) @@ -939,7 +939,7 @@ func (cs *ConsensusState) SetProposal(proposal *Proposal) error { } // Verify signature - if !cs.Validators.Proposer().PubKey.VerifyBytes(account.SignBytes(proposal), proposal.Signature) { + if !cs.Validators.Proposer().PubKey.VerifyBytes(account.SignBytes(cs.state.ChainID, proposal), proposal.Signature) { return ErrInvalidProposalSignature } @@ -1111,7 +1111,7 @@ func (cs *ConsensusState) signAddVote(type_ byte, hash []byte, header types.Part BlockHash: hash, BlockParts: header, } - err := cs.privValidator.SignVote(vote) + err := cs.privValidator.SignVote(cs.state.ChainID, vote) if err == nil { log.Info("Signed and added vote", "height", cs.Height, "round", cs.Round, "vote", vote) cs.addVote(cs.privValidator.Address, vote) diff --git a/consensus/state_test.go b/consensus/state_test.go index 8ab220393..af25ae016 100644 --- a/consensus/state_test.go +++ b/consensus/state_test.go @@ -16,7 +16,7 @@ func TestSetupRound(t *testing.T) { voteTypes := []byte{types.VoteTypePrevote, types.VoteTypePrecommit, types.VoteTypeCommit} for _, voteType := range voteTypes { vote := &types.Vote{Height: 1, Round: 0, Type: voteType} // nil vote - err := val0.SignVote(vote) + err := val0.SignVote(cs.state.ChainID, vote) if err != nil { t.Error("Error signing vote: %v", err) } @@ -124,7 +124,7 @@ func TestRunActionPrecommitCommitFinalize(t *testing.T) { BlockHash: cs.ProposalBlock.Hash(), BlockParts: cs.ProposalBlockParts.Header(), } - err := privValidators[i].SignVote(vote) + err := privValidators[i].SignVote(cs.state.ChainID, vote) if err != nil { t.Error("Error signing vote: %v", err) } @@ -154,7 +154,7 @@ func TestRunActionPrecommitCommitFinalize(t *testing.T) { BlockHash: cs.ProposalBlock.Hash(), BlockParts: cs.ProposalBlockParts.Header(), } - err := privValidators[i].SignVote(vote) + err := privValidators[i].SignVote(cs.state.ChainID, vote) if err != nil { t.Error("Error signing vote: %v", err) } @@ -192,7 +192,7 @@ func TestRunActionPrecommitCommitFinalize(t *testing.T) { BlockHash: cs.ProposalBlock.Hash(), BlockParts: cs.ProposalBlockParts.Header(), } - err := privValidators[i].SignVote(vote) + err := privValidators[i].SignVote(cs.state.ChainID, vote) if err != nil { t.Error("Error signing vote: %v", err) } diff --git a/consensus/types/proposal.go b/consensus/types/proposal.go index 0d6e018c2..a306f032a 100644 --- a/consensus/types/proposal.go +++ b/consensus/types/proposal.go @@ -38,9 +38,9 @@ func (p *Proposal) String() string { p.BlockParts, p.POLParts, p.Signature) } -func (p *Proposal) WriteSignBytes(w io.Writer, n *int64, err *error) { - // We hex encode the network name so we don't deal with escaping issues. - binary.WriteTo([]byte(Fmt(`{"network":"%X"`, config.GetString("network"))), w, n, err) +func (p *Proposal) WriteSignBytes(chainID string, w io.Writer, n *int64, err *error) { + // We hex encode the chain_id name so we don't deal with escaping issues. + binary.WriteTo([]byte(Fmt(`{"chain_id":"%X"`, chainID)), w, n, err) binary.WriteTo([]byte(`,"proposal":{"block_parts":`), w, n, err) p.BlockParts.WriteSignBytes(w, n, err) binary.WriteTo([]byte(Fmt(`,"height":%v,"pol_parts":`, p.Height)), w, n, err) diff --git a/consensus/types/proposal_test.go b/consensus/types/proposal_test.go index fea9f079a..fa8f37be3 100644 --- a/consensus/types/proposal_test.go +++ b/consensus/types/proposal_test.go @@ -17,10 +17,10 @@ func TestProposalSignable(t *testing.T) { POLParts: types.PartSetHeader{222, []byte("polparts")}, Signature: nil, } - signBytes := account.SignBytes(proposal) + signBytes := account.SignBytes(config.GetString("chain_id"), proposal) signStr := string(signBytes) - expected := Fmt(`{"network":"%X","proposal":{"block_parts":{"hash":"626C6F636B7061727473","total":111},"height":12345,"pol_parts":{"hash":"706F6C7061727473","total":222},"round":23456}}`, - config.GetString("network")) + expected := Fmt(`{"chain_id":"%X","proposal":{"block_parts":{"hash":"626C6F636B7061727473","total":111},"height":12345,"pol_parts":{"hash":"706F6C7061727473","total":222},"round":23456}}`, + config.GetString("chain_id")) if signStr != expected { t.Errorf("Got unexpected sign string for SendTx. Expected:\n%v\nGot:\n%v", expected, signStr) } diff --git a/consensus/vote_set.go b/consensus/vote_set.go index 21e986617..ca2f44eb8 100644 --- a/consensus/vote_set.go +++ b/consensus/vote_set.go @@ -93,7 +93,7 @@ func (voteSet *VoteSet) Add(address []byte, vote *types.Vote) (bool, uint, error } // Check signature. - if !val.PubKey.VerifyBytes(account.SignBytes(vote), vote.Signature) { + if !val.PubKey.VerifyBytes(account.SignBytes(config.GetString("chain_id"), vote), vote.Signature) { // Bad signature. return false, 0, types.ErrVoteInvalidSignature } diff --git a/consensus/vote_set_test.go b/consensus/vote_set_test.go index 2c94d682f..212fcf665 100644 --- a/consensus/vote_set_test.go +++ b/consensus/vote_set_test.go @@ -5,8 +5,8 @@ import ( . "github.com/tendermint/tendermint/common" . "github.com/tendermint/tendermint/common/test" - sm "github.com/tendermint/tendermint/state" _ "github.com/tendermint/tendermint/config/tendermint_test" + sm "github.com/tendermint/tendermint/state" "github.com/tendermint/tendermint/types" "testing" @@ -50,7 +50,7 @@ func withBlockParts(vote *types.Vote, blockParts types.PartSetHeader) *types.Vot } func signAddVote(privVal *sm.PrivValidator, vote *types.Vote, voteSet *VoteSet) (bool, error) { - privVal.SignVoteUnsafe(vote) + privVal.SignVoteUnsafe(config.GetString("chain_id"), vote) added, _, err := voteSet.Add(privVal.Address, vote) return added, err } diff --git a/crawler/crawl.go b/crawler/crawl.go index a3e5cf722..b337d320d 100644 --- a/crawler/crawl.go +++ b/crawler/crawl.go @@ -20,7 +20,7 @@ const ( //--------------------------------------------------------------------------------------- // crawler.Node -// A node is a peer on the network. +// A node is a peer on the network type Node struct { Host string P2PPort uint16 @@ -32,7 +32,7 @@ type Node struct { client *NodeClient LastSeen time.Time - Network string + ChainID string BlockHeight uint BlockHistory map[uint]time.Time // when we saw each block NetInfo *rpctypes.ResponseNetInfo @@ -47,10 +47,10 @@ func (n *Node) Address() string { return fmt.Sprintf("%s:%d", n.Host, n.RPCPort) } -// Set the basic status and network info for a node from RPC responses +// Set the basic status and chain_id info for a node from RPC responses func (n *Node) SetInfo(status *rpctypes.ResponseStatus, netinfo *rpctypes.ResponseNetInfo) { n.LastSeen = time.Now() - n.Network = status.Network + n.ChainID = status.ChainID n.BlockHeight = status.LatestBlockHeight n.NetInfo = netinfo // n.Validator diff --git a/node/id.go b/node/id.go index b65ea4ac1..2d52213f1 100644 --- a/node/id.go +++ b/node/id.go @@ -18,7 +18,7 @@ type PrivNodeID struct { type NodeGreeting struct { NodeID Version string - Network string + ChainID string Message string Time time.Time } diff --git a/node/node.go b/node/node.go index ed0816a08..aa6eb124d 100644 --- a/node/node.go +++ b/node/node.go @@ -56,6 +56,8 @@ func NewNode() *Node { state = sm.MakeGenesisStateFromFile(stateDB, config.GetString("genesis_file")) state.Save() } + // add the chainid to the global config + config.Set("chain_id", state.ChainID) // Get PrivValidator var privValidator *sm.PrivValidator @@ -212,7 +214,7 @@ func (n *Node) EventSwitch() *events.EventSwitch { func makeNodeInfo(sw *p2p.Switch) *types.NodeInfo { nodeInfo := &types.NodeInfo{ - Network: config.GetString("network"), + ChainID: config.GetString("chain_id"), Moniker: config.GetString("moniker"), Version: config.GetString("version"), } diff --git a/p2p/switch_test.go b/p2p/switch_test.go index 98bf4b4da..209defcc6 100644 --- a/p2p/switch_test.go +++ b/p2p/switch_test.go @@ -76,13 +76,13 @@ func makeSwitchPair(t testing.TB, initSwitch func(*Switch) *Switch) (*Switch, *S s1 := initSwitch(NewSwitch()) s1.SetNodeInfo(&types.NodeInfo{ Moniker: "switch1", - Network: "testing", + ChainID: "testing", Version: "123.123.123", }) s2 := initSwitch(NewSwitch()) s2.SetNodeInfo(&types.NodeInfo{ Moniker: "switch2", - Network: "testing", + ChainID: "testing", Version: "123.123.123", }) diff --git a/rpc/core/mempool.go b/rpc/core/mempool.go index 4fa935603..e4ae77096 100644 --- a/rpc/core/mempool.go +++ b/rpc/core/mempool.go @@ -17,7 +17,7 @@ func BroadcastTx(tx types.Tx) (*ctypes.ResponseBroadcastTx, error) { return nil, fmt.Errorf("Error broadcasting transaction: %v", err) } - txHash := types.TxId(tx) + txHash := types.TxId(mempoolReactor.Mempool.GetState().ChainID, tx) var createsContract uint8 var contractAddr []byte // check if creates new contract diff --git a/rpc/core/net.go b/rpc/core/net.go index 22811ddd6..f74510e78 100644 --- a/rpc/core/net.go +++ b/rpc/core/net.go @@ -1,6 +1,8 @@ package core import ( + "io/ioutil" + dbm "github.com/tendermint/tendermint/db" ctypes "github.com/tendermint/tendermint/rpc/core/types" sm "github.com/tendermint/tendermint/state" @@ -27,7 +29,7 @@ func Status() (*ctypes.ResponseStatus, error) { return &ctypes.ResponseStatus{ Moniker: config.GetString("moniker"), - Network: config.GetString("network"), + ChainID: config.GetString("chain_id"), Version: config.GetString("version"), GenesisHash: genesisHash, PubKey: privValidator.PubKey, @@ -57,3 +59,15 @@ func NetInfo() (*ctypes.ResponseNetInfo, error) { Peers: peers, }, nil } + +//----------------------------------------------------------------------------- + +// returns pointer because the rpc-gen code returns nil (TODO!) +func Genesis() (*string, error) { + b, err := ioutil.ReadFile(config.GetString("genesis_file")) + if err != nil { + return nil, err + } + ret := string(b) + return &ret, nil +} diff --git a/rpc/core/routes.go b/rpc/core/routes.go index e136a0100..f65d58e23 100644 --- a/rpc/core/routes.go +++ b/rpc/core/routes.go @@ -8,6 +8,7 @@ var Routes = map[string]*rpc.RPCFunc{ "status": rpc.NewRPCFunc(Status, []string{}), "net_info": rpc.NewRPCFunc(NetInfo, []string{}), "blockchain": rpc.NewRPCFunc(BlockchainInfo, []string{"minHeight", "maxHeight"}), + "genesis": rpc.NewRPCFunc(Genesis, []string{}), "get_block": rpc.NewRPCFunc(GetBlock, []string{"height"}), "get_account": rpc.NewRPCFunc(GetAccount, []string{"address"}), "get_storage": rpc.NewRPCFunc(GetStorage, []string{"address", "key"}), diff --git a/rpc/core/txs.go b/rpc/core/txs.go index e0c40a55e..07e14d94d 100644 --- a/rpc/core/txs.go +++ b/rpc/core/txs.go @@ -91,27 +91,27 @@ func SignTx(tx types.Tx, privAccounts []*account.PrivAccount) (*ctypes.ResponseS sendTx := tx.(*types.SendTx) for i, input := range sendTx.Inputs { input.PubKey = privAccounts[i].PubKey - input.Signature = privAccounts[i].Sign(sendTx) + input.Signature = privAccounts[i].Sign(config.GetString("chain_id"), sendTx) } case *types.CallTx: callTx := tx.(*types.CallTx) callTx.Input.PubKey = privAccounts[0].PubKey - callTx.Input.Signature = privAccounts[0].Sign(callTx) + callTx.Input.Signature = privAccounts[0].Sign(config.GetString("chain_id"), callTx) case *types.BondTx: bondTx := tx.(*types.BondTx) // the first privaccount corresponds to the BondTx pub key. // the rest to the inputs - bondTx.Signature = privAccounts[0].Sign(bondTx).(account.SignatureEd25519) + bondTx.Signature = privAccounts[0].Sign(config.GetString("chain_id"), bondTx).(account.SignatureEd25519) for i, input := range bondTx.Inputs { input.PubKey = privAccounts[i+1].PubKey - input.Signature = privAccounts[i+1].Sign(bondTx) + input.Signature = privAccounts[i+1].Sign(config.GetString("chain_id"), bondTx) } case *types.UnbondTx: unbondTx := tx.(*types.UnbondTx) - unbondTx.Signature = privAccounts[0].Sign(unbondTx).(account.SignatureEd25519) + unbondTx.Signature = privAccounts[0].Sign(config.GetString("chain_id"), unbondTx).(account.SignatureEd25519) case *types.RebondTx: rebondTx := tx.(*types.RebondTx) - rebondTx.Signature = privAccounts[0].Sign(rebondTx).(account.SignatureEd25519) + rebondTx.Signature = privAccounts[0].Sign(config.GetString("chain_id"), rebondTx).(account.SignatureEd25519) } return &ctypes.ResponseSignTx{tx}, nil } diff --git a/rpc/core/types/responses.go b/rpc/core/types/responses.go index 3934fcaab..9239695f2 100644 --- a/rpc/core/types/responses.go +++ b/rpc/core/types/responses.go @@ -66,7 +66,7 @@ type Receipt struct { type ResponseStatus struct { Moniker string `json:"moniker"` - Network string `json:"network"` + ChainID string `json:"chain_id"` Version string `json:"version"` GenesisHash []byte `json:"genesis_hash"` PubKey account.PubKey `json:"pub_key"` diff --git a/rpc/core_client/client_methods.go b/rpc/core_client/client_methods.go index e9593b189..aa48dcffd 100644 --- a/rpc/core_client/client_methods.go +++ b/rpc/core_client/client_methods.go @@ -21,6 +21,7 @@ type Client interface { DumpConsensusState() (*ctypes.ResponseDumpConsensusState, error) DumpStorage(address []byte) (*ctypes.ResponseDumpStorage, error) GenPrivAccount() (*ctypes.ResponseGenPrivAccount, error) + Genesis() (*string, error) GetAccount(address []byte) (*ctypes.ResponseGetAccount, error) GetBlock(height uint) (*ctypes.ResponseGetBlock, error) GetStorage(address []byte, key []byte) (*ctypes.ResponseGetStorage, error) @@ -242,6 +243,36 @@ func (c *ClientHTTP) GenPrivAccount() (*ctypes.ResponseGenPrivAccount, error) { return response.Result, nil } +func (c *ClientHTTP) Genesis() (*string, error) { + values, err := argsToURLValues(nil) + if err != nil { + return nil, err + } + resp, err := http.PostForm(c.addr+reverseFuncMap["Genesis"], values) + if err != nil { + return nil, err + } + defer resp.Body.Close() + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + var response struct { + Result *string `json:"result"` + Error string `json:"error"` + Id string `json:"id"` + JSONRPC string `json:"jsonrpc"` + } + binary.ReadJSON(&response, body, &err) + if err != nil { + return nil, err + } + if response.Error != "" { + return nil, fmt.Errorf(response.Error) + } + return response.Result, nil +} + func (c *ClientHTTP) GetAccount(address []byte) (*ctypes.ResponseGetAccount, error) { values, err := argsToURLValues([]string{"address"}, address) if err != nil { @@ -701,6 +732,33 @@ func (c *ClientJSON) GenPrivAccount() (*ctypes.ResponseGenPrivAccount, error) { return response.Result, nil } +func (c *ClientJSON) Genesis() (*string, error) { + request := rpctypes.RPCRequest{ + JSONRPC: "2.0", + Method: reverseFuncMap["Genesis"], + Params: []interface{}{}, + Id: 0, + } + body, err := c.RequestResponse(request) + if err != nil { + return nil, err + } + var response struct { + Result *string `json:"result"` + Error string `json:"error"` + Id string `json:"id"` + JSONRPC string `json:"jsonrpc"` + } + binary.ReadJSON(&response, body, &err) + if err != nil { + return nil, err + } + if response.Error != "" { + return nil, fmt.Errorf(response.Error) + } + return response.Result, nil +} + func (c *ClientJSON) GetAccount(address []byte) (*ctypes.ResponseGetAccount, error) { request := rpctypes.RPCRequest{ JSONRPC: "2.0", diff --git a/rpc/test/client_ws_test.go b/rpc/test/client_ws_test.go index a5d0880c7..5f94306b6 100644 --- a/rpc/test/client_ws_test.go +++ b/rpc/test/client_ws_test.go @@ -193,6 +193,6 @@ func TestWSCallCall(t *testing.T) { waitForEvent(t, con, eid1, true, func() { tx := makeDefaultCallTx(t, wsTyp, contractAddr2, nil, amt, gasLim, fee) broadcastTx(t, wsTyp, tx) - *txid = account.HashSignBytes(tx) + *txid = account.HashSignBytes(chainID, tx) }, unmarshalValidateCallCall(user[0].Address, returnVal, txid)) } diff --git a/rpc/test/helpers.go b/rpc/test/helpers.go index 8602c0bf5..da05ccfdc 100644 --- a/rpc/test/helpers.go +++ b/rpc/test/helpers.go @@ -32,6 +32,8 @@ var ( userPriv = "C453604BD6480D5538B4C6FD2E3E314B5BCE518D75ADE4DA3DA85AB8ADFD819606FBAC4E285285D1D91FCBC7E91C780ADA11516F67462340B3980CE2B94940E8" user = makeUsers(2) + chainID string + clients = map[string]cclient.Client{ "JSONRPC": cclient.NewClient(requestAddr, "JSONRPC"), "HTTP": cclient.NewClient(requestAddr, "HTTP"), @@ -74,6 +76,8 @@ func newNode(ready chan struct{}) { // initialize config and create new node func init() { + chainID = config.GetString("chain_id") + // Save new priv_validator file. priv := &state.PrivValidator{ Address: user[0].Address, @@ -83,7 +87,7 @@ func init() { priv.SetFile(config.GetString("priv_validator_file")) priv.Save() - consensus.RoundDuration0 = 3 * time.Second + consensus.RoundDuration0 = 2 * time.Second consensus.RoundDurationDelta = 1 * time.Second // start a node @@ -105,14 +109,14 @@ func makeDefaultSendTx(t *testing.T, typ string, addr []byte, amt uint64) *types func makeDefaultSendTxSigned(t *testing.T, typ string, addr []byte, amt uint64) *types.SendTx { tx := makeDefaultSendTx(t, typ, addr, amt) - tx.SignInput(0, user[0]) + tx.SignInput(chainID, 0, user[0]) return tx } func makeDefaultCallTx(t *testing.T, typ string, addr, code []byte, amt, gasLim, fee uint64) *types.CallTx { nonce := getNonce(t, typ, user[0].Address) tx := types.NewCallTxWithNonce(user[0].PubKey, addr, code, amt, gasLim, fee, nonce) - tx.Sign(user[0]) + tx.Sign(chainID, user[0]) return tx } @@ -214,7 +218,7 @@ func checkTx(t *testing.T, fromAddr []byte, priv *account.PrivAccount, tx *types t.Fatal("Tx input addresses don't match!") } - signBytes := account.SignBytes(tx) + signBytes := account.SignBytes(chainID, tx) in := tx.Inputs[0] //(*types.SendTx).Inputs[0] if err := in.ValidateBasic(); err != nil { diff --git a/rpc/test/tests.go b/rpc/test/tests.go index 40819e0b1..ca9221ea3 100644 --- a/rpc/test/tests.go +++ b/rpc/test/tests.go @@ -15,9 +15,9 @@ func testStatus(t *testing.T, typ string) { if err != nil { t.Fatal(err) } - if resp.Network != config.GetString("network") { - t.Fatal(fmt.Errorf("Network mismatch: got %s expected %s", - resp.Network, config.Get("network"))) + if resp.ChainID != chainID { + t.Fatal(fmt.Errorf("ChainID mismatch: got %s expected %s", + resp.ChainID, chainID)) } } @@ -57,9 +57,9 @@ func testSignedTx(t *testing.T, typ string) { func testOneSignTx(t *testing.T, typ string, addr []byte, amt uint64) { tx := makeDefaultSendTx(t, typ, addr, amt) tx2 := signTx(t, typ, tx, user[0]) - tx2hash := account.HashSignBytes(tx2) - tx.SignInput(0, user[0]) - txhash := account.HashSignBytes(tx) + tx2hash := account.HashSignBytes(chainID, tx2) + tx.SignInput(chainID, 0, user[0]) + txhash := account.HashSignBytes(chainID, tx) if bytes.Compare(txhash, tx2hash) != 0 { t.Fatal("Got different signatures for signing via rpc vs tx_utils") } @@ -88,8 +88,8 @@ func testBroadcastTx(t *testing.T, typ string) { tx2 := txs[mempoolCount-1].(*types.SendTx) n, err := new(int64), new(error) buf1, buf2 := new(bytes.Buffer), new(bytes.Buffer) - tx.WriteSignBytes(buf1, n, err) - tx2.WriteSignBytes(buf2, n, err) + tx.WriteSignBytes(chainID, buf1, n, err) + tx2.WriteSignBytes(chainID, buf2, n, err) if bytes.Compare(buf1.Bytes(), buf2.Bytes()) != 0 { t.Fatal("inconsistent hashes for mempool tx and sent tx") } diff --git a/state/execution.go b/state/execution.go index 9b6c35be7..e46a2150b 100644 --- a/state/execution.go +++ b/state/execution.go @@ -33,7 +33,7 @@ func ExecBlock(s *State, block *types.Block, blockPartsHeader types.PartSetHeade // at an invalid state. Copy the state before calling execBlock! func execBlock(s *State, block *types.Block, blockPartsHeader types.PartSetHeader) error { // Basic block validation. - err := block.ValidateBasic(s.LastBlockHeight, s.LastBlockHash, s.LastBlockParts, s.LastBlockTime) + err := block.ValidateBasic(s.ChainID, s.LastBlockHeight, s.LastBlockHash, s.LastBlockParts, s.LastBlockTime) if err != nil { return err } @@ -61,7 +61,7 @@ func execBlock(s *State, block *types.Block, blockPartsHeader types.PartSetHeade BlockHash: block.LastBlockHash, BlockParts: block.LastBlockParts, } - if val.PubKey.VerifyBytes(account.SignBytes(vote), commit.Signature) { + if val.PubKey.VerifyBytes(account.SignBytes(s.ChainID, vote), commit.Signature) { sumVotingPower += val.VotingPower return false } else { @@ -305,7 +305,7 @@ func ExecTx(blockCache *BlockCache, tx_ types.Tx, runCall bool, evc events.Firea if err != nil { return err } - signBytes := account.SignBytes(tx) + signBytes := account.SignBytes(_s.ChainID, tx) inTotal, err := validateInputs(accounts, signBytes, tx.Inputs) if err != nil { return err @@ -353,7 +353,7 @@ func ExecTx(blockCache *BlockCache, tx_ types.Tx, runCall bool, evc events.Firea log.Debug(Fmt("Can't find pubkey for %X", tx.Input.Address)) return err } - signBytes := account.SignBytes(tx) + signBytes := account.SignBytes(_s.ChainID, tx) err := validateInput(inAcc, signBytes, tx.Input) if err != nil { log.Debug(Fmt("validateInput failed on %X:", tx.Input.Address)) @@ -433,7 +433,7 @@ func ExecTx(blockCache *BlockCache, tx_ types.Tx, runCall bool, evc events.Firea txCache.UpdateAccount(caller) // because we adjusted by input above, and bumped nonce maybe. txCache.UpdateAccount(callee) // because we adjusted by input above. - vmach := vm.NewVM(txCache, params, caller.Address, account.HashSignBytes(tx)) + vmach := vm.NewVM(txCache, params, caller.Address, account.HashSignBytes(_s.ChainID, tx)) vmach.SetFireable(evc) // NOTE: Call() transfers the value from caller to callee iff call succeeds. @@ -490,7 +490,7 @@ func ExecTx(blockCache *BlockCache, tx_ types.Tx, runCall bool, evc events.Firea return err } - signBytes := account.SignBytes(tx) + signBytes := account.SignBytes(_s.ChainID, tx) inTotal, err := validateInputs(accounts, signBytes, tx.Inputs) if err != nil { return err @@ -548,7 +548,7 @@ func ExecTx(blockCache *BlockCache, tx_ types.Tx, runCall bool, evc events.Firea } // Verify the signature - signBytes := account.SignBytes(tx) + signBytes := account.SignBytes(_s.ChainID, tx) if !val.PubKey.VerifyBytes(signBytes, tx.Signature) { return types.ErrTxInvalidSignature } @@ -573,7 +573,7 @@ func ExecTx(blockCache *BlockCache, tx_ types.Tx, runCall bool, evc events.Firea } // Verify the signature - signBytes := account.SignBytes(tx) + signBytes := account.SignBytes(_s.ChainID, tx) if !val.PubKey.VerifyBytes(signBytes, tx.Signature) { return types.ErrTxInvalidSignature } @@ -599,8 +599,8 @@ func ExecTx(blockCache *BlockCache, tx_ types.Tx, runCall bool, evc events.Firea return types.ErrTxInvalidAddress } } - voteASignBytes := account.SignBytes(&tx.VoteA) - voteBSignBytes := account.SignBytes(&tx.VoteB) + voteASignBytes := account.SignBytes(_s.ChainID, &tx.VoteA) + voteBSignBytes := account.SignBytes(_s.ChainID, &tx.VoteB) if !accused.PubKey.VerifyBytes(voteASignBytes, tx.VoteA.Signature) || !accused.PubKey.VerifyBytes(voteBSignBytes, tx.VoteB.Signature) { return types.ErrTxInvalidSignature diff --git a/state/genesis.go b/state/genesis.go index f43c22ef1..691597ce0 100644 --- a/state/genesis.go +++ b/state/genesis.go @@ -25,6 +25,7 @@ type GenesisValidator struct { type GenesisDoc struct { GenesisTime time.Time `json:"genesis_time"` + ChainID string `json:"chain_id"` Accounts []GenesisAccount `json:"accounts"` Validators []GenesisValidator `json:"validators"` } @@ -105,6 +106,7 @@ func MakeGenesisState(db dbm.DB, genDoc *GenesisDoc) *State { return &State{ DB: db, + ChainID: genDoc.ChainID, LastBlockHeight: 0, LastBlockHash: nil, LastBlockParts: types.PartSetHeader{}, diff --git a/state/priv_validator.go b/state/priv_validator.go index 607a789ed..6ddfb3b4b 100644 --- a/state/priv_validator.go +++ b/state/priv_validator.go @@ -109,7 +109,7 @@ func (privVal *PrivValidator) save() { } // TODO: test -func (privVal *PrivValidator) SignVote(vote *types.Vote) error { +func (privVal *PrivValidator) SignVote(chainID string, vote *types.Vote) error { privVal.mtx.Lock() defer privVal.mtx.Unlock() @@ -140,15 +140,15 @@ func (privVal *PrivValidator) SignVote(vote *types.Vote) error { privVal.save() // Sign - privVal.SignVoteUnsafe(vote) + privVal.SignVoteUnsafe(chainID, vote) return nil } -func (privVal *PrivValidator) SignVoteUnsafe(vote *types.Vote) { - vote.Signature = privVal.PrivKey.Sign(account.SignBytes(vote)).(account.SignatureEd25519) +func (privVal *PrivValidator) SignVoteUnsafe(chainID string, vote *types.Vote) { + vote.Signature = privVal.PrivKey.Sign(account.SignBytes(chainID, vote)).(account.SignatureEd25519) } -func (privVal *PrivValidator) SignProposal(proposal *Proposal) error { +func (privVal *PrivValidator) SignProposal(chainID string, proposal *Proposal) error { privVal.mtx.Lock() defer privVal.mtx.Unlock() if privVal.LastHeight < proposal.Height || @@ -162,14 +162,14 @@ func (privVal *PrivValidator) SignProposal(proposal *Proposal) error { privVal.save() // Sign - proposal.Signature = privVal.PrivKey.Sign(account.SignBytes(proposal)).(account.SignatureEd25519) + proposal.Signature = privVal.PrivKey.Sign(account.SignBytes(chainID, proposal)).(account.SignatureEd25519) return nil } else { return errors.New(fmt.Sprintf("Attempt of duplicate signing of proposal: Height %v, Round %v", proposal.Height, proposal.Round)) } } -func (privVal *PrivValidator) SignRebondTx(rebondTx *types.RebondTx) error { +func (privVal *PrivValidator) SignRebondTx(chainID string, rebondTx *types.RebondTx) error { privVal.mtx.Lock() defer privVal.mtx.Unlock() if privVal.LastHeight < rebondTx.Height { @@ -181,7 +181,7 @@ func (privVal *PrivValidator) SignRebondTx(rebondTx *types.RebondTx) error { privVal.save() // Sign - rebondTx.Signature = privVal.PrivKey.Sign(account.SignBytes(rebondTx)).(account.SignatureEd25519) + rebondTx.Signature = privVal.PrivKey.Sign(account.SignBytes(chainID, rebondTx)).(account.SignatureEd25519) return nil } else { return errors.New(fmt.Sprintf("Attempt of duplicate signing of rebondTx: Height %v", rebondTx.Height)) diff --git a/state/state.go b/state/state.go index 182d2692b..13bd7d74d 100644 --- a/state/state.go +++ b/state/state.go @@ -26,6 +26,7 @@ var ( // NOTE: not goroutine-safe. type State struct { DB dbm.DB + ChainID string LastBlockHeight uint LastBlockHash []byte LastBlockParts types.PartSetHeader @@ -46,6 +47,7 @@ func LoadState(db dbm.DB) *State { return nil } else { r, n, err := bytes.NewReader(buf), new(int64), new(error) + s.ChainID = binary.ReadString(r, n, err) s.LastBlockHeight = binary.ReadUvarint(r, n, err) s.LastBlockHash = binary.ReadByteSlice(r, n, err) s.LastBlockParts = binary.ReadBinary(types.PartSetHeader{}, r, n, err).(types.PartSetHeader) @@ -71,6 +73,7 @@ func (s *State) Save() { s.accounts.Save() s.validatorInfos.Save() buf, n, err := new(bytes.Buffer), new(int64), new(error) + binary.WriteString(s.ChainID, buf, n, err) binary.WriteUvarint(s.LastBlockHeight, buf, n, err) binary.WriteByteSlice(s.LastBlockHash, buf, n, err) binary.WriteBinary(s.LastBlockParts, buf, n, err) @@ -92,6 +95,7 @@ func (s *State) Save() { func (s *State) Copy() *State { return &State{ DB: s.DB, + ChainID: s.ChainID, LastBlockHeight: s.LastBlockHeight, LastBlockHash: s.LastBlockHash, LastBlockParts: s.LastBlockParts, diff --git a/state/state_test.go b/state/state_test.go index d11c5cc5c..a2fb2b78a 100644 --- a/state/state_test.go +++ b/state/state_test.go @@ -65,7 +65,7 @@ func TestCopyState(t *testing.T) { func makeBlock(t *testing.T, state *State, commits []types.Commit, txs []types.Tx) *types.Block { block := &types.Block{ Header: &types.Header{ - Network: "tendermint_test", + ChainID: state.ChainID, Height: state.LastBlockHeight + 1, Time: state.LastBlockTime.Add(time.Minute), Fees: 0, @@ -191,7 +191,7 @@ func TestTxSequence(t *testing.T) { for i := -1; i < 3; i++ { sequence := acc0.Sequence + uint(i) tx := makeSendTx(sequence) - tx.Inputs[0].Signature = privAccounts[0].Sign(tx) + tx.Inputs[0].Signature = privAccounts[0].Sign(state.ChainID, tx) stateCopy := state.Copy() err := execTxWithState(stateCopy, tx, true) if i == 1 { @@ -251,7 +251,7 @@ func TestTxs(t *testing.T) { }, } - tx.Inputs[0].Signature = privAccounts[0].Sign(tx) + tx.Inputs[0].Signature = privAccounts[0].Sign(state.ChainID, tx) err := execTxWithState(state, tx, true) if err != nil { t.Errorf("Got error in executing send transaction, %v", err) @@ -288,8 +288,8 @@ func TestTxs(t *testing.T) { }, }, } - tx.Signature = privAccounts[0].Sign(tx).(account.SignatureEd25519) - tx.Inputs[0].Signature = privAccounts[0].Sign(tx) + tx.Signature = privAccounts[0].Sign(state.ChainID, tx).(account.SignatureEd25519) + tx.Inputs[0].Signature = privAccounts[0].Sign(state.ChainID, tx) err := execTxWithState(state, tx, true) if err != nil { t.Errorf("Got error in executing bond transaction, %v", err) @@ -345,8 +345,8 @@ func TestAddValidator(t *testing.T) { }, }, } - bondTx.Signature = acc0.Sign(bondTx).(account.SignatureEd25519) - bondTx.Inputs[0].Signature = acc0.Sign(bondTx) + bondTx.Signature = acc0.Sign(s0.ChainID, bondTx).(account.SignatureEd25519) + bondTx.Inputs[0].Signature = acc0.Sign(s0.ChainID, bondTx) // Make complete block and blockParts block0 := makeBlock(t, s0, nil, []types.Tx{bondTx}) @@ -380,7 +380,7 @@ func TestAddValidator(t *testing.T) { BlockHash: block0.Hash(), BlockParts: block0Parts.Header(), } - privValidators[0].SignVote(commit0) + privValidators[0].SignVote(s0.ChainID, commit0) block1 := makeBlock(t, s0, []types.Commit{ diff --git a/state/test.go b/state/test.go index efb425fbf..8e0f3520a 100644 --- a/state/test.go +++ b/state/test.go @@ -97,6 +97,7 @@ func RandGenesisState(numAccounts int, randBalance bool, minBalance uint64, numV sort.Sort(PrivValidatorsByAddress(privValidators)) s0 := MakeGenesisState(db, &GenesisDoc{ GenesisTime: time.Now(), + ChainID: "tendermint_test", Accounts: accounts, Validators: validators, }) diff --git a/state/validator_set.go b/state/validator_set.go index 2d247313b..a7cede7cc 100644 --- a/state/validator_set.go +++ b/state/validator_set.go @@ -201,7 +201,7 @@ func (valSet *ValidatorSet) Iterate(fn func(index uint, val *Validator) bool) { } // Verify that +2/3 of the set had signed the given signBytes -func (valSet *ValidatorSet) VerifyValidation(hash []byte, parts types.PartSetHeader, height uint, v *types.Validation) error { +func (valSet *ValidatorSet) VerifyValidation(chainID string, hash []byte, parts types.PartSetHeader, height uint, v *types.Validation) error { if valSet.Size() != uint(len(v.Commits)) { return errors.New(Fmt("Invalid validation -- wrong set size: %v vs %v", valSet.Size(), len(v.Commits))) @@ -216,7 +216,7 @@ func (valSet *ValidatorSet) VerifyValidation(hash []byte, parts types.PartSetHea continue } _, val := valSet.GetByIndex(uint(idx)) - commitSignBytes := account.SignBytes(&types.Vote{ + commitSignBytes := account.SignBytes(chainID, &types.Vote{ Height: height, Round: commit.Round, Type: types.VoteTypeCommit, BlockHash: hash, BlockParts: parts, diff --git a/types/block.go b/types/block.go index 8ef46950b..eef5fe89a 100644 --- a/types/block.go +++ b/types/block.go @@ -21,10 +21,10 @@ type Block struct { } // Basic validation that doesn't involve state data. -func (b *Block) ValidateBasic(lastBlockHeight uint, lastBlockHash []byte, +func (b *Block) ValidateBasic(chainID string, lastBlockHeight uint, lastBlockHash []byte, lastBlockParts PartSetHeader, lastBlockTime time.Time) error { - if b.Network != config.GetString("network") { - return errors.New("Wrong Block.Header.Network") + if b.ChainID != chainID { + return errors.New("Wrong Block.Header.ChainID") } if b.Height != lastBlockHeight+1 { return errors.New("Wrong Block.Header.Height") @@ -122,7 +122,7 @@ func (b *Block) StringShort() string { //----------------------------------------------------------------------------- type Header struct { - Network string `json:"network"` + ChainID string `json:"chain_id"` Height uint `json:"height"` Time time.Time `json:"time"` Fees uint64 `json:"fees"` @@ -154,7 +154,7 @@ func (h *Header) StringIndented(indent string) string { return "nil-Header" } return fmt.Sprintf(`Header{ -%s Network: %v +%s ChainID: %v %s Height: %v %s Time: %v %s Fees: %v @@ -163,7 +163,7 @@ func (h *Header) StringIndented(indent string) string { %s LastBlockParts: %v %s StateHash: %X %s}#%X`, - indent, h.Network, + indent, h.ChainID, indent, h.Height, indent, h.Time, indent, h.Fees, @@ -276,7 +276,7 @@ func (data *Data) Hash() []byte { if data.hash == nil { bs := make([]interface{}, len(data.Txs)) for i, tx := range data.Txs { - bs[i] = account.SignBytes(tx) + bs[i] = account.SignBytes(config.GetString("chain_id"), tx) } data.hash = merkle.HashFromBinaries(bs) } diff --git a/types/node.go b/types/node.go index b42e4bbb4..8cb1255a0 100644 --- a/types/node.go +++ b/types/node.go @@ -7,7 +7,7 @@ import ( type NodeInfo struct { Moniker string `json:"moniker"` - Network string `json:"network"` + ChainID string `json:"chain_id"` Version string `json:"version"` Host string `json:"host"` @@ -39,9 +39,9 @@ func (ni *NodeInfo) CompatibleWith(no *NodeInfo) error { return fmt.Errorf("Peer is on a different minor version. Got %v, expected %v", om, im) } - // nodes must be on the same network - if ni.Network != no.Network { - return fmt.Errorf("Peer is on a different network. Got %v, expected %v", no.Network, ni.Network) + // nodes must be on the same chain_id + if ni.ChainID != no.ChainID { + return fmt.Errorf("Peer is on a different chain_id. Got %v, expected %v", no.ChainID, ni.ChainID) } return nil diff --git a/types/tx.go b/types/tx.go index 3331eafa1..2d365881f 100644 --- a/types/tx.go +++ b/types/tx.go @@ -42,7 +42,7 @@ Validation Txs: - DupeoutTx Validator dupes out (equivocates) */ type Tx interface { - WriteSignBytes(w io.Writer, n *int64, err *error) + WriteSignBytes(chainID string, w io.Writer, n *int64, err *error) } // Types of Tx implementations @@ -129,9 +129,9 @@ type SendTx struct { Outputs []*TxOutput `json:"outputs"` } -func (tx *SendTx) WriteSignBytes(w io.Writer, n *int64, err *error) { - // We hex encode the network name so we don't deal with escaping issues. - binary.WriteTo([]byte(Fmt(`{"network":"%X"`, config.GetString("network"))), w, n, err) +func (tx *SendTx) WriteSignBytes(chainID string, w io.Writer, n *int64, err *error) { + // We hex encode the chain_id so we don't deal with escaping issues. + binary.WriteTo([]byte(Fmt(`{"chain_id":"%X"`, chainID)), w, n, err) binary.WriteTo([]byte(Fmt(`,"tx":[%v,{"inputs":[`, TxTypeSend)), w, n, err) for i, in := range tx.Inputs { in.WriteSignBytes(w, n, err) @@ -163,9 +163,9 @@ type CallTx struct { Data []byte `json:"data"` } -func (tx *CallTx) WriteSignBytes(w io.Writer, n *int64, err *error) { - // We hex encode the network name so we don't deal with escaping issues. - binary.WriteTo([]byte(Fmt(`{"network":"%X"`, config.GetString("network"))), w, n, err) +func (tx *CallTx) WriteSignBytes(chainID string, w io.Writer, n *int64, err *error) { + // We hex encode the chain_id so we don't deal with escaping issues. + binary.WriteTo([]byte(Fmt(`{"chain_id":"%X"`, chainID)), w, n, err) binary.WriteTo([]byte(Fmt(`,"tx":[%v,{"address":"%X","data":"%X"`, TxTypeCall, tx.Address, tx.Data)), w, n, err) binary.WriteTo([]byte(Fmt(`,"fee":%v,"gas_limit":%v,"input":`, tx.Fee, tx.GasLimit)), w, n, err) tx.Input.WriteSignBytes(w, n, err) @@ -185,9 +185,9 @@ type BondTx struct { UnbondTo []*TxOutput `json:"unbond_to"` } -func (tx *BondTx) WriteSignBytes(w io.Writer, n *int64, err *error) { - // We hex encode the network name so we don't deal with escaping issues. - binary.WriteTo([]byte(Fmt(`{"network":"%X"`, config.GetString("network"))), w, n, err) +func (tx *BondTx) WriteSignBytes(chainID string, w io.Writer, n *int64, err *error) { + // We hex encode the chain_id so we don't deal with escaping issues. + binary.WriteTo([]byte(Fmt(`{"chain_id":"%X"`, chainID)), w, n, err) binary.WriteTo([]byte(Fmt(`,"tx":[%v,{"inputs":[`, TxTypeBond)), w, n, err) for i, in := range tx.Inputs { in.WriteSignBytes(w, n, err) @@ -219,9 +219,9 @@ type UnbondTx struct { Signature account.SignatureEd25519 `json:"signature"` } -func (tx *UnbondTx) WriteSignBytes(w io.Writer, n *int64, err *error) { - // We hex encode the network name so we don't deal with escaping issues. - binary.WriteTo([]byte(Fmt(`{"network":"%X"`, config.GetString("network"))), w, n, err) +func (tx *UnbondTx) WriteSignBytes(chainID string, w io.Writer, n *int64, err *error) { + // We hex encode the chain_id so we don't deal with escaping issues. + binary.WriteTo([]byte(Fmt(`{"chain_id":"%X"`, chainID)), w, n, err) binary.WriteTo([]byte(Fmt(`,"tx":[%v,{"address":"%X","height":%v}]}`, TxTypeUnbond, tx.Address, tx.Height)), w, n, err) } @@ -237,9 +237,9 @@ type RebondTx struct { Signature account.SignatureEd25519 `json:"signature"` } -func (tx *RebondTx) WriteSignBytes(w io.Writer, n *int64, err *error) { - // We hex encode the network name so we don't deal with escaping issues. - binary.WriteTo([]byte(Fmt(`{"network":"%X"`, config.GetString("network"))), w, n, err) +func (tx *RebondTx) WriteSignBytes(chainID string, w io.Writer, n *int64, err *error) { + // We hex encode the chain_id so we don't deal with escaping issues. + binary.WriteTo([]byte(Fmt(`{"chain_id":"%X"`, chainID)), w, n, err) binary.WriteTo([]byte(Fmt(`,"tx":[%v,{"address":"%X","height":%v}]}`, TxTypeRebond, tx.Address, tx.Height)), w, n, err) } @@ -255,7 +255,7 @@ type DupeoutTx struct { VoteB Vote `json:"vote_b"` } -func (tx *DupeoutTx) WriteSignBytes(w io.Writer, n *int64, err *error) { +func (tx *DupeoutTx) WriteSignBytes(chainID string, w io.Writer, n *int64, err *error) { panic("DupeoutTx has no sign bytes") } @@ -265,7 +265,7 @@ func (tx *DupeoutTx) String() string { //----------------------------------------------------------------------------- -func TxId(tx Tx) []byte { - signBytes := account.SignBytes(tx) +func TxId(chainID string, tx Tx) []byte { + signBytes := account.SignBytes(chainID, tx) return binary.BinaryRipemd160(signBytes) } diff --git a/types/tx_test.go b/types/tx_test.go index edc5b8685..5ac1f908d 100644 --- a/types/tx_test.go +++ b/types/tx_test.go @@ -8,6 +8,12 @@ import ( _ "github.com/tendermint/tendermint/config/tendermint_test" ) +var chainID string + +func init() { + chainID = config.GetString("chain_id") +} + func TestSendTxSignable(t *testing.T) { sendTx := &SendTx{ Inputs: []*TxInput{ @@ -33,10 +39,10 @@ func TestSendTxSignable(t *testing.T) { }, }, } - signBytes := account.SignBytes(sendTx) + signBytes := account.SignBytes(chainID, sendTx) signStr := string(signBytes) - expected := Fmt(`{"network":"%X","tx":[1,{"inputs":[{"address":"696E70757431","amount":12345,"sequence":67890},{"address":"696E70757432","amount":111,"sequence":222}],"outputs":[{"address":"6F757470757431","amount":333},{"address":"6F757470757432","amount":444}]}]}`, - config.GetString("network")) + expected := Fmt(`{"chain_id":"%X","tx":[1,{"inputs":[{"address":"696E70757431","amount":12345,"sequence":67890},{"address":"696E70757432","amount":111,"sequence":222}],"outputs":[{"address":"6F757470757431","amount":333},{"address":"6F757470757432","amount":444}]}]}`, + config.GetString("chain_id")) if signStr != expected { t.Errorf("Got unexpected sign string for SendTx. Expected:\n%v\nGot:\n%v", expected, signStr) } @@ -54,10 +60,10 @@ func TestCallTxSignable(t *testing.T) { Fee: 222, Data: []byte("data1"), } - signBytes := account.SignBytes(callTx) + signBytes := account.SignBytes(chainID, callTx) signStr := string(signBytes) - expected := Fmt(`{"network":"%X","tx":[2,{"address":"636F6E747261637431","data":"6461746131","fee":222,"gas_limit":111,"input":{"address":"696E70757431","amount":12345,"sequence":67890}}]}`, - config.GetString("network")) + expected := Fmt(`{"chain_id":"%X","tx":[2,{"address":"636F6E747261637431","data":"6461746131","fee":222,"gas_limit":111,"input":{"address":"696E70757431","amount":12345,"sequence":67890}}]}`, + config.GetString("chain_id")) if signStr != expected { t.Errorf("Got unexpected sign string for CallTx. Expected:\n%v\nGot:\n%v", expected, signStr) } @@ -90,10 +96,10 @@ func TestBondTxSignable(t *testing.T) { }, }, } - signBytes := account.SignBytes(bondTx) + signBytes := account.SignBytes(chainID, bondTx) signStr := string(signBytes) - expected := Fmt(`{"network":"%X","tx":[17,{"inputs":[{"address":"696E70757431","amount":12345,"sequence":67890},{"address":"696E70757432","amount":111,"sequence":222}],"pub_key":[1,"3B6A27BCCEB6A42D62A3A8D02A6F0D73653215771DE243A63AC048A18B59DA29"],"unbond_to":[{"address":"6F757470757431","amount":333},{"address":"6F757470757432","amount":444}]}]}`, - config.GetString("network")) + expected := Fmt(`{"chain_id":"%X","tx":[17,{"inputs":[{"address":"696E70757431","amount":12345,"sequence":67890},{"address":"696E70757432","amount":111,"sequence":222}],"pub_key":[1,"3B6A27BCCEB6A42D62A3A8D02A6F0D73653215771DE243A63AC048A18B59DA29"],"unbond_to":[{"address":"6F757470757431","amount":333},{"address":"6F757470757432","amount":444}]}]}`, + config.GetString("chain_id")) if signStr != expected { t.Errorf("Got unexpected sign string for BondTx") } @@ -104,10 +110,10 @@ func TestUnbondTxSignable(t *testing.T) { Address: []byte("address1"), Height: 111, } - signBytes := account.SignBytes(unbondTx) + signBytes := account.SignBytes(chainID, unbondTx) signStr := string(signBytes) - expected := Fmt(`{"network":"%X","tx":[18,{"address":"6164647265737331","height":111}]}`, - config.GetString("network")) + expected := Fmt(`{"chain_id":"%X","tx":[18,{"address":"6164647265737331","height":111}]}`, + config.GetString("chain_id")) if signStr != expected { t.Errorf("Got unexpected sign string for UnbondTx") } @@ -118,10 +124,10 @@ func TestRebondTxSignable(t *testing.T) { Address: []byte("address1"), Height: 111, } - signBytes := account.SignBytes(rebondTx) + signBytes := account.SignBytes(chainID, rebondTx) signStr := string(signBytes) - expected := Fmt(`{"network":"%X","tx":[19,{"address":"6164647265737331","height":111}]}`, - config.GetString("network")) + expected := Fmt(`{"chain_id":"%X","tx":[19,{"address":"6164647265737331","height":111}]}`, + config.GetString("chain_id")) if signStr != expected { t.Errorf("Got unexpected sign string for RebondTx") } diff --git a/types/tx_utils.go b/types/tx_utils.go index 29a7b3ab3..eb5491ad1 100644 --- a/types/tx_utils.go +++ b/types/tx_utils.go @@ -56,12 +56,12 @@ func (tx *SendTx) AddOutput(addr []byte, amt uint64) error { return nil } -func (tx *SendTx) SignInput(i int, privAccount *account.PrivAccount) error { +func (tx *SendTx) SignInput(chainID string, i int, privAccount *account.PrivAccount) error { if i >= len(tx.Inputs) { return fmt.Errorf("Index %v is greater than number of inputs (%v)", i, len(tx.Inputs)) } tx.Inputs[i].PubKey = privAccount.PubKey - tx.Inputs[i].Signature = privAccount.Sign(tx) + tx.Inputs[i].Signature = privAccount.Sign(chainID, tx) return nil } @@ -98,9 +98,9 @@ func NewCallTxWithNonce(from account.PubKey, to, data []byte, amt, gasLimit, fee } } -func (tx *CallTx) Sign(privAccount *account.PrivAccount) { +func (tx *CallTx) Sign(chainID string, privAccount *account.PrivAccount) { tx.Input.PubKey = privAccount.PubKey - tx.Input.Signature = privAccount.Sign(tx) + tx.Input.Signature = privAccount.Sign(chainID, tx) } //---------------------------------------------------------------------------- @@ -155,8 +155,8 @@ func (tx *BondTx) AddOutput(addr []byte, amt uint64) error { return nil } -func (tx *BondTx) SignBond(privAccount *account.PrivAccount) error { - sig := privAccount.Sign(tx) +func (tx *BondTx) SignBond(chainID string, privAccount *account.PrivAccount) error { + sig := privAccount.Sign(chainID, tx) sigEd, ok := sig.(account.SignatureEd25519) if !ok { return fmt.Errorf("Bond signer must be ED25519") @@ -165,11 +165,11 @@ func (tx *BondTx) SignBond(privAccount *account.PrivAccount) error { return nil } -func (tx *BondTx) SignInput(i int, privAccount *account.PrivAccount) error { +func (tx *BondTx) SignInput(chainID string, i int, privAccount *account.PrivAccount) error { if i >= len(tx.Inputs) { return fmt.Errorf("Index %v is greater than number of inputs (%v)", i, len(tx.Inputs)) } tx.Inputs[i].PubKey = privAccount.PubKey - tx.Inputs[i].Signature = privAccount.Sign(tx) + tx.Inputs[i].Signature = privAccount.Sign(chainID, tx) return nil } diff --git a/types/vote.go b/types/vote.go index f9ed0f9de..def488e92 100644 --- a/types/vote.go +++ b/types/vote.go @@ -45,9 +45,9 @@ const ( VoteTypeCommit = byte(0x03) ) -func (vote *Vote) WriteSignBytes(w io.Writer, n *int64, err *error) { - // We hex encode the network name so we don't deal with escaping issues. - binary.WriteTo([]byte(Fmt(`{"network":"%X"`, config.GetString("network"))), w, n, err) +func (vote *Vote) WriteSignBytes(chainID string, w io.Writer, n *int64, err *error) { + // We hex encode the chain_id name so we don't deal with escaping issues. + binary.WriteTo([]byte(Fmt(`{"chain_id":"%X"`, chainID)), w, n, err) binary.WriteTo([]byte(Fmt(`,"vote":{"block_hash":"%X","block_parts":%v`, vote.BlockHash, vote.BlockParts)), w, n, err) binary.WriteTo([]byte(Fmt(`,"height":%v,"round":%v,"type":%v}}`, vote.Height, vote.Round, vote.Type)), w, n, err) }