diff options
Diffstat (limited to 'core/types')
-rw-r--r-- | core/types/block.go | 39 | ||||
-rw-r--r-- | core/types/block_test.go | 14 |
2 files changed, 34 insertions, 19 deletions
diff --git a/core/types/block.go b/core/types/block.go index 06712b1..e00465c 100644 --- a/core/types/block.go +++ b/core/types/block.go @@ -22,6 +22,7 @@ package types import ( "bytes" "fmt" + "sort" "sync" "time" @@ -47,24 +48,20 @@ func RecycleBlock(b *Block) { // NewBlock initiate a block. func NewBlock() (b *Block) { b = blockPool.Get().(*Block) - if b.Acks != nil { - for k := range b.Acks { - delete(b.Acks, k) - } - } + b.Acks = b.Acks[:0] return } // Block represents a single event broadcasted on the network. type Block struct { - ProposerID ValidatorID `json:"proposer_id"` - ParentHash common.Hash `json:"parent_hash"` - Hash common.Hash `json:"hash"` - Position Position `json:"position"` - Timestamp time.Time `json:"timestamps"` - Acks map[common.Hash]struct{} `json:"acks"` - Payload []byte `json:"payload"` - Signature crypto.Signature `json:"signature"` + ProposerID ValidatorID `json:"proposer_id"` + ParentHash common.Hash `json:"parent_hash"` + Hash common.Hash `json:"hash"` + Position Position `json:"position"` + Timestamp time.Time `json:"timestamps"` + Acks common.SortedHashes `json:"acks"` + Payload []byte `json:"payload"` + Signature crypto.Signature `json:"signature"` CRSSignature crypto.Signature `json:"crs_signature"` @@ -90,12 +87,8 @@ func (b *Block) Clone() (bcopy *Block) { bcopy.Notary.Timestamp = b.Notary.Timestamp bcopy.Notary.Height = b.Notary.Height bcopy.Timestamp = b.Timestamp - if bcopy.Acks == nil { - bcopy.Acks = make(map[common.Hash]struct{}, len(b.Acks)) - } - for k, v := range b.Acks { - bcopy.Acks[k] = v - } + bcopy.Acks = make(common.SortedHashes, len(b.Acks)) + copy(bcopy.Acks, b.Acks) bcopy.Payload = make([]byte, len(b.Payload)) copy(bcopy.Payload, b.Payload) return @@ -106,6 +99,14 @@ func (b *Block) IsGenesis() bool { return b.Position.Height == 0 && b.ParentHash == common.Hash{} } +// IsAcking checks if a block acking another by it's hash. +func (b *Block) IsAcking(hash common.Hash) bool { + idx := sort.Search(len(b.Acks), func(i int) bool { + return bytes.Compare(b.Acks[i][:], hash[:]) >= 0 + }) + return !(idx == len(b.Acks) || b.Acks[idx] != hash) +} + // ByHash is the helper type for sorting slice of blocks by hash. type ByHash []*Block diff --git a/core/types/block_test.go b/core/types/block_test.go index 4763ad1..2e6807d 100644 --- a/core/types/block_test.go +++ b/core/types/block_test.go @@ -86,6 +86,20 @@ func (s *BlockTestSuite) TestGenesisBlock() { s.False(b2.IsGenesis()) } +func (s *BlockTestSuite) TestIsAcking() { + // This test case would check if types.Block.IsAcking works + ack0 := common.NewRandomHash() + acks0 := common.Hashes{ + ack0, + common.NewRandomHash(), + common.NewRandomHash(), + } + b0 := &Block{Acks: common.NewSortedHashes(acks0)} + s.True(b0.IsAcking(ack0)) + s.False(b0.IsAcking(common.Hash{})) + s.False(b0.IsAcking(common.NewRandomHash())) +} + func TestBlock(t *testing.T) { suite.Run(t, new(BlockTestSuite)) } |