From 0c206aa748754903fe9cc02b9d279651e6f6e629 Mon Sep 17 00:00:00 2001 From: Jae Kwon Date: Tue, 7 Oct 2014 19:37:20 -0700 Subject: [PATCH] Signable interface. --- blocks/document.go | 46 ------------------------------------- blocks/signature.go | 8 +++++++ blocks/tx.go | 38 +++++++++++++++++------------- blocks/vote.go | 14 ++++++++++- consensus/pol.go | 7 ++++-- consensus/priv_validator.go | 7 ++---- consensus/proposal.go | 15 ++++++++++-- consensus/state.go | 8 +++---- state/account.go | 17 ++++++++++++-- state/log.go | 2 +- state/state.go | 2 +- 11 files changed, 84 insertions(+), 80 deletions(-) delete mode 100644 blocks/document.go diff --git a/blocks/document.go b/blocks/document.go deleted file mode 100644 index 658751bc3..000000000 --- a/blocks/document.go +++ /dev/null @@ -1,46 +0,0 @@ -package blocks - -import ( - "fmt" - . "github.com/tendermint/tendermint/config" -) - -func GenVoteDocument(voteType byte, height uint32, round uint16, blockHash []byte) []byte { - stepName := "" - switch voteType { - case VoteTypeBare: - stepName = "bare" - case VoteTypePrecommit: - stepName = "precommit" - case VoteTypeCommit: - stepName = "commit" - default: - panic("Unknown vote type") - } - return []byte(fmt.Sprintf( - `!!!!!BEGIN TENDERMINT VOTE!!!!! -Network: %v -Height: %v -Round: %v -Step: %v -BlockHash: %v -!!!!!END TENDERMINT VOTE!!!!!`, - Config.Network, height, round, stepName, blockHash, - )) -} - -func GenProposalDocument(height uint32, round uint16, blockPartsTotal uint16, blockPartsHash []byte, - polPartsTotal uint16, polPartsHash []byte) []byte { - return []byte(fmt.Sprintf( - `!!!!!BEGIN TENDERMINT PROPOSAL!!!!! -Network: %v -Height: %v -Round: %v -BlockPartsTotal: %v -BlockPartsHash: %X -POLPartsTotal: %v -POLPartsHash: %X -!!!!!END TENDERMINT PROPOSAL!!!!!`, - Config.Network, height, round, blockPartsTotal, blockPartsHash, polPartsTotal, polPartsHash, - )) -} diff --git a/blocks/signature.go b/blocks/signature.go index 6bfa28b82..80b6c91d8 100644 --- a/blocks/signature.go +++ b/blocks/signature.go @@ -5,6 +5,14 @@ import ( "io" ) +type Signable interface { + GenDocument() []byte + GetSignature() Signature + SetSignature(Signature) +} + +//----------------------------------------------------------------------------- + type Signature struct { SignerId uint64 Bytes []byte diff --git a/blocks/tx.go b/blocks/tx.go index bd69cadc8..c4f311ecc 100644 --- a/blocks/tx.go +++ b/blocks/tx.go @@ -20,8 +20,6 @@ Validation Txs: type Tx interface { Type() byte - GetSequence() uint64 - GetSignature() *Signature //IsValidation() bool Binary } @@ -99,18 +97,18 @@ func ReadBaseTx(r io.Reader, n *int64, err *error) BaseTx { } } -func (tx *BaseTx) GetSequence() uint64 { - return tx.Sequence +func (tx BaseTx) WriteTo(w io.Writer) (n int64, err error) { + WriteUVarInt(w, tx.Sequence, &n, &err) + WriteBinary(w, tx.Signature, &n, &err) + return } -func (tx *BaseTx) GetSignature() *Signature { - return &tx.Signature +func (tx *BaseTx) GetSignature() Signature { + return tx.Signature } -func (tx *BaseTx) WriteTo(w io.Writer) (n int64, err error) { - WriteUVarInt(w, tx.Sequence, &n, &err) - WriteBinary(w, tx.Signature, &n, &err) - return +func (tx *BaseTx) SetSignature(sig Signature) { + tx.Signature = sig } //----------------------------------------------------------------------------- @@ -128,7 +126,7 @@ func (tx *SendTx) Type() byte { func (tx *SendTx) WriteTo(w io.Writer) (n int64, err error) { WriteByte(w, tx.Type(), &n, &err) - WriteBinary(w, &tx.BaseTx, &n, &err) + WriteBinary(w, tx.BaseTx, &n, &err) WriteUInt64(w, tx.Fee, &n, &err) WriteUInt64(w, tx.To, &n, &err) WriteUInt64(w, tx.Amount, &n, &err) @@ -150,7 +148,7 @@ func (tx *NameTx) Type() byte { func (tx *NameTx) WriteTo(w io.Writer) (n int64, err error) { WriteByte(w, tx.Type(), &n, &err) - WriteBinary(w, &tx.BaseTx, &n, &err) + WriteBinary(w, tx.BaseTx, &n, &err) WriteUInt64(w, tx.Fee, &n, &err) WriteString(w, tx.Name, &n, &err) WriteByteSlice(w, tx.PubKey, &n, &err) @@ -172,7 +170,7 @@ func (tx *BondTx) Type() byte { func (tx *BondTx) WriteTo(w io.Writer) (n int64, err error) { WriteByte(w, tx.Type(), &n, &err) - WriteBinary(w, &tx.BaseTx, &n, &err) + WriteBinary(w, tx.BaseTx, &n, &err) WriteUInt64(w, tx.Fee, &n, &err) WriteUInt64(w, tx.UnbondTo, &n, &err) WriteUInt64(w, tx.Amount, &n, &err) @@ -193,7 +191,7 @@ func (tx *UnbondTx) Type() byte { func (tx *UnbondTx) WriteTo(w io.Writer) (n int64, err error) { WriteByte(w, tx.Type(), &n, &err) - WriteBinary(w, &tx.BaseTx, &n, &err) + WriteBinary(w, tx.BaseTx, &n, &err) WriteUInt64(w, tx.Fee, &n, &err) WriteUInt64(w, tx.Amount, &n, &err) return @@ -213,7 +211,7 @@ func (tx *TimeoutTx) Type() byte { func (tx *TimeoutTx) WriteTo(w io.Writer) (n int64, err error) { WriteByte(w, tx.Type(), &n, &err) - WriteBinary(w, &tx.BaseTx, &n, &err) + WriteBinary(w, tx.BaseTx, &n, &err) WriteUInt64(w, tx.AccountId, &n, &err) WriteUInt64(w, tx.Penalty, &n, &err) return @@ -233,8 +231,16 @@ func (tx *DupeoutTx) Type() byte { func (tx *DupeoutTx) WriteTo(w io.Writer) (n int64, err error) { WriteByte(w, tx.Type(), &n, &err) - WriteBinary(w, &tx.BaseTx, &n, &err) + WriteBinary(w, tx.BaseTx, &n, &err) WriteBinary(w, &tx.VoteA, &n, &err) WriteBinary(w, &tx.VoteB, &n, &err) return } + +func (tx *DupeoutTx) GenDocument() []byte { + oldSig := tx.Signature + tx.Signature = Signature{} + doc := BinaryBytes(tx) + tx.Signature = oldSig + return doc +} diff --git a/blocks/vote.go b/blocks/vote.go index 649476331..babd58229 100644 --- a/blocks/vote.go +++ b/blocks/vote.go @@ -50,5 +50,17 @@ func (v *Vote) WriteTo(w io.Writer) (n int64, err error) { } func (v *Vote) GenDocument() []byte { - return GenVoteDocument(v.Type, v.Height, v.Round, v.BlockHash) + oldSig := v.Signature + v.Signature = Signature{} + doc := BinaryBytes(v) + v.Signature = oldSig + return doc +} + +func (v *Vote) GetSignature() Signature { + return v.Signature +} + +func (v *Vote) SetSignature(sig Signature) { + v.Signature = sig } diff --git a/consensus/pol.go b/consensus/pol.go index 395aca749..ae34c48c9 100644 --- a/consensus/pol.go +++ b/consensus/pol.go @@ -45,7 +45,8 @@ func (pol *POL) WriteTo(w io.Writer) (n int64, err error) { func (pol *POL) Verify(vset *ValidatorSet) error { talliedVotingPower := uint64(0) - voteDoc := GenVoteDocument(VoteTypeBare, pol.Height, pol.Round, pol.BlockHash) + voteDoc := (&Vote{Height: pol.Height, Round: pol.Round, + Type: VoteTypeBare, BlockHash: pol.BlockHash}).GenDocument() seenValidators := map[uint64]struct{}{} for _, sig := range pol.Votes { @@ -78,7 +79,9 @@ func (pol *POL) Verify(vset *ValidatorSet) error { if validator == nil { return Errorf("Invalid validator for commit %v for POL %v", sig, pol) } - commitDoc := GenVoteDocument(VoteTypeCommit, pol.Height, round, pol.BlockHash) // TODO cache + + commitDoc := (&Vote{Height: pol.Height, Round: round, + Type: VoteTypeCommit, BlockHash: pol.BlockHash}).GenDocument() // TODO cache if !validator.Verify(commitDoc, sig) { return Errorf("Invalid signature for commit %v for POL %v", sig, pol) } diff --git a/consensus/priv_validator.go b/consensus/priv_validator.go index 72674302a..cb6c53538 100644 --- a/consensus/priv_validator.go +++ b/consensus/priv_validator.go @@ -16,14 +16,11 @@ type PrivValidator struct { // Double signing results in an error. func (pv *PrivValidator) SignProposal(proposal *Proposal) { //TODO: prevent double signing. - doc := GenProposalDocument(proposal.Height, proposal.Round, proposal.BlockPartsTotal, - proposal.BlockPartsHash, proposal.POLPartsTotal, proposal.POLPartsHash) - proposal.Signature = pv.Sign([]byte(doc)) + pv.SignSignable(proposal) } // Double signing results in an error. func (pv *PrivValidator) SignVote(vote *Vote) { //TODO: prevent double signing. - doc := GenVoteDocument(vote.Type, vote.Height, vote.Round, vote.BlockHash) - vote.Signature = pv.Sign([]byte(doc)) + pv.SignSignable(vote) } diff --git a/consensus/proposal.go b/consensus/proposal.go index 8f0c06c30..2fb695042 100644 --- a/consensus/proposal.go +++ b/consensus/proposal.go @@ -59,6 +59,17 @@ func (p *Proposal) WriteTo(w io.Writer) (n int64, err error) { } func (p *Proposal) GenDocument() []byte { - return GenProposalDocument(p.Height, p.Round, p.BlockPartsTotal, p.BlockPartsHash, - p.POLPartsTotal, p.POLPartsHash) + oldSig := p.Signature + p.Signature = Signature{} + doc := BinaryBytes(p) + p.Signature = oldSig + return doc +} + +func (p *Proposal) GetSignature() Signature { + return p.Signature +} + +func (p *Proposal) SetSignature(sig Signature) { + p.Signature = sig } diff --git a/consensus/state.go b/consensus/state.go index 621449cf5..3fd38e9d9 100644 --- a/consensus/state.go +++ b/consensus/state.go @@ -79,18 +79,18 @@ func (cs *ConsensusState) GetRoundState() *RoundState { func (cs *ConsensusState) updateToState(state *State) { // Sanity check state. - stateHeight := state.Height() + stateHeight := state.Height if stateHeight > 0 && stateHeight != cs.Height+1 { Panicf("updateToState() expected state height of %v but found %v", cs.Height+1, stateHeight) } // Reset fields based on state. - height := state.Height() - validators := state.Validators() + height := state.Height + validators := state.Validators cs.Height = height cs.Round = 0 cs.Step = RoundStepStart - cs.StartTime = state.CommitTime().Add(newBlockWaitDuration) + cs.StartTime = state.CommitTime.Add(newBlockWaitDuration) cs.Validators = validators cs.Proposer = validators.GetProposer() cs.Proposal = nil diff --git a/state/account.go b/state/account.go index 707a4db7d..45aada2cf 100644 --- a/state/account.go +++ b/state/account.go @@ -33,7 +33,7 @@ func (account Account) WriteTo(w io.Writer) (n int64, err error) { func (account Account) Verify(msg []byte, sig Signature) bool { if sig.SignerId != account.Id { - panic("Account.Id doesn't match sig.SignerId") + panic("account.id doesn't match sig.signerid") } v1 := &crypto.Verify{ Message: msg, @@ -44,6 +44,12 @@ func (account Account) Verify(msg []byte, sig Signature) bool { return ok } +func (account Account) VerifySignable(o Signable) bool { + msg := o.GenDocument() + sig := o.GetSignature() + return account.Verify(msg, sig) +} + //----------------------------------------------------------------------------- type AccountBalance struct { @@ -90,8 +96,15 @@ func GenPrivAccount() *PrivAccount { func (pa *PrivAccount) Sign(msg []byte) Signature { signature := crypto.SignMessage(msg, pa.PrivKey, pa.PubKey) - return Signature{ + sig := Signature{ SignerId: pa.Id, Bytes: signature, } + return sig +} + +func (pa *PrivAccount) SignSignable(o Signable) { + msg := o.GenDocument() + sig := pa.Sign(msg) + o.SetSignature(sig) } diff --git a/state/log.go b/state/log.go index 323af2627..63fbee78e 100644 --- a/state/log.go +++ b/state/log.go @@ -10,6 +10,6 @@ func init() { logging.SetFormatter(logging.MustStringFormatter("[%{level:.1s}] %{message}")) } -func SetStatesLogger(l *logging.Logger) { +func SetStateLogger(l *logging.Logger) { log = l } diff --git a/state/state.go b/state/state.go index 5079e3b8c..395dde505 100644 --- a/state/state.go +++ b/state/state.go @@ -147,7 +147,7 @@ func (s *State) ExecTx(tx Tx) error { } // NOTE: If an error occurs during block execution, state will be left -// at an invalid state. Copy the state before calling Commit! +// at an invalid state. Copy the state before calling AppendBlock! func (s *State) AppendBlock(b *Block) error { // Basic block validation. err := b.ValidateBasic(s.Height, s.BlockHash)