Skip to content

Commit

Permalink
Merge pull request #51 from zemyblue/feature/genesis_hash
Browse files Browse the repository at this point in the history
Add `ProofHash` for first block
  • Loading branch information
torao authored Apr 3, 2020
2 parents 25d587d + db5e553 commit 8bef2d9
Show file tree
Hide file tree
Showing 9 changed files with 34 additions and 29 deletions.
4 changes: 1 addition & 3 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -402,9 +402,7 @@ workflows:
only:
- docs-theme-latest
- lint
- setup_dependencies:
requires:
- lint
- setup_dependencies
- test_abci_apps:
requires:
- setup_dependencies
Expand Down
1 change: 1 addition & 0 deletions CHANGELOG_PENDING.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ program](https://hackerone.com/tendermint).
### FEATURES:
- [types] [\#40](https:/line/tendermint/issues/40) Add vrf interface and add a function generating vrf proof to PrivValidator
- [lib/rand] [\#43](https:/line/tendermint/issues/43) Implementation of selection algorithms using categorical distributions
- [state] [\#44](https:/line/tendermint/issues/44) Add genesis seed for electing proposer of first block

### IMPROVEMENTS:

Expand Down
8 changes: 7 additions & 1 deletion state/execution.go
Original file line number Diff line number Diff line change
Expand Up @@ -427,6 +427,12 @@ func updateState(
// TODO: allow app to upgrade version
nextVersion := state.Version

// get proof hash from vrf proof
proofHash, err := vrf.ProofToHash(header.Proof.Bytes())
if err != nil {
return state, fmt.Errorf("error get proof of hash: %v", err)
}

// NOTE: the AppHash has not been populated.
// It will be filled on state.Save.
return State{
Expand All @@ -435,7 +441,7 @@ func updateState(
LastBlockHeight: header.Height,
LastBlockID: blockID,
LastBlockTime: header.Time,
LastProof: header.Proof.Bytes(),
LastProofHash: proofHash,
NextValidators: nValSet,
Validators: state.NextValidators.Copy(),
LastValidators: state.Validators.Copy(),
Expand Down
7 changes: 4 additions & 3 deletions state/helpers_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,8 @@ func makeAndCommitGoodBlock(
privVals map[string]types.PrivValidator,
evidence []types.Evidence) (sm.State, types.BlockID, *types.Commit, error) {
// A good block passes
state, blockID, err := makeAndApplyGoodBlock(state, privVals[state.Validators.Proposer.Address.String()], height, lastCommit, proposerAddr, blockExec, evidence)
state, blockID, err := makeAndApplyGoodBlock(state, privVals[state.Validators.Proposer.Address.String()], height,
lastCommit, proposerAddr, blockExec, evidence)
if err != nil {
return state, types.BlockID{}, nil, err
}
Expand All @@ -58,8 +59,8 @@ func makeAndCommitGoodBlock(
return state, blockID, commit, nil
}

func makeAndApplyGoodBlock(state sm.State, privVal types.PrivValidator, height int64, lastCommit *types.Commit, proposerAddr []byte,
blockExec *sm.BlockExecutor, evidence []types.Evidence) (sm.State, types.BlockID, error) {
func makeAndApplyGoodBlock(state sm.State, privVal types.PrivValidator, height int64, lastCommit *types.Commit,
proposerAddr []byte, blockExec *sm.BlockExecutor, evidence []types.Evidence) (sm.State, types.BlockID, error) {
message, _ := state.MakeHashMessage(0)
proof, _ := privVal.GenerateVRFProof(message)
block, _ := state.MakeBlock(height, makeTxs(height), lastCommit, evidence, proposerAddr, 0, proof)
Expand Down
24 changes: 6 additions & 18 deletions state/state.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,8 +62,8 @@ type State struct {
LastBlockID types.BlockID
LastBlockTime time.Time

// vrf proof
LastProof vrf.Proof
// vrf hash from proof
LastProofHash []byte

// LastValidators is used to validate block.LastCommit.
// Validators are persisted to the database separately every time they change,
Expand All @@ -89,23 +89,11 @@ type State struct {
}

func (state State) MakeHashMessage(round int) ([]byte, error) {
var seed []byte

if len(state.LastProof) == 0 {
// TODO: This code is temporary. When genesis seed is prepared, use that code.
seed = []byte("LINE Blockchain VRF Algorithm's first seed")
} else {
output, err := vrf.ProofToHash(state.LastProof)
if err != nil {
return nil, err
}
seed = output
}
b := make([]byte, 16)
binary.LittleEndian.PutUint64(b, uint64(state.LastBlockHeight))
binary.LittleEndian.PutUint64(b[8:], uint64(round))
hash := tmhash.New()
hash.Write(seed)
hash.Write(state.LastProofHash)
return hash.Sum(b), nil
}

Expand All @@ -119,7 +107,7 @@ func (state State) Copy() State {
LastBlockID: state.LastBlockID,
LastBlockTime: state.LastBlockTime,

LastProof: state.LastProof,
LastProofHash: state.LastProofHash,

NextValidators: state.NextValidators.Copy(),
Validators: state.Validators.Copy(),
Expand Down Expand Up @@ -271,8 +259,8 @@ func MakeGenesisState(genDoc *types.GenesisDoc) (State, error) {
LastBlockID: types.BlockID{},
LastBlockTime: genDoc.GenesisTime,

// genesis block has no last proof
LastProof: nil,
// genesis block use the hash of GenesisDoc instead for the `LastProofHash`
LastProofHash: genDoc.Hash(),

NextValidators: nextValidatorSet,
Validators: validatorSet,
Expand Down
5 changes: 4 additions & 1 deletion state/state_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import (
"github.com/stretchr/testify/require"
abci "github.com/tendermint/tendermint/abci/types"
"github.com/tendermint/tendermint/crypto/ed25519"
"github.com/tendermint/tendermint/crypto/vrf"
"github.com/tendermint/tendermint/libs/kv"
"github.com/tendermint/tendermint/libs/rand"
tmrand "github.com/tendermint/tendermint/libs/rand"
Expand Down Expand Up @@ -1027,7 +1028,9 @@ func TestState_MakeHashMessage(t *testing.T) {
require.False(t, bytes.Equal(message1, message2))

privVal := makePrivVal()
state.LastProof, _ = privVal.GenerateVRFProof(message1)
proof, _ := privVal.GenerateVRFProof(message1)
output, _ := vrf.ProofToHash(proof)
state.LastProofHash = output
message3, err := state.MakeHashMessage(0)
require.NoError(t, err)
require.False(t, bytes.Equal(message1, message3))
Expand Down
7 changes: 5 additions & 2 deletions state/validation.go
Original file line number Diff line number Diff line change
Expand Up @@ -166,9 +166,12 @@ func validateBlock(evidencePool EvidencePool, stateDB dbm.DB, state State, round
_, val := state.Validators.GetByAddress(block.ProposerAddress)
verified, err := vrf.Verify(val.PubKey.(ed25519.PubKeyEd25519), block.Proof.Bytes(), message)
if err != nil {
return types.NewErrInvalidProof(fmt.Sprintf("verification failed: %s; proof: %v, prevProof: %v, height=%d, round=%d, addr: %v", err.Error(), block.Proof, state.LastProof, state.LastBlockHeight, block.Round, block.ProposerAddress))
return types.NewErrInvalidProof(fmt.Sprintf(
"verification failed: %s; proof: %v, prevProofHash: %v, height=%d, round=%d, addr: %v",
err.Error(), block.Proof, state.LastProofHash, state.LastBlockHeight, block.Round, block.ProposerAddress))
} else if !verified {
return types.NewErrInvalidProof(fmt.Sprintf("proof: %v, prevProof: %v, height=%d, round=%d, addr: %v", block.Proof, state.LastProof, state.LastBlockHeight, block.Round, block.ProposerAddress))
return types.NewErrInvalidProof(fmt.Sprintf("proof: %v, prevProofHash: %v, height=%d, round=%d, addr: %v",
block.Proof, state.LastProofHash, state.LastBlockHeight, block.Round, block.ProposerAddress))
}

return nil
Expand Down
2 changes: 1 addition & 1 deletion types/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -81,4 +81,4 @@ func NewErrInvalidRound(consensusRound, blockRound int) ErrInvalidRound {

func (e ErrInvalidRound) Error() string {
return fmt.Sprintf("Block round(%d) is mismatched to consensus round(%d)", e.BlockRound, e.ConsensusRound)
}
}
5 changes: 5 additions & 0 deletions types/genesis.go
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,11 @@ func (genDoc *GenesisDoc) ValidateAndComplete() error {
return nil
}

// Hash returns the hash of the GenesisDoc
func (genDoc *GenesisDoc) Hash() []byte {
return cdcEncode(genDoc)
}

//------------------------------------------------------------
// Make genesis state from file

Expand Down

0 comments on commit 8bef2d9

Please sign in to comment.