Skip to content

Commit

Permalink
add vote when sign block for compatible with IBC client
Browse files Browse the repository at this point in the history
  • Loading branch information
trinitys7 committed Nov 4, 2023
1 parent 0162c66 commit 5a3670a
Show file tree
Hide file tree
Showing 6 changed files with 82 additions and 14 deletions.
37 changes: 35 additions & 2 deletions block/manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@ import (
"sync/atomic"
"time"

cmbytes "github.com/cometbft/cometbft/libs/bytes"
cmtproto "github.com/cometbft/cometbft/proto/tendermint/types"

goheaderstore "github.com/celestiaorg/go-header/store"
abci "github.com/cometbft/cometbft/abci/types"
cmcrypto "github.com/cometbft/cometbft/crypto"
Expand Down Expand Up @@ -546,6 +549,36 @@ func (m *Manager) getCommit(header types.Header) (*types.Commit, error) {
}, nil
}

// sign to the vote, since we only have one validator, it's similar with sign to the header
// for compatible with light client verify in IBC
func (m *Manager) getCommitBySignVote(header types.Header) (*types.Commit, error) {
vote := cmtproto.Vote{
Type: cmtproto.PrecommitType,
Height: int64(header.Height()),
Round: 0,
// Header hash = block hash in rollkit
BlockID: cmtproto.BlockID{
Hash: cmbytes.HexBytes(header.Hash()),
PartSetHeader: cmtproto.PartSetHeader{},
},
Timestamp: header.Time(),
// proposerAddress = sequencer = validator
ValidatorAddress: header.ProposerAddress,
ValidatorIndex: 0,
}
chainID := header.ChainID()
signBytes := cmtypes.VoteSignBytes(chainID, &vote)

sign, err := m.proposerKey.Sign(signBytes)
if err != nil {
return nil, err
}

return &types.Commit{
Signatures: []types.Signature{sign},
}, nil
}

