diff --git a/account/account.go b/account/account.go index 03b9d3eb..081dc106 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 ccd702b1..ad4fc650 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/blockchain/reactor.go b/blockchain/reactor.go index e48da66f..322ed5c3 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 687339be..d499fad8 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/consensus/pol.go b/consensus/pol.go index 433a6992..7314eb48 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 db55bd5d..5b56969d 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 0f75f531..de7b5fd2 100644 --- a/consensus/state.go +++ b/consensus/state.go @@ -16,7 +16,7 @@ Consensus State Machine Overview: * The NewHeight is a transition period after the height is incremented, where the node still receives late commits before potentially proposing. The height should be incremented because a block had been - "committed by the chain_id", and clients should see that + "committed by the network", and clients should see that reflected as a new height. +-------------------------------------+ @@ -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{ - ChainID: config.GetString("chain_id"), + 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 8ab22039..af25ae01 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 642fa59f..a306f032 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) { +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"`, config.GetString("chain_id"))), w, n, err) + 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 cef57faf..fa8f37be 100644 --- a/consensus/types/proposal_test.go +++ b/consensus/types/proposal_test.go @@ -17,7 +17,7 @@ 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(`{"chain_id":"%X","proposal":{"block_parts":{"hash":"626C6F636B7061727473","total":111},"height":12345,"pol_parts":{"hash":"706F6C7061727473","total":222},"round":23456}}`, config.GetString("chain_id")) diff --git a/consensus/vote_set.go b/consensus/vote_set.go index 21e98661..ca2f44eb 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 2c94d682..212fcf66 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/rpc/core/mempool.go b/rpc/core/mempool.go index 4fa93560..e4ae7709 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 842602a2..f74510e7 100644 --- a/rpc/core/net.go +++ b/rpc/core/net.go @@ -66,7 +66,8 @@ func NetInfo() (*ctypes.ResponseNetInfo, error) { func Genesis() (*string, error) { b, err := ioutil.ReadFile(config.GetString("genesis_file")) if err != nil { - return "", err + return nil, err } - return &string(b), nil + ret := string(b) + return &ret, nil } diff --git a/rpc/core/txs.go b/rpc/core/txs.go index e0c40a55..07e14d94 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/test/client_ws_test.go b/rpc/test/client_ws_test.go index a5d0880c..5f94306b 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 8602c0bf..da05ccfd 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 7a172c2c..ca9221ea 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.ChainID != config.GetString("chain_id") { + if resp.ChainID != chainID { t.Fatal(fmt.Errorf("ChainID mismatch: got %s expected %s", - resp.ChainID, config.Get("chain_id"))) + 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 9b6c35be..e46a2150 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/priv_validator.go b/state/priv_validator.go index 607a789e..6ddfb3b4 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_test.go b/state/state_test.go index 1885c8f1..a2fb2b78 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{ - ChainID: "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 efb425fb..8e0f3520 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 2d247313..a7cede7c 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 25de6dd1..eef5fe89 100644 --- a/types/block.go +++ b/types/block.go @@ -21,9 +21,9 @@ 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.ChainID != config.GetString("chain_id") { + if b.ChainID != chainID { return errors.New("Wrong Block.Header.ChainID") } if b.Height != lastBlockHeight+1 { @@ -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/tx.go b/types/tx.go index 00fe34d7..2d365881 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) { +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"`, config.GetString("chain_id"))), w, n, err) + 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) { +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"`, config.GetString("chain_id"))), w, n, err) + 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) { +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"`, config.GetString("chain_id"))), w, n, err) + 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) { +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"`, config.GetString("chain_id"))), w, n, err) + 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) { +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"`, config.GetString("chain_id"))), w, n, err) + 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 88d8204f..5ac1f908 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,7 +39,7 @@ func TestSendTxSignable(t *testing.T) { }, }, } - signBytes := account.SignBytes(sendTx) + signBytes := account.SignBytes(chainID, sendTx) signStr := string(signBytes) 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")) @@ -54,7 +60,7 @@ func TestCallTxSignable(t *testing.T) { Fee: 222, Data: []byte("data1"), } - signBytes := account.SignBytes(callTx) + signBytes := account.SignBytes(chainID, callTx) signStr := string(signBytes) 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")) @@ -90,7 +96,7 @@ func TestBondTxSignable(t *testing.T) { }, }, } - signBytes := account.SignBytes(bondTx) + signBytes := account.SignBytes(chainID, bondTx) signStr := string(signBytes) 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")) @@ -104,7 +110,7 @@ func TestUnbondTxSignable(t *testing.T) { Address: []byte("address1"), Height: 111, } - signBytes := account.SignBytes(unbondTx) + signBytes := account.SignBytes(chainID, unbondTx) signStr := string(signBytes) expected := Fmt(`{"chain_id":"%X","tx":[18,{"address":"6164647265737331","height":111}]}`, config.GetString("chain_id")) @@ -118,7 +124,7 @@ func TestRebondTxSignable(t *testing.T) { Address: []byte("address1"), Height: 111, } - signBytes := account.SignBytes(rebondTx) + signBytes := account.SignBytes(chainID, rebondTx) signStr := string(signBytes) expected := Fmt(`{"chain_id":"%X","tx":[19,{"address":"6164647265737331","height":111}]}`, config.GetString("chain_id")) diff --git a/types/tx_utils.go b/types/tx_utils.go index 29a7b3ab..eb5491ad 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 d733f72d..def488e9 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) { +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"`, config.GetString("chain_id"))), w, n, err) + 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) }