Skip to content

Commit 770a9bd

Browse files
gupadhyayaGanesha Upadhyaya
andauthored
add signatures and keys to signed header along with signature verification in validate method (#788)
Fixes #782 #783 #784 --------- Co-authored-by: Ganesha Upadhyaya <gupadhyaya@Ganeshas-MacBook-Pro-2.local>
1 parent 2728eaf commit 770a9bd

12 files changed

Lines changed: 622 additions & 156 deletions

File tree

block/manager.go

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -446,8 +446,6 @@ func (m *Manager) getCommit(header types.Header) (*types.Commit, error) {
446446
return nil, err
447447
}
448448
return &types.Commit{
449-
Height: uint64(header.Height()),
450-
HeaderHash: header.Hash(),
451449
Signatures: []types.Signature{sign},
452450
}, nil
453451
}
@@ -461,7 +459,7 @@ func (m *Manager) publishBlock(ctx context.Context) error {
461459

462460
// this is a special case, when first block is produced - there is no previous commit
463461
if newHeight == uint64(m.genesis.InitialHeight) {
464-
lastCommit = &types.Commit{Height: height}
462+
lastCommit = &types.Commit{}
465463
} else {
466464
lastCommit, err = m.store.LoadCommit(height)
467465
if err != nil {
@@ -496,6 +494,14 @@ func (m *Manager) publishBlock(ctx context.Context) error {
496494
// set the commit to current block's signed header
497495
block.SignedHeader.Commit = *commit
498496

497+
// set the validator set using the signer's public key
498+
// TODO(ganesh): need to hook into a module that selects signers
499+
pubKey, err := m.proposerKey.GetPublic().Raw()
500+
if err != nil {
501+
return err
502+
}
503+
block.SignedHeader.Validators = types.ValidatorSet{Validators: []types.Validator{{PublicKey: pubKey}}}
504+
499505
// SaveBlock commits the DB tx
500506
err = m.store.SaveBlock(block, commit)
501507
if err != nil {

conv/abci/block.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ func ToABCIBlock(block *types.Block) (*tmtypes.Block, error) {
7676
if err != nil {
7777
return nil, err
7878
}
79-
abciCommit := ToABCICommit(&block.SignedHeader.Commit)
79+
abciCommit := ToABCICommit(&block.SignedHeader.Commit, block.SignedHeader.Header.BaseHeader.Height, block.SignedHeader.Hash())
8080
// This assumes that we have only one signature
8181
if len(abciCommit.Signatures) == 1 {
8282
abciCommit.Signatures[0].ValidatorAddress = block.SignedHeader.Header.ProposerAddress
@@ -116,12 +116,12 @@ func ToABCIBlockMeta(block *types.Block) (*tmtypes.BlockMeta, error) {
116116
// ToABCICommit converts Rollkit commit into commit format defined by ABCI.
117117
// This function only converts fields that are available in Rollkit commit.
118118
// Other fields (especially ValidatorAddress and Timestamp of Signature) has to be filled by caller.
119-
func ToABCICommit(commit *types.Commit) *tmtypes.Commit {
119+
func ToABCICommit(commit *types.Commit, height uint64, hash types.Hash) *tmtypes.Commit {
120120
tmCommit := tmtypes.Commit{
121-
Height: int64(commit.Height),
121+
Height: int64(height),
122122
Round: 0,
123123
BlockID: tmtypes.BlockID{
124-
Hash: tmbytes.HexBytes(commit.HeaderHash),
124+
Hash: tmbytes.HexBytes(hash),
125125
PartSetHeader: tmtypes.PartSetHeader{},
126126
},
127127
}

node/full_client.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -493,7 +493,7 @@ func (c *FullClient) Commit(ctx context.Context, height *int64) (*ctypes.ResultC
493493
if err != nil {
494494
return nil, err
495495
}
496-
commit := abciconv.ToABCICommit(com)
496+
commit := abciconv.ToABCICommit(com, heightValue, b.SignedHeader.Hash())
497497
block, err := abciconv.ToABCIBlock(b)
498498
if err != nil {
499499
return nil, err

node/full_client_test.go

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -273,7 +273,7 @@ func TestGetCommit(t *testing.T) {
273273
require.NoError(err)
274274

275275
for _, b := range blocks {
276-
err = rpc.node.Store.SaveBlock(b, &types.Commit{Height: uint64(b.SignedHeader.Header.Height())})
276+
err = rpc.node.Store.SaveBlock(b, &types.Commit{})
277277
rpc.node.Store.SetHeight(uint64(b.SignedHeader.Header.Height()))
278278
require.NoError(err)
279279
}
@@ -308,10 +308,7 @@ func TestBlockSearch(t *testing.T) {
308308
heights := []int64{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
309309
for _, h := range heights {
310310
block := getRandomBlock(uint64(h), 5)
311-
err := rpc.node.Store.SaveBlock(block, &types.Commit{
312-
Height: uint64(h),
313-
HeaderHash: block.SignedHeader.Header.Hash(),
314-
})
311+
err := rpc.node.Store.SaveBlock(block, &types.Commit{})
315312
require.NoError(err)
316313
}
317314
indexBlocks(t, rpc, heights)
@@ -562,10 +559,7 @@ func TestBlockchainInfo(t *testing.T) {
562559
heights := []int64{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
563560
for _, h := range heights {
564561
block := getRandomBlock(uint64(h), 5)
565-
err := rpc.node.Store.SaveBlock(block, &types.Commit{
566-
Height: uint64(h),
567-
HeaderHash: block.SignedHeader.Header.Hash(),
568-
})
562+
err := rpc.node.Store.SaveBlock(block, &types.Commit{})
569563
rpc.node.Store.SetHeight(uint64(block.SignedHeader.Header.Height()))
570564
require.NoError(err)
571565
}
@@ -988,12 +982,12 @@ func TestStatus(t *testing.T) {
988982
assert.NotNil(rpc)
989983

990984
earliestBlock := getRandomBlockWithProposer(1, 1, validators[0].Address.Bytes())
991-
err = rpc.node.Store.SaveBlock(earliestBlock, &types.Commit{Height: uint64(earliestBlock.SignedHeader.Header.Height())})
985+
err = rpc.node.Store.SaveBlock(earliestBlock, &types.Commit{})
992986
rpc.node.Store.SetHeight(uint64(earliestBlock.SignedHeader.Header.Height()))
993987
require.NoError(err)
994988

995989
latestBlock := getRandomBlockWithProposer(2, 1, validators[1].Address.Bytes())
996-
err = rpc.node.Store.SaveBlock(latestBlock, &types.Commit{Height: uint64(latestBlock.SignedHeader.Header.Height())})
990+
err = rpc.node.Store.SaveBlock(latestBlock, &types.Commit{})
997991
rpc.node.Store.SetHeight(uint64(latestBlock.SignedHeader.Header.Height()))
998992
require.NoError(err)
999993

proto/rollkit/rollkit.proto

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -49,24 +49,29 @@ message Header {
4949
// pubkey can't be recovered by the signature (e.g. ed25519).
5050
bytes proposer_address = 10;
5151

52-
// public key of the proposer so we can verify the signature
53-
bytes proposer_public_key = 11;
54-
55-
5652
// Hash of block aggregator set, at a time of block creation
57-
bytes aggregators_hash = 12;
53+
bytes aggregators_hash = 11;
5854

5955
// Chain ID the block belongs to
60-
string chain_id = 13;
56+
string chain_id = 12;
6157
}
6258

6359
message Commit {
6460
repeated bytes signatures = 1;
6561
}
6662

63+
message Validator {
64+
bytes public_key = 1;
65+
}
66+
67+
message ValidatorSet {
68+
repeated Validator validators = 1;
69+
}
70+
6771
message SignedHeader {
6872
Header header = 1;
6973
Commit commit = 2;
74+
ValidatorSet validators = 3;
7075
}
7176

7277
message Data {

state/executor.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -446,7 +446,7 @@ func (e *BlockExecutor) generateFraudProof(beginBlockRequest *abci.RequestBeginB
446446
}
447447

448448
func (e *BlockExecutor) getLastCommitHash(lastCommit *types.Commit, header *types.Header) []byte {
449-
lastABCICommit := abciconv.ToABCICommit(lastCommit)
449+
lastABCICommit := abciconv.ToABCICommit(lastCommit, header.BaseHeader.Height, header.Hash())
450450
if len(lastCommit.Signatures) == 1 {
451451
lastABCICommit.Signatures[0].ValidatorAddress = e.proposerAddress
452452
lastABCICommit.Signatures[0].Timestamp = header.Time()

state/executor_test.go

Lines changed: 48 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import (
1212

1313
abci "github.com/tendermint/tendermint/abci/types"
1414
cfg "github.com/tendermint/tendermint/config"
15+
"github.com/tendermint/tendermint/crypto/ed25519"
1516
"github.com/tendermint/tendermint/libs/log"
1617
"github.com/tendermint/tendermint/libs/pubsub/query"
1718
"github.com/tendermint/tendermint/proxy"
@@ -44,7 +45,16 @@ func doTestCreateBlock(t *testing.T, fraudProofsEnabled bool) {
4445
state := types.State{}
4546
state.ConsensusParams.Block.MaxBytes = 100
4647
state.ConsensusParams.Block.MaxGas = 100000
47-
state.Validators = tmtypes.NewValidatorSet(nil)
48+
vKey := ed25519.GenPrivKey()
49+
validators := []*tmtypes.Validator{
50+
{
51+
Address: vKey.PubKey().Address(),
52+
PubKey: vKey.PubKey(),
53+
VotingPower: int64(100),
54+
ProposerPriority: int64(1),
55+
},
56+
}
57+
state.Validators = tmtypes.NewValidatorSet(validators)
4858

4959
// empty block
5060
block := executor.CreateBlock(1, &types.Commit{}, []byte{}, state)
@@ -124,10 +134,19 @@ func doTestApplyBlock(t *testing.T, fraudProofsEnabled bool) {
124134
require.NoError(err)
125135
require.NotNil(headerSub)
126136

137+
vKey := ed25519.GenPrivKey()
138+
validators := []*tmtypes.Validator{
139+
{
140+
Address: vKey.PubKey().Address(),
141+
PubKey: vKey.PubKey(),
142+
VotingPower: int64(100),
143+
ProposerPriority: int64(1),
144+
},
145+
}
127146
state := types.State{
128-
NextValidators: tmtypes.NewValidatorSet(nil),
129-
Validators: tmtypes.NewValidatorSet(nil),
130-
LastValidators: tmtypes.NewValidatorSet(nil),
147+
NextValidators: tmtypes.NewValidatorSet(validators),
148+
Validators: tmtypes.NewValidatorSet(validators),
149+
LastValidators: tmtypes.NewValidatorSet(validators),
131150
}
132151
state.InitialHeight = 1
133152
state.LastBlockHeight = 0
@@ -136,11 +155,23 @@ func doTestApplyBlock(t *testing.T, fraudProofsEnabled bool) {
136155

137156
_ = mpool.CheckTx([]byte{1, 2, 3, 4}, func(r *abci.Response) {}, mempool.TxInfo{})
138157
require.NoError(err)
139-
block := executor.CreateBlock(1, &types.Commit{}, []byte{}, state)
158+
block := executor.CreateBlock(1, &types.Commit{Signatures: []types.Signature{types.Signature([]byte{1, 1, 1})}}, []byte{}, state)
140159
require.NotNil(block)
141160
assert.Equal(int64(1), block.SignedHeader.Header.Height())
142161
assert.Len(block.Data.Txs, 1)
143162

163+
// Update the signature on the block to current from last
164+
headerBytes, _ := block.SignedHeader.Header.MarshalBinary()
165+
sig, _ := vKey.Sign(headerBytes)
166+
block.SignedHeader.Commit = types.Commit{
167+
Signatures: []types.Signature{sig},
168+
}
169+
block.SignedHeader.Validators = types.ValidatorSet{
170+
Validators: []types.Validator{{
171+
PublicKey: vKey.PubKey().Bytes(),
172+
}},
173+
}
174+
144175
newState, resp, err := executor.ApplyBlock(context.Background(), state, block)
145176
require.NoError(err)
146177
require.NotNil(newState)
@@ -154,11 +185,22 @@ func doTestApplyBlock(t *testing.T, fraudProofsEnabled bool) {
154185
require.NoError(mpool.CheckTx([]byte{5, 6, 7, 8, 9}, func(r *abci.Response) {}, mempool.TxInfo{}))
155186
require.NoError(mpool.CheckTx([]byte{1, 2, 3, 4, 5}, func(r *abci.Response) {}, mempool.TxInfo{}))
156187
require.NoError(mpool.CheckTx(make([]byte, 90), func(r *abci.Response) {}, mempool.TxInfo{}))
157-
block = executor.CreateBlock(2, &types.Commit{}, []byte{}, newState)
188+
block = executor.CreateBlock(2, &types.Commit{Signatures: []types.Signature{types.Signature([]byte{1, 1, 1})}}, []byte{}, newState)
158189
require.NotNil(block)
159190
assert.Equal(int64(2), block.SignedHeader.Header.Height())
160191
assert.Len(block.Data.Txs, 3)
161192

193+
headerBytes, _ = block.SignedHeader.Header.MarshalBinary()
194+
sig, _ = vKey.Sign(headerBytes)
195+
block.SignedHeader.Commit = types.Commit{
196+
Signatures: []types.Signature{sig},
197+
}
198+
block.SignedHeader.Validators = types.ValidatorSet{
199+
Validators: []types.Validator{{
200+
PublicKey: vKey.PubKey().Bytes(),
201+
}},
202+
}
203+
162204
newState, resp, err = executor.ApplyBlock(context.Background(), newState, block)
163205
require.NoError(err)
164206
require.NotNil(newState)

types/block.go

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,17 +38,24 @@ type EvidenceData struct {
3838

3939
// Commit contains evidence of block creation.
4040
type Commit struct {
41-
Height uint64
42-
HeaderHash Hash
4341
Signatures []Signature // most of the time this is a single signature
4442
}
4543

44+
type Validator struct {
45+
PublicKey []byte
46+
}
47+
48+
type ValidatorSet struct {
49+
Validators []Validator
50+
}
51+
4652
// SignedHeader combines Header and its Commit.
4753
//
4854
// Used mostly for gossiping.
4955
type SignedHeader struct {
5056
Header
51-
Commit Commit
57+
Commit Commit
58+
Validators ValidatorSet
5259
}
5360

5461
// Signature represents signature of block creator.

0 commit comments

Comments
 (0)