func (m *Manager) IsProposer() (bool, error) {
m.lastStateMtx.RLock()
defer m.lastStateMtx.RUnlock()
Expand Down Expand Up @@ -611,7 +644,7 @@ func (m *Manager) publishBlock(ctx context.Context) error {
return nil
}
block.SignedHeader.Header.NextAggregatorsHash = m.getNextAggregatorsHash()
commit, err = m.getCommit(block.SignedHeader.Header)
commit, err = m.getCommitBySignVote(block.SignedHeader.Header)
if err != nil {
return err
}
Expand Down Expand Up @@ -642,7 +675,7 @@ func (m *Manager) publishBlock(ctx context.Context) error {

block.SignedHeader.Header.NextAggregatorsHash = newState.NextValidators.Hash()

commit, err = m.getCommit(block.SignedHeader.Header)
commit, err = m.getCommitBySignVote(block.SignedHeader.Header)
if err != nil {
return err
}
Expand Down
8 changes: 7 additions & 1 deletion node/full_client.go
Original file line number Diff line number Diff line change
Expand Up @@ -484,14 +484,20 @@ func (c *FullClient) BlockResults(ctx context.Context, height *int64) (*ctypes.R
func (c *FullClient) Commit(ctx context.Context, height *int64) (*ctypes.ResultCommit, error) {
heightValue := c.normalizeHeight(height)
com, err := c.node.Store.LoadCommit(heightValue)

//
if err != nil {
return nil, err
}
b, err := c.node.Store.LoadBlock(heightValue)
if err != nil {
return nil, err
}
commit := com.ToABCICommit(heightValue, b.Hash())

// we only have one validator
val := b.SignedHeader.Validators.Validators[0].Address

commit := com.ToABCICommit(heightValue, b.Hash(), val, b.SignedHeader.Time())
block, err := abciconv.ToABCIBlock(b)
if err != nil {
return nil, err
Expand Down
7 changes: 6 additions & 1 deletion types/abci/block.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,12 @@ func ToABCIBlock(block *types.Block) (*cmtypes.Block, error) {
if err != nil {
return nil, err
}
abciCommit := block.SignedHeader.Commit.ToABCICommit(block.Height(), block.Hash())

valsAddr := block.SignedHeader.Validators
// we only have one validator.
val := valsAddr.Validators[0].Address
abciCommit := block.SignedHeader.Commit.ToABCICommit(block.Height(), block.Hash(), val, block.Time())

// This assumes that we have only one signature
if len(abciCommit.Signatures) == 1 {
abciCommit.Signatures[0].ValidatorAddress = block.SignedHeader.ProposerAddress
Expand Down
4 changes: 2 additions & 2 deletions types/abci/block_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -131,8 +131,8 @@ func TestToABCIBlock(t *testing.T) {
if err != nil {
t.Fatal(err)
}

abciCommit := block.SignedHeader.Commit.ToABCICommit(block.Height(), block.Hash())
val := block.SignedHeader.Validators.Validators[0].Address
abciCommit := block.SignedHeader.Commit.ToABCICommit(block.Height(), block.Hash(), val, block.Time())

if len(abciCommit.Signatures) == 1 {
abciCommit.Signatures[0].ValidatorAddress = block.SignedHeader.ProposerAddress
Expand Down
10 changes: 6 additions & 4 deletions types/block.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ type IntermediateStateRoots struct {
// ToABCICommit converts Rollkit commit into commit format defined by ABCI.
// This function only converts fields that are available in Rollkit commit.
// Other fields (especially ValidatorAddress and Timestamp of Signature) has to be filled by caller.
func (c *Commit) ToABCICommit(height uint64, hash Hash) *cmtypes.Commit {
func (c *Commit) ToABCICommit(height uint64, hash Hash, val cmtypes.Address, time time.Time) *cmtypes.Commit {
tmCommit := cmtypes.Commit{
Height: int64(height),
Round: 0,
Expand All @@ -73,8 +73,10 @@ func (c *Commit) ToABCICommit(height uint64, hash Hash) *cmtypes.Commit {
}
for i, sig := range c.Signatures {
commitSig := cmtypes.CommitSig{
BlockIDFlag: cmtypes.BlockIDFlagCommit,
Signature: sig,
BlockIDFlag: cmtypes.BlockIDFlagCommit,
Signature: sig,
ValidatorAddress: val,
Timestamp: time,
}
tmCommit.Signatures[i] = commitSig
}
Expand All @@ -83,7 +85,7 @@ func (c *Commit) ToABCICommit(height uint64, hash Hash) *cmtypes.Commit {
}

func (c *Commit) GetCommitHash(header *Header, proposerAddress []byte) []byte {
lastABCICommit := c.ToABCICommit(header.Height(), header.Hash())
lastABCICommit := c.ToABCICommit(header.Height(), header.Hash(), proposerAddress, header.Time())
// Rollkit does not support a multi signature scheme so there can only be one signature
if len(c.Signatures) == 1 {
lastABCICommit.Signatures[0].ValidatorAddress = proposerAddress
Expand Down
30 changes: 26 additions & 4 deletions types/signed_header.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,11 @@ import (
"errors"
"fmt"

cmtproto "github.com/cometbft/cometbft/proto/tendermint/types"

"github.com/celestiaorg/go-header"
"github.com/cometbft/cometbft/crypto/ed25519"
cmbytes "github.com/cometbft/cometbft/libs/bytes"
cmtypes "github.com/cometbft/cometbft/types"
)

Expand Down Expand Up @@ -110,11 +113,30 @@ func (sh *SignedHeader) ValidateBasic() error {
signature := sh.Commit.Signatures[0]
proposer := sh.Validators.GetProposer()
var pubKey ed25519.PubKey = proposer.PubKey.Bytes()
msg, err := sh.Header.MarshalBinary()
if err != nil {
return errors.New("signature verification failed, unable to marshal header")
// msg, err := sh.Header.MarshalBinary()
// if err != nil {
// return errors.New("signature verification failed, unable to marshal header")
// }
header := sh.Header
// using vote here
vote := cmtproto.Vote{
Type: cmtproto.PrecommitType,
Height: int64(header.Height()),
Round: 0,
// Header hash = block hash in rollkit
BlockID: cmtproto.BlockID{
Hash: cmbytes.HexBytes(header.Hash()),
PartSetHeader: cmtproto.PartSetHeader{},
},
Timestamp: header.Time(),
// proposerAddress = sequencer = validator
ValidatorAddress: header.ProposerAddress,
ValidatorIndex: 0,
}
if !pubKey.VerifySignature(msg, signature) {
chainID := header.ChainID()
signBytes := cmtypes.VoteSignBytes(chainID, &vote)

if !pubKey.VerifySignature(signBytes, signature) {
return ErrSignatureVerificationFailed
}

Expand Down

0 comments on commit 5a3670a

Please sign in to comment.