pass chainID through sign interfaces

This commit is contained in:
Ethan Buchman
2015-05-29 17:53:57 -04:00
parent 8a2d9525f0
commit 2045aee9cd
28 changed files with 122 additions and 110 deletions

View File

@ -12,13 +12,13 @@ import (
// Signable is an interface for all signable things. // Signable is an interface for all signable things.
// It typically removes signatures before serializing. // It typically removes signatures before serializing.
type Signable interface { 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. // 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) buf, n, err := new(bytes.Buffer), new(int64), new(error)
o.WriteSignBytes(buf, n, err) o.WriteSignBytes(chainID, buf, n, err)
if *err != nil { if *err != nil {
panic(err) 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 // HashSignBytes is a convenience method for getting the hash of the bytes of a signable
func HashSignBytes(o Signable) []byte { func HashSignBytes(chainID string, o Signable) []byte {
return merkle.HashFromBinary(SignBytes(o)) return merkle.HashFromBinary(SignBytes(chainID, o))
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------

View File

@ -52,8 +52,8 @@ func GenPrivAccountFromKey(privKeyBytes [64]byte) *PrivAccount {
} }
} }
func (privAccount *PrivAccount) Sign(o Signable) Signature { func (privAccount *PrivAccount) Sign(chainID string, o Signable) Signature {
return privAccount.PrivKey.Sign(SignBytes(o)) return privAccount.PrivKey.Sign(SignBytes(chainID, o))
} }
func (privAccount *PrivAccount) String() string { func (privAccount *PrivAccount) String() string {

View File

@ -232,7 +232,7 @@ FOR_LOOP:
firstPartsHeader := firstParts.Header() firstPartsHeader := firstParts.Header()
// Finally, verify the first block using the second's validation. // Finally, verify the first block using the second's validation.
err := bcR.state.BondedValidators.VerifyValidation( 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 { if err != nil {
log.Debug("error in validation", "error", err) log.Debug("error in validation", "error", err)
bcR.pool.RedoRequest(first.Height) bcR.pool.RedoRequest(first.Height)

View File

@ -110,6 +110,6 @@ func gen_tx() {
} }
// Sign // 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)) fmt.Printf("Signed tx: %X\n", binary.BinaryBytes(tx))
} }

View File

@ -38,7 +38,7 @@ func (pol *POL) Verify(valSet *sm.ValidatorSet) error {
} }
talliedVotingPower := uint64(0) 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, Height: pol.Height, Round: pol.Round, Type: types.VoteTypePrevote,
BlockHash: pol.BlockHash, BlockHash: pol.BlockHash,
BlockParts: pol.BlockParts, BlockParts: pol.BlockParts,
@ -55,7 +55,7 @@ func (pol *POL) Verify(valSet *sm.ValidatorSet) error {
// Commit vote? // Commit vote?
if vote.Round < pol.Round { 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, Height: pol.Height, Round: vote.Round, Type: types.VoteTypeCommit,
BlockHash: pol.BlockHash, BlockHash: pol.BlockHash,
BlockParts: pol.BlockParts, BlockParts: pol.BlockParts,

View File

@ -3,8 +3,8 @@ package consensus
import ( import (
"github.com/tendermint/tendermint/binary" "github.com/tendermint/tendermint/binary"
. "github.com/tendermint/tendermint/common" . "github.com/tendermint/tendermint/common"
sm "github.com/tendermint/tendermint/state"
_ "github.com/tendermint/tendermint/config/tendermint_test" _ "github.com/tendermint/tendermint/config/tendermint_test"
sm "github.com/tendermint/tendermint/state"
"github.com/tendermint/tendermint/types" "github.com/tendermint/tendermint/types"
"bytes" "bytes"
@ -18,7 +18,7 @@ import (
// Returns the POLVoteSignature pointer, so you can modify it afterwards. // Returns the POLVoteSignature pointer, so you can modify it afterwards.
func signAddPOLVoteSignature(val *sm.PrivValidator, valSet *sm.ValidatorSet, vote *types.Vote, pol *POL) *POLVoteSignature { func signAddPOLVoteSignature(val *sm.PrivValidator, valSet *sm.ValidatorSet, vote *types.Vote, pol *POL) *POLVoteSignature {
vote = vote.Copy() vote = vote.Copy()
err := val.SignVote(vote) err := val.SignVote(config.GetString("chain_id"), vote)
if err != nil { if err != nil {
panic(err) panic(err)
} }

View File

@ -16,7 +16,7 @@ Consensus State Machine Overview:
* The NewHeight is a transition period after the height is incremented, * The NewHeight is a transition period after the height is incremented,
where the node still receives late commits before potentially proposing. where the node still receives late commits before potentially proposing.
The height should be incremented because a block had been 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. reflected as a new height.
+-------------------------------------+ +-------------------------------------+
@ -536,7 +536,7 @@ func (cs *ConsensusState) updateToState(state *sm.State, contiguous bool) {
Address: cs.privValidator.Address, Address: cs.privValidator.Address,
Height: cs.Height, Height: cs.Height,
} }
err := cs.privValidator.SignRebondTx(rebondTx) err := cs.privValidator.SignRebondTx(cs.state.ChainID, rebondTx)
if err == nil { if err == nil {
err := cs.mempoolReactor.BroadcastTx(rebondTx) err := cs.mempoolReactor.BroadcastTx(rebondTx)
if err != nil { if err != nil {
@ -656,7 +656,7 @@ func (cs *ConsensusState) RunActionPropose(height uint, round uint) {
txs := cs.mempoolReactor.Mempool.GetProposalTxs() txs := cs.mempoolReactor.Mempool.GetProposalTxs()
block = &types.Block{ block = &types.Block{
Header: &types.Header{ Header: &types.Header{
ChainID: config.GetString("chain_id"), ChainID: cs.state.ChainID,
Height: cs.Height, Height: cs.Height,
Time: time.Now(), Time: time.Now(),
Fees: 0, // TODO fees Fees: 0, // TODO fees
@ -688,7 +688,7 @@ func (cs *ConsensusState) RunActionPropose(height uint, round uint) {
// Make proposal // Make proposal
proposal := NewProposal(cs.Height, cs.Round, blockParts.Header(), polParts.Header()) 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 { if err == nil {
log.Info("Signed and set proposal", "height", cs.Height, "round", cs.Round, "proposal", proposal) log.Info("Signed and set proposal", "height", cs.Height, "round", cs.Round, "proposal", proposal)
log.Debug(Fmt("Signed and set proposal block: %v", block)) log.Debug(Fmt("Signed and set proposal block: %v", block))
@ -939,7 +939,7 @@ func (cs *ConsensusState) SetProposal(proposal *Proposal) error {
} }
// Verify signature // 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 return ErrInvalidProposalSignature
} }
@ -1111,7 +1111,7 @@ func (cs *ConsensusState) signAddVote(type_ byte, hash []byte, header types.Part
BlockHash: hash, BlockHash: hash,
BlockParts: header, BlockParts: header,
} }
err := cs.privValidator.SignVote(vote) err := cs.privValidator.SignVote(cs.state.ChainID, vote)
if err == nil { if err == nil {
log.Info("Signed and added vote", "height", cs.Height, "round", cs.Round, "vote", vote) log.Info("Signed and added vote", "height", cs.Height, "round", cs.Round, "vote", vote)
cs.addVote(cs.privValidator.Address, vote) cs.addVote(cs.privValidator.Address, vote)

View File

@ -16,7 +16,7 @@ func TestSetupRound(t *testing.T) {
voteTypes := []byte{types.VoteTypePrevote, types.VoteTypePrecommit, types.VoteTypeCommit} voteTypes := []byte{types.VoteTypePrevote, types.VoteTypePrecommit, types.VoteTypeCommit}
for _, voteType := range voteTypes { for _, voteType := range voteTypes {
vote := &types.Vote{Height: 1, Round: 0, Type: voteType} // nil vote 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 { if err != nil {
t.Error("Error signing vote: %v", err) t.Error("Error signing vote: %v", err)
} }
@ -124,7 +124,7 @@ func TestRunActionPrecommitCommitFinalize(t *testing.T) {
BlockHash: cs.ProposalBlock.Hash(), BlockHash: cs.ProposalBlock.Hash(),
BlockParts: cs.ProposalBlockParts.Header(), BlockParts: cs.ProposalBlockParts.Header(),
} }
err := privValidators[i].SignVote(vote) err := privValidators[i].SignVote(cs.state.ChainID, vote)
if err != nil { if err != nil {
t.Error("Error signing vote: %v", err) t.Error("Error signing vote: %v", err)
} }
@ -154,7 +154,7 @@ func TestRunActionPrecommitCommitFinalize(t *testing.T) {
BlockHash: cs.ProposalBlock.Hash(), BlockHash: cs.ProposalBlock.Hash(),
BlockParts: cs.ProposalBlockParts.Header(), BlockParts: cs.ProposalBlockParts.Header(),
} }
err := privValidators[i].SignVote(vote) err := privValidators[i].SignVote(cs.state.ChainID, vote)
if err != nil { if err != nil {
t.Error("Error signing vote: %v", err) t.Error("Error signing vote: %v", err)
} }
@ -192,7 +192,7 @@ func TestRunActionPrecommitCommitFinalize(t *testing.T) {
BlockHash: cs.ProposalBlock.Hash(), BlockHash: cs.ProposalBlock.Hash(),
BlockParts: cs.ProposalBlockParts.Header(), BlockParts: cs.ProposalBlockParts.Header(),
} }
err := privValidators[i].SignVote(vote) err := privValidators[i].SignVote(cs.state.ChainID, vote)
if err != nil { if err != nil {
t.Error("Error signing vote: %v", err) t.Error("Error signing vote: %v", err)
} }

View File

@ -38,9 +38,9 @@ func (p *Proposal) String() string {
p.BlockParts, p.POLParts, p.Signature) 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. // 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) binary.WriteTo([]byte(`,"proposal":{"block_parts":`), w, n, err)
p.BlockParts.WriteSignBytes(w, n, err) p.BlockParts.WriteSignBytes(w, n, err)
binary.WriteTo([]byte(Fmt(`,"height":%v,"pol_parts":`, p.Height)), w, n, err) binary.WriteTo([]byte(Fmt(`,"height":%v,"pol_parts":`, p.Height)), w, n, err)

View File

@ -17,7 +17,7 @@ func TestProposalSignable(t *testing.T) {
POLParts: types.PartSetHeader{222, []byte("polparts")}, POLParts: types.PartSetHeader{222, []byte("polparts")},
Signature: nil, Signature: nil,
} }
signBytes := account.SignBytes(proposal) signBytes := account.SignBytes(config.GetString("chain_id"), proposal)
signStr := string(signBytes) 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}}`, 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")) config.GetString("chain_id"))

View File

@ -93,7 +93,7 @@ func (voteSet *VoteSet) Add(address []byte, vote *types.Vote) (bool, uint, error
} }
// Check signature. // 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. // Bad signature.
return false, 0, types.ErrVoteInvalidSignature return false, 0, types.ErrVoteInvalidSignature
} }

View File

@ -5,8 +5,8 @@ import (
. "github.com/tendermint/tendermint/common" . "github.com/tendermint/tendermint/common"
. "github.com/tendermint/tendermint/common/test" . "github.com/tendermint/tendermint/common/test"
sm "github.com/tendermint/tendermint/state"
_ "github.com/tendermint/tendermint/config/tendermint_test" _ "github.com/tendermint/tendermint/config/tendermint_test"
sm "github.com/tendermint/tendermint/state"
"github.com/tendermint/tendermint/types" "github.com/tendermint/tendermint/types"
"testing" "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) { 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) added, _, err := voteSet.Add(privVal.Address, vote)
return added, err return added, err
} }

View File

@ -17,7 +17,7 @@ func BroadcastTx(tx types.Tx) (*ctypes.ResponseBroadcastTx, error) {
return nil, fmt.Errorf("Error broadcasting transaction: %v", err) 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 createsContract uint8
var contractAddr []byte var contractAddr []byte
// check if creates new contract // check if creates new contract

View File

@ -66,7 +66,8 @@ func NetInfo() (*ctypes.ResponseNetInfo, error) {
func Genesis() (*string, error) { func Genesis() (*string, error) {
b, err := ioutil.ReadFile(config.GetString("genesis_file")) b, err := ioutil.ReadFile(config.GetString("genesis_file"))
if err != nil { if err != nil {
return "", err return nil, err
} }
return &string(b), nil ret := string(b)
return &ret, nil
} }

View File

@ -91,27 +91,27 @@ func SignTx(tx types.Tx, privAccounts []*account.PrivAccount) (*ctypes.ResponseS
sendTx := tx.(*types.SendTx) sendTx := tx.(*types.SendTx)
for i, input := range sendTx.Inputs { for i, input := range sendTx.Inputs {
input.PubKey = privAccounts[i].PubKey input.PubKey = privAccounts[i].PubKey
input.Signature = privAccounts[i].Sign(sendTx) input.Signature = privAccounts[i].Sign(config.GetString("chain_id"), sendTx)
} }
case *types.CallTx: case *types.CallTx:
callTx := tx.(*types.CallTx) callTx := tx.(*types.CallTx)
callTx.Input.PubKey = privAccounts[0].PubKey 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: case *types.BondTx:
bondTx := tx.(*types.BondTx) bondTx := tx.(*types.BondTx)
// the first privaccount corresponds to the BondTx pub key. // the first privaccount corresponds to the BondTx pub key.
// the rest to the inputs // 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 { for i, input := range bondTx.Inputs {
input.PubKey = privAccounts[i+1].PubKey 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: case *types.UnbondTx:
unbondTx := tx.(*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: case *types.RebondTx:
rebondTx := tx.(*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 return &ctypes.ResponseSignTx{tx}, nil
} }

View File

@ -193,6 +193,6 @@ func TestWSCallCall(t *testing.T) {
waitForEvent(t, con, eid1, true, func() { waitForEvent(t, con, eid1, true, func() {
tx := makeDefaultCallTx(t, wsTyp, contractAddr2, nil, amt, gasLim, fee) tx := makeDefaultCallTx(t, wsTyp, contractAddr2, nil, amt, gasLim, fee)
broadcastTx(t, wsTyp, tx) broadcastTx(t, wsTyp, tx)
*txid = account.HashSignBytes(tx) *txid = account.HashSignBytes(chainID, tx)
}, unmarshalValidateCallCall(user[0].Address, returnVal, txid)) }, unmarshalValidateCallCall(user[0].Address, returnVal, txid))
} }

View File

@ -32,6 +32,8 @@ var (
userPriv = "C453604BD6480D5538B4C6FD2E3E314B5BCE518D75ADE4DA3DA85AB8ADFD819606FBAC4E285285D1D91FCBC7E91C780ADA11516F67462340B3980CE2B94940E8" userPriv = "C453604BD6480D5538B4C6FD2E3E314B5BCE518D75ADE4DA3DA85AB8ADFD819606FBAC4E285285D1D91FCBC7E91C780ADA11516F67462340B3980CE2B94940E8"
user = makeUsers(2) user = makeUsers(2)
chainID string
clients = map[string]cclient.Client{ clients = map[string]cclient.Client{
"JSONRPC": cclient.NewClient(requestAddr, "JSONRPC"), "JSONRPC": cclient.NewClient(requestAddr, "JSONRPC"),
"HTTP": cclient.NewClient(requestAddr, "HTTP"), "HTTP": cclient.NewClient(requestAddr, "HTTP"),
@ -74,6 +76,8 @@ func newNode(ready chan struct{}) {
// initialize config and create new node // initialize config and create new node
func init() { func init() {
chainID = config.GetString("chain_id")
// Save new priv_validator file. // Save new priv_validator file.
priv := &state.PrivValidator{ priv := &state.PrivValidator{
Address: user[0].Address, Address: user[0].Address,
@ -83,7 +87,7 @@ func init() {
priv.SetFile(config.GetString("priv_validator_file")) priv.SetFile(config.GetString("priv_validator_file"))
priv.Save() priv.Save()
consensus.RoundDuration0 = 3 * time.Second consensus.RoundDuration0 = 2 * time.Second
consensus.RoundDurationDelta = 1 * time.Second consensus.RoundDurationDelta = 1 * time.Second
// start a node // 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 { func makeDefaultSendTxSigned(t *testing.T, typ string, addr []byte, amt uint64) *types.SendTx {
tx := makeDefaultSendTx(t, typ, addr, amt) tx := makeDefaultSendTx(t, typ, addr, amt)
tx.SignInput(0, user[0]) tx.SignInput(chainID, 0, user[0])
return tx return tx
} }
func makeDefaultCallTx(t *testing.T, typ string, addr, code []byte, amt, gasLim, fee uint64) *types.CallTx { func makeDefaultCallTx(t *testing.T, typ string, addr, code []byte, amt, gasLim, fee uint64) *types.CallTx {
nonce := getNonce(t, typ, user[0].Address) nonce := getNonce(t, typ, user[0].Address)
tx := types.NewCallTxWithNonce(user[0].PubKey, addr, code, amt, gasLim, fee, nonce) tx := types.NewCallTxWithNonce(user[0].PubKey, addr, code, amt, gasLim, fee, nonce)
tx.Sign(user[0]) tx.Sign(chainID, user[0])
return tx 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!") 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] in := tx.Inputs[0] //(*types.SendTx).Inputs[0]
if err := in.ValidateBasic(); err != nil { if err := in.ValidateBasic(); err != nil {

View File

@ -15,9 +15,9 @@ func testStatus(t *testing.T, typ string) {
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
if resp.ChainID != config.GetString("chain_id") { if resp.ChainID != chainID {
t.Fatal(fmt.Errorf("ChainID mismatch: got %s expected %s", 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) { func testOneSignTx(t *testing.T, typ string, addr []byte, amt uint64) {
tx := makeDefaultSendTx(t, typ, addr, amt) tx := makeDefaultSendTx(t, typ, addr, amt)
tx2 := signTx(t, typ, tx, user[0]) tx2 := signTx(t, typ, tx, user[0])
tx2hash := account.HashSignBytes(tx2) tx2hash := account.HashSignBytes(chainID, tx2)
tx.SignInput(0, user[0]) tx.SignInput(chainID, 0, user[0])
txhash := account.HashSignBytes(tx) txhash := account.HashSignBytes(chainID, tx)
if bytes.Compare(txhash, tx2hash) != 0 { if bytes.Compare(txhash, tx2hash) != 0 {
t.Fatal("Got different signatures for signing via rpc vs tx_utils") 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) tx2 := txs[mempoolCount-1].(*types.SendTx)
n, err := new(int64), new(error) n, err := new(int64), new(error)
buf1, buf2 := new(bytes.Buffer), new(bytes.Buffer) buf1, buf2 := new(bytes.Buffer), new(bytes.Buffer)
tx.WriteSignBytes(buf1, n, err) tx.WriteSignBytes(chainID, buf1, n, err)
tx2.WriteSignBytes(buf2, n, err) tx2.WriteSignBytes(chainID, buf2, n, err)
if bytes.Compare(buf1.Bytes(), buf2.Bytes()) != 0 { if bytes.Compare(buf1.Bytes(), buf2.Bytes()) != 0 {
t.Fatal("inconsistent hashes for mempool tx and sent tx") t.Fatal("inconsistent hashes for mempool tx and sent tx")
} }

View File

@ -33,7 +33,7 @@ func ExecBlock(s *State, block *types.Block, blockPartsHeader types.PartSetHeade
// at an invalid state. Copy the state before calling execBlock! // at an invalid state. Copy the state before calling execBlock!
func execBlock(s *State, block *types.Block, blockPartsHeader types.PartSetHeader) error { func execBlock(s *State, block *types.Block, blockPartsHeader types.PartSetHeader) error {
// Basic block validation. // 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 { if err != nil {
return err return err
} }
@ -61,7 +61,7 @@ func execBlock(s *State, block *types.Block, blockPartsHeader types.PartSetHeade
BlockHash: block.LastBlockHash, BlockHash: block.LastBlockHash,
BlockParts: block.LastBlockParts, 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 sumVotingPower += val.VotingPower
return false return false
} else { } else {
@ -305,7 +305,7 @@ func ExecTx(blockCache *BlockCache, tx_ types.Tx, runCall bool, evc events.Firea
if err != nil { if err != nil {
return err return err
} }
signBytes := account.SignBytes(tx) signBytes := account.SignBytes(_s.ChainID, tx)
inTotal, err := validateInputs(accounts, signBytes, tx.Inputs) inTotal, err := validateInputs(accounts, signBytes, tx.Inputs)
if err != nil { if err != nil {
return err 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)) log.Debug(Fmt("Can't find pubkey for %X", tx.Input.Address))
return err return err
} }
signBytes := account.SignBytes(tx) signBytes := account.SignBytes(_s.ChainID, tx)
err := validateInput(inAcc, signBytes, tx.Input) err := validateInput(inAcc, signBytes, tx.Input)
if err != nil { if err != nil {
log.Debug(Fmt("validateInput failed on %X:", tx.Input.Address)) 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(caller) // because we adjusted by input above, and bumped nonce maybe.
txCache.UpdateAccount(callee) // because we adjusted by input above. 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) vmach.SetFireable(evc)
// NOTE: Call() transfers the value from caller to callee iff call succeeds. // 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 return err
} }
signBytes := account.SignBytes(tx) signBytes := account.SignBytes(_s.ChainID, tx)
inTotal, err := validateInputs(accounts, signBytes, tx.Inputs) inTotal, err := validateInputs(accounts, signBytes, tx.Inputs)
if err != nil { if err != nil {
return err return err
@ -548,7 +548,7 @@ func ExecTx(blockCache *BlockCache, tx_ types.Tx, runCall bool, evc events.Firea
} }
// Verify the signature // Verify the signature
signBytes := account.SignBytes(tx) signBytes := account.SignBytes(_s.ChainID, tx)
if !val.PubKey.VerifyBytes(signBytes, tx.Signature) { if !val.PubKey.VerifyBytes(signBytes, tx.Signature) {
return types.ErrTxInvalidSignature return types.ErrTxInvalidSignature
} }
@ -573,7 +573,7 @@ func ExecTx(blockCache *BlockCache, tx_ types.Tx, runCall bool, evc events.Firea
} }
// Verify the signature // Verify the signature
signBytes := account.SignBytes(tx) signBytes := account.SignBytes(_s.ChainID, tx)
if !val.PubKey.VerifyBytes(signBytes, tx.Signature) { if !val.PubKey.VerifyBytes(signBytes, tx.Signature) {
return types.ErrTxInvalidSignature return types.ErrTxInvalidSignature
} }
@ -599,8 +599,8 @@ func ExecTx(blockCache *BlockCache, tx_ types.Tx, runCall bool, evc events.Firea
return types.ErrTxInvalidAddress return types.ErrTxInvalidAddress
} }
} }
voteASignBytes := account.SignBytes(&tx.VoteA) voteASignBytes := account.SignBytes(_s.ChainID, &tx.VoteA)
voteBSignBytes := account.SignBytes(&tx.VoteB) voteBSignBytes := account.SignBytes(_s.ChainID, &tx.VoteB)
if !accused.PubKey.VerifyBytes(voteASignBytes, tx.VoteA.Signature) || if !accused.PubKey.VerifyBytes(voteASignBytes, tx.VoteA.Signature) ||
!accused.PubKey.VerifyBytes(voteBSignBytes, tx.VoteB.Signature) { !accused.PubKey.VerifyBytes(voteBSignBytes, tx.VoteB.Signature) {
return types.ErrTxInvalidSignature return types.ErrTxInvalidSignature

View File

@ -109,7 +109,7 @@ func (privVal *PrivValidator) save() {
} }
// TODO: test // TODO: test
func (privVal *PrivValidator) SignVote(vote *types.Vote) error { func (privVal *PrivValidator) SignVote(chainID string, vote *types.Vote) error {
privVal.mtx.Lock() privVal.mtx.Lock()
defer privVal.mtx.Unlock() defer privVal.mtx.Unlock()
@ -140,15 +140,15 @@ func (privVal *PrivValidator) SignVote(vote *types.Vote) error {
privVal.save() privVal.save()
// Sign // Sign
privVal.SignVoteUnsafe(vote) privVal.SignVoteUnsafe(chainID, vote)
return nil return nil
} }
func (privVal *PrivValidator) SignVoteUnsafe(vote *types.Vote) { func (privVal *PrivValidator) SignVoteUnsafe(chainID string, vote *types.Vote) {
vote.Signature = privVal.PrivKey.Sign(account.SignBytes(vote)).(account.SignatureEd25519) 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() privVal.mtx.Lock()
defer privVal.mtx.Unlock() defer privVal.mtx.Unlock()
if privVal.LastHeight < proposal.Height || if privVal.LastHeight < proposal.Height ||
@ -162,14 +162,14 @@ func (privVal *PrivValidator) SignProposal(proposal *Proposal) error {
privVal.save() privVal.save()
// Sign // Sign
proposal.Signature = privVal.PrivKey.Sign(account.SignBytes(proposal)).(account.SignatureEd25519) proposal.Signature = privVal.PrivKey.Sign(account.SignBytes(chainID, proposal)).(account.SignatureEd25519)
return nil return nil
} else { } else {
return errors.New(fmt.Sprintf("Attempt of duplicate signing of proposal: Height %v, Round %v", proposal.Height, proposal.Round)) 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() privVal.mtx.Lock()
defer privVal.mtx.Unlock() defer privVal.mtx.Unlock()
if privVal.LastHeight < rebondTx.Height { if privVal.LastHeight < rebondTx.Height {
@ -181,7 +181,7 @@ func (privVal *PrivValidator) SignRebondTx(rebondTx *types.RebondTx) error {
privVal.save() privVal.save()
// Sign // Sign
rebondTx.Signature = privVal.PrivKey.Sign(account.SignBytes(rebondTx)).(account.SignatureEd25519) rebondTx.Signature = privVal.PrivKey.Sign(account.SignBytes(chainID, rebondTx)).(account.SignatureEd25519)
return nil return nil
} else { } else {
return errors.New(fmt.Sprintf("Attempt of duplicate signing of rebondTx: Height %v", rebondTx.Height)) return errors.New(fmt.Sprintf("Attempt of duplicate signing of rebondTx: Height %v", rebondTx.Height))

View File

@ -65,7 +65,7 @@ func TestCopyState(t *testing.T) {
func makeBlock(t *testing.T, state *State, commits []types.Commit, txs []types.Tx) *types.Block { func makeBlock(t *testing.T, state *State, commits []types.Commit, txs []types.Tx) *types.Block {
block := &types.Block{ block := &types.Block{
Header: &types.Header{ Header: &types.Header{
ChainID: "tendermint_test", ChainID: state.ChainID,
Height: state.LastBlockHeight + 1, Height: state.LastBlockHeight + 1,
Time: state.LastBlockTime.Add(time.Minute), Time: state.LastBlockTime.Add(time.Minute),
Fees: 0, Fees: 0,
@ -191,7 +191,7 @@ func TestTxSequence(t *testing.T) {
for i := -1; i < 3; i++ { for i := -1; i < 3; i++ {
sequence := acc0.Sequence + uint(i) sequence := acc0.Sequence + uint(i)
tx := makeSendTx(sequence) tx := makeSendTx(sequence)
tx.Inputs[0].Signature = privAccounts[0].Sign(tx) tx.Inputs[0].Signature = privAccounts[0].Sign(state.ChainID, tx)
stateCopy := state.Copy() stateCopy := state.Copy()
err := execTxWithState(stateCopy, tx, true) err := execTxWithState(stateCopy, tx, true)
if i == 1 { 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) err := execTxWithState(state, tx, true)
if err != nil { if err != nil {
t.Errorf("Got error in executing send transaction, %v", err) 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.Signature = privAccounts[0].Sign(state.ChainID, tx).(account.SignatureEd25519)
tx.Inputs[0].Signature = privAccounts[0].Sign(tx) tx.Inputs[0].Signature = privAccounts[0].Sign(state.ChainID, tx)
err := execTxWithState(state, tx, true) err := execTxWithState(state, tx, true)
if err != nil { if err != nil {
t.Errorf("Got error in executing bond transaction, %v", err) 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.Signature = acc0.Sign(s0.ChainID, bondTx).(account.SignatureEd25519)
bondTx.Inputs[0].Signature = acc0.Sign(bondTx) bondTx.Inputs[0].Signature = acc0.Sign(s0.ChainID, bondTx)
// Make complete block and blockParts // Make complete block and blockParts
block0 := makeBlock(t, s0, nil, []types.Tx{bondTx}) block0 := makeBlock(t, s0, nil, []types.Tx{bondTx})
@ -380,7 +380,7 @@ func TestAddValidator(t *testing.T) {
BlockHash: block0.Hash(), BlockHash: block0.Hash(),
BlockParts: block0Parts.Header(), BlockParts: block0Parts.Header(),
} }
privValidators[0].SignVote(commit0) privValidators[0].SignVote(s0.ChainID, commit0)
block1 := makeBlock(t, s0, block1 := makeBlock(t, s0,
[]types.Commit{ []types.Commit{

View File

@ -97,6 +97,7 @@ func RandGenesisState(numAccounts int, randBalance bool, minBalance uint64, numV
sort.Sort(PrivValidatorsByAddress(privValidators)) sort.Sort(PrivValidatorsByAddress(privValidators))
s0 := MakeGenesisState(db, &GenesisDoc{ s0 := MakeGenesisState(db, &GenesisDoc{
GenesisTime: time.Now(), GenesisTime: time.Now(),
ChainID: "tendermint_test",
Accounts: accounts, Accounts: accounts,
Validators: validators, Validators: validators,
}) })

View File

@ -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 // 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)) { if valSet.Size() != uint(len(v.Commits)) {
return errors.New(Fmt("Invalid validation -- wrong set size: %v vs %v", return errors.New(Fmt("Invalid validation -- wrong set size: %v vs %v",
valSet.Size(), len(v.Commits))) valSet.Size(), len(v.Commits)))
@ -216,7 +216,7 @@ func (valSet *ValidatorSet) VerifyValidation(hash []byte, parts types.PartSetHea
continue continue
} }
_, val := valSet.GetByIndex(uint(idx)) _, val := valSet.GetByIndex(uint(idx))
commitSignBytes := account.SignBytes(&types.Vote{ commitSignBytes := account.SignBytes(chainID, &types.Vote{
Height: height, Round: commit.Round, Type: types.VoteTypeCommit, Height: height, Round: commit.Round, Type: types.VoteTypeCommit,
BlockHash: hash, BlockHash: hash,
BlockParts: parts, BlockParts: parts,

View File

@ -21,9 +21,9 @@ type Block struct {
} }
// Basic validation that doesn't involve state data. // 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 { lastBlockParts PartSetHeader, lastBlockTime time.Time) error {
if b.ChainID != config.GetString("chain_id") { if b.ChainID != chainID {
return errors.New("Wrong Block.Header.ChainID") return errors.New("Wrong Block.Header.ChainID")
} }
if b.Height != lastBlockHeight+1 { if b.Height != lastBlockHeight+1 {
@ -276,7 +276,7 @@ func (data *Data) Hash() []byte {
if data.hash == nil { if data.hash == nil {
bs := make([]interface{}, len(data.Txs)) bs := make([]interface{}, len(data.Txs))
for i, tx := range 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) data.hash = merkle.HashFromBinaries(bs)
} }

View File

@ -42,7 +42,7 @@ Validation Txs:
- DupeoutTx Validator dupes out (equivocates) - DupeoutTx Validator dupes out (equivocates)
*/ */
type Tx interface { 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 // Types of Tx implementations
@ -129,9 +129,9 @@ type SendTx struct {
Outputs []*TxOutput `json:"outputs"` 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. // 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) binary.WriteTo([]byte(Fmt(`,"tx":[%v,{"inputs":[`, TxTypeSend)), w, n, err)
for i, in := range tx.Inputs { for i, in := range tx.Inputs {
in.WriteSignBytes(w, n, err) in.WriteSignBytes(w, n, err)
@ -163,9 +163,9 @@ type CallTx struct {
Data []byte `json:"data"` 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. // 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(`,"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) binary.WriteTo([]byte(Fmt(`,"fee":%v,"gas_limit":%v,"input":`, tx.Fee, tx.GasLimit)), w, n, err)
tx.Input.WriteSignBytes(w, n, err) tx.Input.WriteSignBytes(w, n, err)
@ -185,9 +185,9 @@ type BondTx struct {
UnbondTo []*TxOutput `json:"unbond_to"` 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. // 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) binary.WriteTo([]byte(Fmt(`,"tx":[%v,{"inputs":[`, TxTypeBond)), w, n, err)
for i, in := range tx.Inputs { for i, in := range tx.Inputs {
in.WriteSignBytes(w, n, err) in.WriteSignBytes(w, n, err)
@ -219,9 +219,9 @@ type UnbondTx struct {
Signature account.SignatureEd25519 `json:"signature"` 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. // 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) 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"` 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. // 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) 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"` 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") panic("DupeoutTx has no sign bytes")
} }
@ -265,7 +265,7 @@ func (tx *DupeoutTx) String() string {
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
func TxId(tx Tx) []byte { func TxId(chainID string, tx Tx) []byte {
signBytes := account.SignBytes(tx) signBytes := account.SignBytes(chainID, tx)
return binary.BinaryRipemd160(signBytes) return binary.BinaryRipemd160(signBytes)
} }

View File

@ -8,6 +8,12 @@ import (
_ "github.com/tendermint/tendermint/config/tendermint_test" _ "github.com/tendermint/tendermint/config/tendermint_test"
) )
var chainID string
func init() {
chainID = config.GetString("chain_id")
}
func TestSendTxSignable(t *testing.T) { func TestSendTxSignable(t *testing.T) {
sendTx := &SendTx{ sendTx := &SendTx{
Inputs: []*TxInput{ Inputs: []*TxInput{
@ -33,7 +39,7 @@ func TestSendTxSignable(t *testing.T) {
}, },
}, },
} }
signBytes := account.SignBytes(sendTx) signBytes := account.SignBytes(chainID, sendTx)
signStr := string(signBytes) 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}]}]}`, 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")) config.GetString("chain_id"))
@ -54,7 +60,7 @@ func TestCallTxSignable(t *testing.T) {
Fee: 222, Fee: 222,
Data: []byte("data1"), Data: []byte("data1"),
} }
signBytes := account.SignBytes(callTx) signBytes := account.SignBytes(chainID, callTx)
signStr := string(signBytes) 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}}]}`, 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")) 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) 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}]}]}`, 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")) config.GetString("chain_id"))
@ -104,7 +110,7 @@ func TestUnbondTxSignable(t *testing.T) {
Address: []byte("address1"), Address: []byte("address1"),
Height: 111, Height: 111,
} }
signBytes := account.SignBytes(unbondTx) signBytes := account.SignBytes(chainID, unbondTx)
signStr := string(signBytes) signStr := string(signBytes)
expected := Fmt(`{"chain_id":"%X","tx":[18,{"address":"6164647265737331","height":111}]}`, expected := Fmt(`{"chain_id":"%X","tx":[18,{"address":"6164647265737331","height":111}]}`,
config.GetString("chain_id")) config.GetString("chain_id"))
@ -118,7 +124,7 @@ func TestRebondTxSignable(t *testing.T) {
Address: []byte("address1"), Address: []byte("address1"),
Height: 111, Height: 111,
} }
signBytes := account.SignBytes(rebondTx) signBytes := account.SignBytes(chainID, rebondTx)
signStr := string(signBytes) signStr := string(signBytes)
expected := Fmt(`{"chain_id":"%X","tx":[19,{"address":"6164647265737331","height":111}]}`, expected := Fmt(`{"chain_id":"%X","tx":[19,{"address":"6164647265737331","height":111}]}`,
config.GetString("chain_id")) config.GetString("chain_id"))

View File

@ -56,12 +56,12 @@ func (tx *SendTx) AddOutput(addr []byte, amt uint64) error {
return nil 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) { if i >= len(tx.Inputs) {
return fmt.Errorf("Index %v is greater than number of inputs (%v)", 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].PubKey = privAccount.PubKey
tx.Inputs[i].Signature = privAccount.Sign(tx) tx.Inputs[i].Signature = privAccount.Sign(chainID, tx)
return nil 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.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 return nil
} }
func (tx *BondTx) SignBond(privAccount *account.PrivAccount) error { func (tx *BondTx) SignBond(chainID string, privAccount *account.PrivAccount) error {
sig := privAccount.Sign(tx) sig := privAccount.Sign(chainID, tx)
sigEd, ok := sig.(account.SignatureEd25519) sigEd, ok := sig.(account.SignatureEd25519)
if !ok { if !ok {
return fmt.Errorf("Bond signer must be ED25519") return fmt.Errorf("Bond signer must be ED25519")
@ -165,11 +165,11 @@ func (tx *BondTx) SignBond(privAccount *account.PrivAccount) error {
return nil 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) { if i >= len(tx.Inputs) {
return fmt.Errorf("Index %v is greater than number of inputs (%v)", 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].PubKey = privAccount.PubKey
tx.Inputs[i].Signature = privAccount.Sign(tx) tx.Inputs[i].Signature = privAccount.Sign(chainID, tx)
return nil return nil
} }

View File

@ -45,9 +45,9 @@ const (
VoteTypeCommit = byte(0x03) 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. // 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(`,"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) binary.WriteTo([]byte(Fmt(`,"height":%v,"round":%v,"type":%v}}`, vote.Height, vote.Round, vote.Type)), w, n, err)
} }