update package types

This commit is contained in:
Callum Waters
2021-08-24 13:25:49 +02:00
parent 4d0da50e41
commit dcf91478f8
18 changed files with 264 additions and 264 deletions
+15 -13
View File
@@ -9,12 +9,14 @@ import (
"github.com/stretchr/testify/mock"
"github.com/stretchr/testify/require"
abcitypes "github.com/tendermint/tendermint/abci/types"
tmcfg "github.com/tendermint/tendermint/config"
"github.com/tendermint/tendermint/pkg/abci"
"github.com/tendermint/tendermint/pkg/block"
"github.com/tendermint/tendermint/pkg/mempool"
prototmstate "github.com/tendermint/tendermint/proto/tendermint/state"
"github.com/tendermint/tendermint/state/indexer"
evmocks "github.com/tendermint/tendermint/state/indexer/mocks"
"github.com/tendermint/tendermint/state/mocks"
"github.com/tendermint/tendermint/types"
)
const (
@@ -116,27 +118,27 @@ func TestLoadBlockStore(t *testing.T) {
func TestReIndexEvent(t *testing.T) {
mockBlockStore := &mocks.BlockStore{}
mockStateStore := &mocks.Store{}
mockEventSink := &mocks.EventSink{}
mockEventSink := &evmocks.EventSink{}
mockBlockStore.
On("Base").Return(base).
On("Height").Return(height).
On("LoadBlock", base).Return(nil).Once().
On("LoadBlock", base).Return(&types.Block{Data: types.Data{Txs: types.Txs{make(types.Tx, 1)}}}).
On("LoadBlock", height).Return(&types.Block{Data: types.Data{Txs: types.Txs{make(types.Tx, 1)}}})
On("LoadBlock", base).Return(&block.Block{Data: block.Data{Txs: mempool.Txs{make(mempool.Tx, 1)}}}).
On("LoadBlock", height).Return(&block.Block{Data: block.Data{Txs: mempool.Txs{make(mempool.Tx, 1)}}})
mockEventSink.
On("Type").Return(indexer.KV).
On("IndexBlockEvents", mock.AnythingOfType("types.EventDataNewBlockHeader")).Return(errors.New("")).Once().
On("IndexBlockEvents", mock.AnythingOfType("types.EventDataNewBlockHeader")).Return(nil).
On("IndexTxEvents", mock.AnythingOfType("[]*types.TxResult")).Return(errors.New("")).Once().
On("IndexTxEvents", mock.AnythingOfType("[]*types.TxResult")).Return(nil)
On("IndexBlockEvents", mock.AnythingOfType("events.EventDataNewBlockHeader")).Return(errors.New("")).Once().
On("IndexBlockEvents", mock.AnythingOfType("events.EventDataNewBlockHeader")).Return(nil).
On("IndexTxEvents", mock.AnythingOfType("[]*abci.TxResult")).Return(errors.New("")).Once().
On("IndexTxEvents", mock.AnythingOfType("[]*abci.TxResult")).Return(nil)
dtx := abcitypes.ResponseDeliverTx{}
dtx := abci.ResponseDeliverTx{}
abciResp := &prototmstate.ABCIResponses{
DeliverTxs: []*abcitypes.ResponseDeliverTx{&dtx},
EndBlock: &abcitypes.ResponseEndBlock{},
BeginBlock: &abcitypes.ResponseBeginBlock{},
DeliverTxs: []*abci.ResponseDeliverTx{&dtx},
EndBlock: &abci.ResponseEndBlock{},
BeginBlock: &abci.ResponseBeginBlock{},
}
mockStateStore.
+3 -3
View File
@@ -23,9 +23,9 @@ type Block struct {
mtx tmsync.Mutex
metadata.Header `json:"header"`
Data `json:"data"`
Evidence EvidenceData `json:"evidence"`
LastCommit *metadata.Commit `json:"last_commit"`
Data `json:"data"`
Evidence EvidenceData `json:"evidence"`
LastCommit *metadata.Commit `json:"last_commit"`
}
// ValidateBasic performs basic validation that doesn't involve state data.
+2 -2
View File
@@ -12,9 +12,9 @@ import (
// BlockMeta contains meta information.
type BlockMeta struct {
BlockID metadata.BlockID `json:"block_id"`
BlockSize int `json:"block_size"`
BlockSize int `json:"block_size"`
Header metadata.Header `json:"header"`
NumTxs int `json:"num_txs"`
NumTxs int `json:"num_txs"`
}
// NewBlockMeta returns a new BlockMeta.
+5 -5
View File
@@ -25,12 +25,12 @@ var (
// If POLRound >= 0, then BlockID corresponds to the block that is locked in POLRound.
type Proposal struct {
Type tmproto.SignedMsgType
Height int64 `json:"height"`
Round int32 `json:"round"` // there can not be greater than 2_147_483_647 rounds
POLRound int32 `json:"pol_round"` // -1 if null.
Height int64 `json:"height"`
Round int32 `json:"round"` // there can not be greater than 2_147_483_647 rounds
POLRound int32 `json:"pol_round"` // -1 if null.
BlockID metadata.BlockID `json:"block_id"`
Timestamp time.Time `json:"timestamp"`
Signature []byte `json:"signature"`
Timestamp time.Time `json:"timestamp"`
Signature []byte `json:"signature"`
}
// NewProposal returns a new Proposal.
+1 -1
View File
@@ -1,8 +1,8 @@
package consensus
import (
abci "github.com/tendermint/tendermint/abci/types"
cryptoenc "github.com/tendermint/tendermint/crypto/encoding"
"github.com/tendermint/tendermint/pkg/abci"
)
//-------------------------------------------------------
+1 -1
View File
@@ -6,10 +6,10 @@ import (
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
abci "github.com/tendermint/tendermint/abci/types"
"github.com/tendermint/tendermint/crypto"
"github.com/tendermint/tendermint/crypto/ed25519"
cryptoenc "github.com/tendermint/tendermint/crypto/encoding"
"github.com/tendermint/tendermint/pkg/abci"
"github.com/tendermint/tendermint/pkg/consensus"
)
+5
View File
@@ -171,3 +171,8 @@ func ValidatorFromProto(vp *tmproto.Validator) (*Validator, error) {
return v, nil
}
type ValidatorInfo struct {
Address Address `json:"address"`
Index int32 `json:"index"`
}
+1 -1
View File
@@ -52,7 +52,7 @@ type Vote struct {
Type tmproto.SignedMsgType `json:"type"`
Height int64 `json:"height"`
Round int32 `json:"round"` // assume there will not be greater than 2_147_483_647 rounds
BlockID metadata.BlockID `json:"block_id"` // zero if vote is nil.
BlockID metadata.BlockID `json:"block_id"` // zero if vote is nil.
Timestamp time.Time `json:"timestamp"`
ValidatorAddress Address `json:"validator_address"`
ValidatorIndex int32 `json:"validator_index"`
+5 -5
View File
@@ -68,10 +68,10 @@ type VoteSet struct {
mtx tmsync.Mutex
votesBitArray *bits.BitArray
votes []*Vote // Primary votes to share
sum int64 // Sum of voting power for seen votes, discounting conflicts
votes []*Vote // Primary votes to share
sum int64 // Sum of voting power for seen votes, discounting conflicts
maj23 *metadata.BlockID // First 2/3 majority seen
votesByBlock map[string]*blockVotes // string(blockHash|blockParts) -> blockVotes
votesByBlock map[string]*blockVotes // string(blockHash|blockParts) -> blockVotes
peerMaj23s map[P2PID]metadata.BlockID // Maj23 for each peer
}
@@ -521,8 +521,8 @@ func (voteSet *VoteSet) MarshalJSON() ([]byte, error) {
// NOTE: insufficient for unmarshaling from (compressed votes)
// TODO: make the peerMaj23s nicer to read (eg just the block hash)
type VoteSetJSON struct {
Votes []string `json:"votes"`
VotesBitArray string `json:"votes_bit_array"`
Votes []string `json:"votes"`
VotesBitArray string `json:"votes_bit_array"`
PeerMaj23s map[P2PID]metadata.BlockID `json:"peer_maj_23s"`
}
+8 -8
View File
@@ -5,10 +5,10 @@ import (
"fmt"
"strings"
"github.com/tendermint/tendermint/abci/types"
"github.com/tendermint/tendermint/libs/log"
tmpubsub "github.com/tendermint/tendermint/libs/pubsub"
"github.com/tendermint/tendermint/libs/service"
"github.com/tendermint/tendermint/pkg/abci"
"github.com/tendermint/tendermint/pkg/mempool"
)
@@ -107,9 +107,9 @@ func (b *EventBus) Publish(eventValue string, eventData TMEventData) error {
ctx := context.Background()
tokens := strings.Split(EventTypeKey, ".")
event := types.Event{
event := abci.Event{
Type: tokens[0],
Attributes: []types.EventAttribute{
Attributes: []abci.EventAttribute{
{
Key: tokens[1],
Value: eventValue,
@@ -117,7 +117,7 @@ func (b *EventBus) Publish(eventValue string, eventData TMEventData) error {
},
}
return b.pubsub.PublishWithEvents(ctx, eventData, []types.Event{event})
return b.pubsub.PublishWithEvents(ctx, eventData, []abci.Event{event})
}
func (b *EventBus) PublishEventNewBlock(data EventDataNewBlock) error {
@@ -174,9 +174,9 @@ func (b *EventBus) PublishEventTx(data EventDataTx) error {
events = append(events, EventTx)
tokens := strings.Split(TxHashKey, ".")
events = append(events, types.Event{
events = append(events, abci.Event{
Type: tokens[0],
Attributes: []types.EventAttribute{
Attributes: []abci.EventAttribute{
{
Key: tokens[1],
Value: fmt.Sprintf("%X", mempool.Tx(data.Tx).Hash()),
@@ -185,9 +185,9 @@ func (b *EventBus) PublishEventTx(data EventDataTx) error {
})
tokens = strings.Split(TxHeightKey, ".")
events = append(events, types.Event{
events = append(events, abci.Event{
Type: tokens[0],
Attributes: []types.EventAttribute{
Attributes: []abci.EventAttribute{
{
Key: tokens[1],
Value: fmt.Sprintf("%d", data.Height),
+1 -1
View File
@@ -10,9 +10,9 @@ import (
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
abci "github.com/tendermint/tendermint/abci/types"
tmpubsub "github.com/tendermint/tendermint/libs/pubsub"
tmquery "github.com/tendermint/tendermint/libs/pubsub/query"
"github.com/tendermint/tendermint/pkg/abci"
"github.com/tendermint/tendermint/pkg/block"
"github.com/tendermint/tendermint/pkg/events"
"github.com/tendermint/tendermint/pkg/evidence"
+3 -8
View File
@@ -4,10 +4,10 @@ import (
"fmt"
"strings"
abci "github.com/tendermint/tendermint/abci/types"
tmjson "github.com/tendermint/tendermint/libs/json"
tmpubsub "github.com/tendermint/tendermint/libs/pubsub"
tmquery "github.com/tendermint/tendermint/libs/pubsub/query"
"github.com/tendermint/tendermint/pkg/abci"
"github.com/tendermint/tendermint/pkg/block"
"github.com/tendermint/tendermint/pkg/consensus"
@@ -118,7 +118,7 @@ func init() {
// but some (an input to a call tx or a receive) are more exotic
type EventDataNewBlock struct {
Block *block.Block `json:"block"`
Block *block.Block `json:"block"`
BlockID metadata.BlockID `json:"block_id"`
ResultBeginBlock abci.ResponseBeginBlock `json:"result_begin_block"`
@@ -151,17 +151,12 @@ type EventDataRoundState struct {
Step string `json:"step"`
}
type ValidatorInfo struct {
Address consensus.Address `json:"address"`
Index int32 `json:"index"`
}
type EventDataNewRound struct {
Height int64 `json:"height"`
Round int32 `json:"round"`
Step string `json:"step"`
Proposer ValidatorInfo `json:"proposer"`
Proposer consensus.ValidatorInfo `json:"proposer"`
}
type EventDataCompleteProposal struct {
+4 -4
View File
@@ -10,11 +10,11 @@ import (
"strings"
"time"
abci "github.com/tendermint/tendermint/abci/types"
"github.com/tendermint/tendermint/crypto/merkle"
"github.com/tendermint/tendermint/crypto/tmhash"
tmjson "github.com/tendermint/tendermint/libs/json"
tmrand "github.com/tendermint/tendermint/libs/rand"
"github.com/tendermint/tendermint/pkg/abci"
"github.com/tendermint/tendermint/pkg/consensus"
"github.com/tendermint/tendermint/pkg/light"
"github.com/tendermint/tendermint/pkg/metadata"
@@ -313,7 +313,7 @@ func (l *LightClientAttackEvidence) Bytes() []byte {
// the malicious validators were and returns them. This is used both for forming the ByzantineValidators
// field and for validating that it is correct. Validators are ordered based on validator power
func (l *LightClientAttackEvidence) GetByzantineValidators(commonVals *consensus.ValidatorSet,
trusted *light.SignedHeader) []*consensus.Validator {
trusted *metadata.SignedHeader) []*consensus.Validator {
var validators []*consensus.Validator
// First check if the header is invalid. This means that it is a lunatic attack and therefore we take the
// validators who are in the commonVals and voted for the lunatic header
@@ -454,7 +454,7 @@ func (l *LightClientAttackEvidence) ValidateBasic() error {
// invalid.
func (l *LightClientAttackEvidence) ValidateABCI(
commonVals *consensus.ValidatorSet,
trustedHeader *light.SignedHeader,
trustedHeader *metadata.SignedHeader,
evidenceTime time.Time,
) error {
@@ -510,7 +510,7 @@ func (l *LightClientAttackEvidence) ValidateABCI(
// total voting power and byantine validators
func (l *LightClientAttackEvidence) GenerateABCI(
commonVals *consensus.ValidatorSet,
trustedHeader *light.SignedHeader,
trustedHeader *metadata.SignedHeader,
evidenceTime time.Time,
) {
l.Timestamp = evidenceTime
+5 -5
View File
@@ -109,7 +109,7 @@ func TestLightClientAttackEvidenceBasic(t *testing.T) {
require.NoError(t, err)
lcae := &evidence.LightClientAttackEvidence{
ConflictingBlock: &light.LightBlock{
SignedHeader: &light.SignedHeader{
SignedHeader: &metadata.SignedHeader{
Header: header,
Commit: commit,
},
@@ -139,7 +139,7 @@ func TestLightClientAttackEvidenceBasic(t *testing.T) {
for _, tc := range testCases {
lcae := &evidence.LightClientAttackEvidence{
ConflictingBlock: &light.LightBlock{
SignedHeader: &light.SignedHeader{
SignedHeader: &metadata.SignedHeader{
Header: header,
Commit: commit,
},
@@ -169,7 +169,7 @@ func TestLightClientAttackEvidenceValidation(t *testing.T) {
require.NoError(t, err)
lcae := &evidence.LightClientAttackEvidence{
ConflictingBlock: &light.LightBlock{
SignedHeader: &light.SignedHeader{
SignedHeader: &metadata.SignedHeader{
Header: header,
Commit: commit,
},
@@ -209,7 +209,7 @@ func TestLightClientAttackEvidenceValidation(t *testing.T) {
t.Run(tc.testName, func(t *testing.T) {
lcae := &evidence.LightClientAttackEvidence{
ConflictingBlock: &light.LightBlock{
SignedHeader: &light.SignedHeader{
SignedHeader: &metadata.SignedHeader{
Header: header,
Commit: commit,
},
@@ -358,7 +358,7 @@ func TestEvidenceVectors(t *testing.T) {
require.NoError(t, err)
lcae := &evidence.LightClientAttackEvidence{
ConflictingBlock: &light.LightBlock{
SignedHeader: &light.SignedHeader{
SignedHeader: &metadata.SignedHeader{
Header: header,
Commit: commit,
},
+4 -113
View File
@@ -6,15 +6,15 @@ import (
"fmt"
"github.com/tendermint/tendermint/pkg/consensus"
meta "github.com/tendermint/tendermint/pkg/metadata"
"github.com/tendermint/tendermint/pkg/metadata"
tmproto "github.com/tendermint/tendermint/proto/tendermint/types"
)
// LightBlock is a SignedHeader and a ValidatorSet.
// It is the basis of the light client
type LightBlock struct {
*SignedHeader `json:"signed_header"`
ValidatorSet *consensus.ValidatorSet `json:"validator_set"`
*metadata.SignedHeader `json:"signed_header"`
ValidatorSet *consensus.ValidatorSet `json:"validator_set"`
}
// ValidateBasic checks that the data is correct and consistent
@@ -95,7 +95,7 @@ func LightBlockFromProto(pb *tmproto.LightBlock) (*LightBlock, error) {
lb := new(LightBlock)
if pb.SignedHeader != nil {
sh, err := SignedHeaderFromProto(pb.SignedHeader)
sh, err := metadata.SignedHeaderFromProto(pb.SignedHeader)
if err != nil {
return nil, err
}
@@ -112,112 +112,3 @@ func LightBlockFromProto(pb *tmproto.LightBlock) (*LightBlock, error) {
return lb, nil
}
//-----------------------------------------------------------------------------
// SignedHeader is a header along with the commits that prove it.
type SignedHeader struct {
*meta.Header `json:"header"`
Commit *meta.Commit `json:"commit"`
}
// ValidateBasic does basic consistency checks and makes sure the header
// and commit are consistent.
//
// NOTE: This does not actually check the cryptographic signatures. Make sure
// to use a Verifier to validate the signatures actually provide a
// significantly strong proof for this header's validity.
func (sh SignedHeader) ValidateBasic(chainID string) error {
if sh.Header == nil {
return errors.New("missing header")
}
if sh.Commit == nil {
return errors.New("missing commit")
}
if err := sh.Header.ValidateBasic(); err != nil {
return fmt.Errorf("invalid header: %w", err)
}
if err := sh.Commit.ValidateBasic(); err != nil {
return fmt.Errorf("invalid commit: %w", err)
}
if sh.ChainID != chainID {
return fmt.Errorf("header belongs to another chain %q, not %q", sh.ChainID, chainID)
}
// Make sure the header is consistent with the commit.
if sh.Commit.Height != sh.Height {
return fmt.Errorf("header and commit height mismatch: %d vs %d", sh.Height, sh.Commit.Height)
}
if hhash, chash := sh.Header.Hash(), sh.Commit.BlockID.Hash; !bytes.Equal(hhash, chash) {
return fmt.Errorf("commit signs block %X, header is block %X", chash, hhash)
}
return nil
}
// String returns a string representation of SignedHeader.
func (sh SignedHeader) String() string {
return sh.StringIndented("")
}
// StringIndented returns an indented string representation of SignedHeader.
//
// Header
// Commit
func (sh SignedHeader) StringIndented(indent string) string {
return fmt.Sprintf(`SignedHeader{
%s %v
%s %v
%s}`,
indent, sh.Header.StringIndented(indent+" "),
indent, sh.Commit.StringIndented(indent+" "),
indent)
}
// ToProto converts SignedHeader to protobuf
func (sh *SignedHeader) ToProto() *tmproto.SignedHeader {
if sh == nil {
return nil
}
psh := new(tmproto.SignedHeader)
if sh.Header != nil {
psh.Header = sh.Header.ToProto()
}
if sh.Commit != nil {
psh.Commit = sh.Commit.ToProto()
}
return psh
}
// FromProto sets a protobuf SignedHeader to the given pointer.
// It returns an error if the header or the commit is invalid.
func SignedHeaderFromProto(shp *tmproto.SignedHeader) (*SignedHeader, error) {
if shp == nil {
return nil, errors.New("nil SignedHeader")
}
sh := new(SignedHeader)
if shp.Header != nil {
h, err := meta.HeaderFromProto(shp.Header)
if err != nil {
return nil, err
}
sh.Header = &h
}
if shp.Commit != nil {
c, err := meta.CommitFromProto(shp.Commit)
if err != nil {
return nil, err
}
sh.Commit = c
}
return sh, nil
}
+7 -94
View File
@@ -1,14 +1,11 @@
package light_test
import (
"math"
"testing"
"time"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/tendermint/tendermint/crypto"
test "github.com/tendermint/tendermint/internal/test/factory"
"github.com/tendermint/tendermint/pkg/consensus"
"github.com/tendermint/tendermint/pkg/light"
@@ -29,21 +26,21 @@ func TestLightBlockValidateBasic(t *testing.T) {
vals3.Proposer = &consensus.Validator{}
commit.BlockID.Hash = header.Hash()
sh := &light.SignedHeader{
sh := &metadata.SignedHeader{
Header: header,
Commit: commit,
}
testCases := []struct {
name string
sh *light.SignedHeader
sh *metadata.SignedHeader
vals *consensus.ValidatorSet
expectErr bool
}{
{"valid light block", sh, vals, false},
{"hashes don't match", sh, vals2, true},
{"invalid validator set", sh, vals3, true},
{"invalid signed header", &light.SignedHeader{Header: header, Commit: test.MakeRandomCommit(time.Now())}, vals, true},
{"invalid signed header", &metadata.SignedHeader{Header: header, Commit: test.MakeRandomCommit(time.Now())}, vals, true},
}
for _, tc := range testCases {
@@ -73,22 +70,22 @@ func TestLightBlockProtobuf(t *testing.T) {
vals3.Proposer = &consensus.Validator{}
commit.BlockID.Hash = header.Hash()
sh := &light.SignedHeader{
sh := &metadata.SignedHeader{
Header: header,
Commit: commit,
}
testCases := []struct {
name string
sh *light.SignedHeader
sh *metadata.SignedHeader
vals *consensus.ValidatorSet
toProtoErr bool
toBlockErr bool
}{
{"valid light block", sh, vals, false, false},
{"empty signed header", &light.SignedHeader{}, vals, false, false},
{"empty signed header", &metadata.SignedHeader{}, vals, false, false},
{"empty validator set", sh, &consensus.ValidatorSet{}, false, true},
{"empty light block", &light.SignedHeader{}, &consensus.ValidatorSet{}, false, true},
{"empty light block", &metadata.SignedHeader{}, &consensus.ValidatorSet{}, false, true},
}
for _, tc := range testCases {
@@ -113,87 +110,3 @@ func TestLightBlockProtobuf(t *testing.T) {
}
}
func TestSignedHeaderValidateBasic(t *testing.T) {
commit := test.MakeRandomCommit(time.Now())
chainID := "𠜎"
timestamp := time.Date(math.MaxInt64, 0, 0, 0, 0, 0, math.MaxInt64, time.UTC)
h := metadata.Header{
Version: version.Consensus{Block: version.BlockProtocol, App: math.MaxInt64},
ChainID: chainID,
Height: commit.Height,
Time: timestamp,
LastBlockID: commit.BlockID,
LastCommitHash: commit.Hash(),
DataHash: commit.Hash(),
ValidatorsHash: commit.Hash(),
NextValidatorsHash: commit.Hash(),
ConsensusHash: commit.Hash(),
AppHash: commit.Hash(),
LastResultsHash: commit.Hash(),
EvidenceHash: commit.Hash(),
ProposerAddress: crypto.AddressHash([]byte("proposer_address")),
}
validSignedHeader := light.SignedHeader{Header: &h, Commit: commit}
validSignedHeader.Commit.BlockID.Hash = validSignedHeader.Hash()
invalidSignedHeader := light.SignedHeader{}
testCases := []struct {
testName string
shHeader *metadata.Header
shCommit *metadata.Commit
expectErr bool
}{
{"Valid Signed Header", validSignedHeader.Header, validSignedHeader.Commit, false},
{"Invalid Signed Header", invalidSignedHeader.Header, validSignedHeader.Commit, true},
{"Invalid Signed Header", validSignedHeader.Header, invalidSignedHeader.Commit, true},
}
for _, tc := range testCases {
tc := tc
t.Run(tc.testName, func(t *testing.T) {
sh := light.SignedHeader{
Header: tc.shHeader,
Commit: tc.shCommit,
}
err := sh.ValidateBasic(validSignedHeader.Header.ChainID)
assert.Equalf(
t,
tc.expectErr,
err != nil,
"Validate Basic had an unexpected result",
err,
)
})
}
}
func TestSignedHeaderProtoBuf(t *testing.T) {
commit := test.MakeRandomCommit(time.Now())
h := test.MakeRandomHeader()
sh := light.SignedHeader{Header: h, Commit: commit}
testCases := []struct {
msg string
sh1 *light.SignedHeader
expPass bool
}{
{"empty SignedHeader 2", &light.SignedHeader{}, true},
{"success", &sh, true},
{"failure nil", nil, false},
}
for _, tc := range testCases {
protoSignedHeader := tc.sh1.ToProto()
sh, err := light.SignedHeaderFromProto(protoSignedHeader)
if tc.expPass {
require.NoError(t, err, tc.msg)
require.Equal(t, tc.sh1, sh, tc.msg)
} else {
require.Error(t, err, tc.msg)
}
}
}
+110
View File
@@ -1,6 +1,7 @@
package metadata
import (
"bytes"
"errors"
"fmt"
"time"
@@ -291,3 +292,112 @@ func HeaderFromProto(ph *tmproto.Header) (Header, error) {
}
//-------------------------------------
//-----------------------------------------------------------------------------
// SignedHeader is a header along with the commits that prove it.
type SignedHeader struct {
*Header `json:"header"`
Commit *Commit `json:"commit"`
}
// ValidateBasic does basic consistency checks and makes sure the header
// and commit are consistent.
//
// NOTE: This does not actually check the cryptographic signatures. Make sure
// to use a Verifier to validate the signatures actually provide a
// significantly strong proof for this header's validity.
func (sh SignedHeader) ValidateBasic(chainID string) error {
if sh.Header == nil {
return errors.New("missing header")
}
if sh.Commit == nil {
return errors.New("missing commit")
}
if err := sh.Header.ValidateBasic(); err != nil {
return fmt.Errorf("invalid header: %w", err)
}
if err := sh.Commit.ValidateBasic(); err != nil {
return fmt.Errorf("invalid commit: %w", err)
}
if sh.ChainID != chainID {
return fmt.Errorf("header belongs to another chain %q, not %q", sh.ChainID, chainID)
}
// Make sure the header is consistent with the commit.
if sh.Commit.Height != sh.Height {
return fmt.Errorf("header and commit height mismatch: %d vs %d", sh.Height, sh.Commit.Height)
}
if hhash, chash := sh.Header.Hash(), sh.Commit.BlockID.Hash; !bytes.Equal(hhash, chash) {
return fmt.Errorf("commit signs block %X, header is block %X", chash, hhash)
}
return nil
}
// String returns a string representation of SignedHeader.
func (sh SignedHeader) String() string {
return sh.StringIndented("")
}
// StringIndented returns an indented string representation of SignedHeader.
//
// Header
// Commit
func (sh SignedHeader) StringIndented(indent string) string {
return fmt.Sprintf(`SignedHeader{
%s %v
%s %v
%s}`,
indent, sh.Header.StringIndented(indent+" "),
indent, sh.Commit.StringIndented(indent+" "),
indent)
}
// ToProto converts SignedHeader to protobuf
func (sh *SignedHeader) ToProto() *tmproto.SignedHeader {
if sh == nil {
return nil
}
psh := new(tmproto.SignedHeader)
if sh.Header != nil {
psh.Header = sh.Header.ToProto()
}
if sh.Commit != nil {
psh.Commit = sh.Commit.ToProto()
}
return psh
}
// FromProto sets a protobuf SignedHeader to the given pointer.
// It returns an error if the header or the commit is invalid.
func SignedHeaderFromProto(shp *tmproto.SignedHeader) (*SignedHeader, error) {
if shp == nil {
return nil, errors.New("nil SignedHeader")
}
sh := new(SignedHeader)
if shp.Header != nil {
h, err := HeaderFromProto(shp.Header)
if err != nil {
return nil, err
}
sh.Header = &h
}
if shp.Commit != nil {
c, err := CommitFromProto(shp.Commit)
if err != nil {
return nil, err
}
sh.Commit = c
}
return sh, nil
}
+84
View File
@@ -494,3 +494,87 @@ func TestHeaderHashVector(t *testing.T) {
require.Equal(t, tc.expBytes, hex.EncodeToString(hash))
}
}
func TestSignedHeaderValidateBasic(t *testing.T) {
commit := test.MakeRandomCommit(time.Now())
chainID := "𠜎"
timestamp := time.Date(math.MaxInt64, 0, 0, 0, 0, 0, math.MaxInt64, time.UTC)
h := metadata.Header{
Version: version.Consensus{Block: version.BlockProtocol, App: math.MaxInt64},
ChainID: chainID,
Height: commit.Height,
Time: timestamp,
LastBlockID: commit.BlockID,
LastCommitHash: commit.Hash(),
DataHash: commit.Hash(),
ValidatorsHash: commit.Hash(),
NextValidatorsHash: commit.Hash(),
ConsensusHash: commit.Hash(),
AppHash: commit.Hash(),
LastResultsHash: commit.Hash(),
EvidenceHash: commit.Hash(),
ProposerAddress: crypto.AddressHash([]byte("proposer_address")),
}
validSignedHeader := metadata.SignedHeader{Header: &h, Commit: commit}
validSignedHeader.Commit.BlockID.Hash = validSignedHeader.Hash()
invalidSignedHeader := metadata.SignedHeader{}
testCases := []struct {
testName string
shHeader *metadata.Header
shCommit *metadata.Commit
expectErr bool
}{
{"Valid Signed Header", validSignedHeader.Header, validSignedHeader.Commit, false},
{"Invalid Signed Header", invalidSignedHeader.Header, validSignedHeader.Commit, true},
{"Invalid Signed Header", validSignedHeader.Header, invalidSignedHeader.Commit, true},
}
for _, tc := range testCases {
tc := tc
t.Run(tc.testName, func(t *testing.T) {
sh := metadata.SignedHeader{
Header: tc.shHeader,
Commit: tc.shCommit,
}
err := sh.ValidateBasic(validSignedHeader.Header.ChainID)
assert.Equalf(
t,
tc.expectErr,
err != nil,
"Validate Basic had an unexpected result",
err,
)
})
}
}
func TestSignedHeaderProtoBuf(t *testing.T) {
commit := test.MakeRandomCommit(time.Now())
h := test.MakeRandomHeader()
sh := metadata.SignedHeader{Header: h, Commit: commit}
testCases := []struct {
msg string
sh1 *metadata.SignedHeader
expPass bool
}{
{"empty SignedHeader 2", &metadata.SignedHeader{}, true},
{"success", &sh, true},
{"failure nil", nil, false},
}
for _, tc := range testCases {
protoSignedHeader := tc.sh1.ToProto()
sh, err := metadata.SignedHeaderFromProto(protoSignedHeader)
if tc.expPass {
require.NoError(t, err, tc.msg)
require.Equal(t, tc.sh1, sh, tc.msg)
} else {
require.Error(t, err, tc.msg)
}
}
}