aboutsummaryrefslogtreecommitdiffstats
path: root/vendor/github.com/dexon-foundation/dexon-consensus/core/types
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/dexon-foundation/dexon-consensus/core/types')
-rw-r--r--vendor/github.com/dexon-foundation/dexon-consensus/core/types/block-randomness.go43
-rw-r--r--vendor/github.com/dexon-foundation/dexon-consensus/core/types/block.go341
-rw-r--r--vendor/github.com/dexon-foundation/dexon-consensus/core/types/config.go109
-rw-r--r--vendor/github.com/dexon-foundation/dexon-consensus/core/types/dkg/dkg.go194
-rw-r--r--vendor/github.com/dexon-foundation/dexon-consensus/core/types/node.go56
-rw-r--r--vendor/github.com/dexon-foundation/dexon-consensus/core/types/nodeset.go145
-rw-r--r--vendor/github.com/dexon-foundation/dexon-consensus/core/types/position.go74
-rw-r--r--vendor/github.com/dexon-foundation/dexon-consensus/core/types/vote.go65
8 files changed, 1027 insertions, 0 deletions
diff --git a/vendor/github.com/dexon-foundation/dexon-consensus/core/types/block-randomness.go b/vendor/github.com/dexon-foundation/dexon-consensus/core/types/block-randomness.go
new file mode 100644
index 000000000..1eaa3e398
--- /dev/null
+++ b/vendor/github.com/dexon-foundation/dexon-consensus/core/types/block-randomness.go
@@ -0,0 +1,43 @@
+// Copyright 2018 The dexon-consensus Authors
+// This file is part of the dexon-consensus library.
+//
+// The dexon-consensus library is free software: you can redistribute it
+// and/or modify it under the terms of the GNU Lesser General Public License as
+// published by the Free Software Foundation, either version 3 of the License,
+// or (at your option) any later version.
+//
+// The dexon-consensus library is distributed in the hope that it will be
+// useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
+// General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with the dexon-consensus library. If not, see
+// <http://www.gnu.org/licenses/>.
+
+package types
+
+import (
+ "fmt"
+
+ "github.com/dexon-foundation/dexon-consensus/common"
+)
+
+// AgreementResult describes an agremeent result.
+type AgreementResult struct {
+ BlockHash common.Hash `json:"block_hash"`
+ Position Position `json:"position"`
+ Votes []Vote `json:"votes"`
+}
+
+func (r *AgreementResult) String() string {
+ return fmt.Sprintf(
+ "agreementResult[%s:%s]", r.BlockHash, &r.Position)
+}
+
+// BlockRandomnessResult describes a block randomness result
+type BlockRandomnessResult struct {
+ BlockHash common.Hash `json:"block_hash"`
+ Position Position `json:"position"`
+ Randomness []byte `json:"randomness"`
+}
diff --git a/vendor/github.com/dexon-foundation/dexon-consensus/core/types/block.go b/vendor/github.com/dexon-foundation/dexon-consensus/core/types/block.go
new file mode 100644
index 000000000..bde07d518
--- /dev/null
+++ b/vendor/github.com/dexon-foundation/dexon-consensus/core/types/block.go
@@ -0,0 +1,341 @@
+// Copyright 2018 The dexon-consensus Authors
+// This file is part of the dexon-consensus library.
+//
+// The dexon-consensus library is free software: you can redistribute it
+// and/or modify it under the terms of the GNU Lesser General Public License as
+// published by the Free Software Foundation, either version 3 of the License,
+// or (at your option) any later version.
+//
+// The dexon-consensus library is distributed in the hope that it will be
+// useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
+// General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with the dexon-consensus library. If not, see
+// <http://www.gnu.org/licenses/>.
+
+// TODO(jimmy-dexon): remove comments of WitnessAck before open source.
+
+package types
+
+import (
+ "bytes"
+ "fmt"
+ "io"
+ "sort"
+ "sync"
+ "time"
+
+ "github.com/dexon-foundation/dexon/rlp"
+
+ "github.com/dexon-foundation/dexon-consensus/common"
+ "github.com/dexon-foundation/dexon-consensus/core/crypto"
+)
+
+// BlockVerifyStatus is the return code for core.Application.VerifyBlock
+type BlockVerifyStatus int
+
+// Enums for return value of core.Application.VerifyBlock.
+const (
+ // VerifyOK: Block is verified.
+ VerifyOK BlockVerifyStatus = iota
+ // VerifyRetryLater: Block is unable to be verified at this moment.
+ // Try again later.
+ VerifyRetryLater
+ // VerifyInvalidBlock: Block is an invalid one.
+ VerifyInvalidBlock
+)
+
+var (
+ // blockPool is the blocks cache to reuse allocated blocks.
+ blockPool = sync.Pool{
+ New: func() interface{} {
+ return &Block{}
+ },
+ }
+)
+
+type rlpTimestamp struct {
+ time.Time
+}
+
+func (t *rlpTimestamp) EncodeRLP(w io.Writer) error {
+ return rlp.Encode(w, uint64(t.UTC().UnixNano()))
+}
+
+func (t *rlpTimestamp) DecodeRLP(s *rlp.Stream) error {
+ var nano uint64
+ err := s.Decode(&nano)
+ if err == nil {
+ sec := int64(nano) / 1000000000
+ nsec := int64(nano) % 1000000000
+ t.Time = time.Unix(sec, nsec).UTC()
+ }
+ return err
+}
+
+// FinalizationResult represents the result of DEXON consensus algorithm.
+type FinalizationResult struct {
+ ParentHash common.Hash `json:"parent_hash"`
+ Randomness []byte `json:"randomness"`
+ Timestamp time.Time `json:"timestamp"`
+ Height uint64 `json:"height"`
+}
+
+type rlpFinalizationResult struct {
+ ParentHash common.Hash
+ Randomness []byte
+ Timestamp *rlpTimestamp
+ Height uint64
+}
+
+// EncodeRLP implements rlp.Encoder
+func (f *FinalizationResult) EncodeRLP(w io.Writer) error {
+ return rlp.Encode(w, &rlpFinalizationResult{
+ ParentHash: f.ParentHash,
+ Randomness: f.Randomness,
+ Timestamp: &rlpTimestamp{f.Timestamp},
+ Height: f.Height,
+ })
+}
+
+// DecodeRLP implements rlp.Decoder
+func (f *FinalizationResult) DecodeRLP(s *rlp.Stream) error {
+ var dec rlpFinalizationResult
+ err := s.Decode(&dec)
+ if err == nil {
+ *f = FinalizationResult{
+ ParentHash: dec.ParentHash,
+ Randomness: dec.Randomness,
+ Timestamp: dec.Timestamp.Time,
+ Height: dec.Height,
+ }
+ }
+ return err
+}
+
+// Witness represents the consensus information on the compaction chain.
+type Witness struct {
+ Height uint64 `json:"height"`
+ Data []byte `json:"data"`
+}
+
+// RecycleBlock put unused block into cache, which might be reused if
+// not garbage collected.
+func RecycleBlock(b *Block) {
+ blockPool.Put(b)
+}
+
+// NewBlock initiate a block.
+func NewBlock() (b *Block) {
+ b = blockPool.Get().(*Block)
+ b.Acks = b.Acks[:0]
+ return
+}
+
+// Block represents a single event broadcasted on the network.
+type Block struct {
+ ProposerID NodeID `json:"proposer_id"`
+ ParentHash common.Hash `json:"parent_hash"`
+ Hash common.Hash `json:"hash"`
+ Position Position `json:"position"`
+ Timestamp time.Time `json:"timestamp"`
+ Acks common.SortedHashes `json:"acks"`
+ Payload []byte `json:"payload"`
+ PayloadHash common.Hash `json:"payload_hash"`
+ Witness Witness `json:"witness"`
+ Finalization FinalizationResult `json:"finalization"`
+ Signature crypto.Signature `json:"signature"`
+
+ CRSSignature crypto.Signature `json:"crs_signature"`
+}
+
+type rlpBlock struct {
+ ProposerID NodeID
+ ParentHash common.Hash
+ Hash common.Hash
+ Position Position
+ Timestamp *rlpTimestamp
+ Acks common.SortedHashes
+ Payload []byte
+ PayloadHash common.Hash
+ Witness *Witness
+ Finalization *FinalizationResult
+ Signature crypto.Signature
+
+ CRSSignature crypto.Signature
+}
+
+// EncodeRLP implements rlp.Encoder
+func (b *Block) EncodeRLP(w io.Writer) error {
+ return rlp.Encode(w, rlpBlock{
+ ProposerID: b.ProposerID,
+ ParentHash: b.ParentHash,
+ Hash: b.Hash,
+ Position: b.Position,
+ Timestamp: &rlpTimestamp{b.Timestamp},
+ Acks: b.Acks,
+ Payload: b.Payload,
+ PayloadHash: b.PayloadHash,
+ Witness: &b.Witness,
+ Finalization: &b.Finalization,
+ Signature: b.Signature,
+ CRSSignature: b.CRSSignature,
+ })
+}
+
+// DecodeRLP implements rlp.Decoder
+func (b *Block) DecodeRLP(s *rlp.Stream) error {
+ var dec rlpBlock
+ err := s.Decode(&dec)
+ if err == nil {
+ *b = Block{
+ ProposerID: dec.ProposerID,
+ ParentHash: dec.ParentHash,
+ Hash: dec.Hash,
+ Position: dec.Position,
+ Timestamp: dec.Timestamp.Time,
+ Acks: dec.Acks,
+ Payload: dec.Payload,
+ PayloadHash: dec.PayloadHash,
+ Witness: *dec.Witness,
+ Finalization: *dec.Finalization,
+ Signature: dec.Signature,
+ CRSSignature: dec.CRSSignature,
+ }
+ }
+ return err
+}
+
+func (b *Block) String() string {
+ return fmt.Sprintf("Block(%v:%d:%d)", b.Hash.String()[:6],
+ b.Position.ChainID, b.Position.Height)
+}
+
+// Clone returns a deep copy of a block.
+func (b *Block) Clone() (bcopy *Block) {
+ bcopy = NewBlock()
+ bcopy.ProposerID = b.ProposerID
+ bcopy.ParentHash = b.ParentHash
+ bcopy.Hash = b.Hash
+ bcopy.Position.Round = b.Position.Round
+ bcopy.Position.ChainID = b.Position.ChainID
+ bcopy.Position.Height = b.Position.Height
+ bcopy.Signature = b.Signature.Clone()
+ bcopy.CRSSignature = b.CRSSignature.Clone()
+ bcopy.Finalization.ParentHash = b.Finalization.ParentHash
+ bcopy.Finalization.Timestamp = b.Finalization.Timestamp
+ bcopy.Finalization.Height = b.Finalization.Height
+ bcopy.Witness.Height = b.Witness.Height
+ bcopy.Witness.Data = make([]byte, len(b.Witness.Data))
+ copy(bcopy.Witness.Data, b.Witness.Data)
+ bcopy.Timestamp = b.Timestamp
+ 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)
+ bcopy.PayloadHash = b.PayloadHash
+ bcopy.Finalization.Randomness = make([]byte, len(b.Finalization.Randomness))
+ copy(bcopy.Finalization.Randomness, b.Finalization.Randomness)
+ return
+}
+
+// IsGenesis checks if the block is a genesisBlock
+func (b *Block) IsGenesis() bool {
+ return b.Position.Height == 0 && b.ParentHash == common.Hash{}
+}
+
+// IsFinalized checks if the finalization data is ready.
+func (b *Block) IsFinalized() bool {
+ return b.Finalization.Height != 0
+}
+
+// IsEmpty checks if the block is an 'empty block'.
+func (b *Block) IsEmpty() bool {
+ return b.ProposerID.Hash == 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
+
+func (b ByHash) Len() int {
+ return len(b)
+}
+
+func (b ByHash) Less(i int, j int) bool {
+ return bytes.Compare([]byte(b[i].Hash[:]), []byte(b[j].Hash[:])) == -1
+}
+
+func (b ByHash) Swap(i int, j int) {
+ b[i], b[j] = b[j], b[i]
+}
+
+// ByPosition is the helper type for sorting slice of blocks by position.
+type ByPosition []*Block
+
+// Len implements Len method in sort.Sort interface.
+func (bs ByPosition) Len() int {
+ return len(bs)
+}
+
+// Less implements Less method in sort.Sort interface.
+func (bs ByPosition) Less(i int, j int) bool {
+ return bs[j].Position.Newer(&bs[i].Position)
+}
+
+// Swap implements Swap method in sort.Sort interface.
+func (bs ByPosition) Swap(i int, j int) {
+ bs[i], bs[j] = bs[j], bs[i]
+}
+
+// Push implements Push method in heap interface.
+func (bs *ByPosition) Push(x interface{}) {
+ *bs = append(*bs, x.(*Block))
+}
+
+// Pop implements Pop method in heap interface.
+func (bs *ByPosition) Pop() (ret interface{}) {
+ n := len(*bs)
+ *bs, ret = (*bs)[0:n-1], (*bs)[n-1]
+ return
+}
+
+// ByFinalizationHeight is the helper type for sorting slice of blocks by
+// finalization height.
+type ByFinalizationHeight []*Block
+
+// Len implements Len method in sort.Sort interface.
+func (bs ByFinalizationHeight) Len() int {
+ return len(bs)
+}
+
+// Less implements Less method in sort.Sort interface.
+func (bs ByFinalizationHeight) Less(i int, j int) bool {
+ return bs[i].Finalization.Height < bs[j].Finalization.Height
+}
+
+// Swap implements Swap method in sort.Sort interface.
+func (bs ByFinalizationHeight) Swap(i int, j int) {
+ bs[i], bs[j] = bs[j], bs[i]
+}
+
+// Push implements Push method in heap interface.
+func (bs *ByFinalizationHeight) Push(x interface{}) {
+ *bs = append(*bs, x.(*Block))
+}
+
+// Pop implements Pop method in heap interface.
+func (bs *ByFinalizationHeight) Pop() (ret interface{}) {
+ n := len(*bs)
+ *bs, ret = (*bs)[0:n-1], (*bs)[n-1]
+ return
+}
diff --git a/vendor/github.com/dexon-foundation/dexon-consensus/core/types/config.go b/vendor/github.com/dexon-foundation/dexon-consensus/core/types/config.go
new file mode 100644
index 000000000..975eec9cb
--- /dev/null
+++ b/vendor/github.com/dexon-foundation/dexon-consensus/core/types/config.go
@@ -0,0 +1,109 @@
+// Copyright 2018 The dexon-consensus Authors
+// This file is part of the dexon-consensus library.
+//
+// The dexon-consensus library is free software: you can redistribute it
+// and/or modify it under the terms of the GNU Lesser General Public License as
+// published by the Free Software Foundation, either version 3 of the License,
+// or (at your option) any later version.
+//
+// The dexon-consensus library is distributed in the hope that it will be
+// useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
+// General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with the dexon-consensus library. If not, see
+// <http://www.gnu.org/licenses/>.
+
+package types
+
+import (
+ "encoding/binary"
+ "math"
+ "time"
+)
+
+// Config stands for Current Configuration Parameters.
+type Config struct {
+ // Network related.
+ NumChains uint32
+
+ // Lambda related.
+ LambdaBA time.Duration
+ LambdaDKG time.Duration
+
+ // Total ordering related.
+ K int
+ PhiRatio float32
+
+ // Set related.
+ NotarySetSize uint32
+ DKGSetSize uint32
+
+ // Time related.
+ RoundInterval time.Duration
+ MinBlockInterval time.Duration
+ MaxBlockInterval time.Duration
+}
+
+// Clone return a copied configuration.
+func (c *Config) Clone() *Config {
+ return &Config{
+ NumChains: c.NumChains,
+ LambdaBA: c.LambdaBA,
+ LambdaDKG: c.LambdaDKG,
+ K: c.K,
+ PhiRatio: c.PhiRatio,
+ NotarySetSize: c.NotarySetSize,
+ DKGSetSize: c.DKGSetSize,
+ RoundInterval: c.RoundInterval,
+ MinBlockInterval: c.MinBlockInterval,
+ MaxBlockInterval: c.MaxBlockInterval,
+ }
+}
+
+// Bytes returns []byte representation of Config.
+func (c *Config) Bytes() []byte {
+ binaryNumChains := make([]byte, 4)
+ binary.LittleEndian.PutUint32(binaryNumChains, c.NumChains)
+
+ binaryLambdaBA := make([]byte, 8)
+ binary.LittleEndian.PutUint64(
+ binaryLambdaBA, uint64(c.LambdaBA.Nanoseconds()))
+ binaryLambdaDKG := make([]byte, 8)
+ binary.LittleEndian.PutUint64(
+ binaryLambdaDKG, uint64(c.LambdaDKG.Nanoseconds()))
+
+ binaryK := make([]byte, 4)
+ binary.LittleEndian.PutUint32(binaryK, uint32(c.K))
+ binaryPhiRatio := make([]byte, 4)
+ binary.LittleEndian.PutUint32(binaryPhiRatio, math.Float32bits(c.PhiRatio))
+
+ binaryNotarySetSize := make([]byte, 4)
+ binary.LittleEndian.PutUint32(binaryNotarySetSize, c.NotarySetSize)
+ binaryDKGSetSize := make([]byte, 4)
+ binary.LittleEndian.PutUint32(binaryDKGSetSize, c.DKGSetSize)
+
+ binaryRoundInterval := make([]byte, 8)
+ binary.LittleEndian.PutUint64(binaryRoundInterval,
+ uint64(c.RoundInterval.Nanoseconds()))
+ binaryMinBlockInterval := make([]byte, 8)
+ binary.LittleEndian.PutUint64(binaryMinBlockInterval,
+ uint64(c.MinBlockInterval.Nanoseconds()))
+ binaryMaxBlockInterval := make([]byte, 8)
+ binary.LittleEndian.PutUint64(binaryMaxBlockInterval,
+ uint64(c.MaxBlockInterval.Nanoseconds()))
+
+ enc := make([]byte, 0, 40)
+ enc = append(enc, binaryNumChains...)
+ enc = append(enc, binaryLambdaBA...)
+ enc = append(enc, binaryLambdaDKG...)
+ enc = append(enc, binaryK...)
+ enc = append(enc, binaryPhiRatio...)
+ enc = append(enc, binaryNotarySetSize...)
+ enc = append(enc, binaryDKGSetSize...)
+ enc = append(enc, binaryRoundInterval...)
+ enc = append(enc, binaryMinBlockInterval...)
+ enc = append(enc, binaryMaxBlockInterval...)
+ return enc
+}
diff --git a/vendor/github.com/dexon-foundation/dexon-consensus/core/types/dkg/dkg.go b/vendor/github.com/dexon-foundation/dexon-consensus/core/types/dkg/dkg.go
new file mode 100644
index 000000000..4053c5a28
--- /dev/null
+++ b/vendor/github.com/dexon-foundation/dexon-consensus/core/types/dkg/dkg.go
@@ -0,0 +1,194 @@
+// Copyright 2018 The dexon-consensus Authors
+// This file is part of the dexon-consensus library.
+//
+// The dexon-consensus library is free software: you can redistribute it
+// and/or modify it under the terms of the GNU Lesser General Public License as
+// published by the Free Software Foundation, either version 3 of the License,
+// or (at your option) any later version.
+//
+// The dexon-consensus library is distributed in the hope that it will be
+// useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
+// General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with the dexon-consensus library. If not, see
+// <http://www.gnu.org/licenses/>.
+
+package dkg
+
+import (
+ "bytes"
+ "encoding/json"
+ "fmt"
+ "io"
+
+ "github.com/dexon-foundation/dexon/rlp"
+
+ "github.com/dexon-foundation/dexon-consensus/common"
+ "github.com/dexon-foundation/dexon-consensus/core/crypto"
+ cryptoDKG "github.com/dexon-foundation/dexon-consensus/core/crypto/dkg"
+ "github.com/dexon-foundation/dexon-consensus/core/types"
+)
+
+// PrivateShare describe a secret share in DKG protocol.
+type PrivateShare struct {
+ ProposerID types.NodeID `json:"proposer_id"`
+ ReceiverID types.NodeID `json:"receiver_id"`
+ Round uint64 `json:"round"`
+ PrivateShare cryptoDKG.PrivateKey `json:"private_share"`
+ Signature crypto.Signature `json:"signature"`
+}
+
+// Equal checks equality between two PrivateShare instances.
+func (p *PrivateShare) Equal(other *PrivateShare) bool {
+ return p.ProposerID.Equal(other.ProposerID) &&
+ p.ReceiverID.Equal(other.ReceiverID) &&
+ p.Round == other.Round &&
+ p.Signature.Type == other.Signature.Type &&
+ bytes.Compare(p.Signature.Signature, other.Signature.Signature) == 0 &&
+ bytes.Compare(
+ p.PrivateShare.Bytes(), other.PrivateShare.Bytes()) == 0
+}
+
+// MasterPublicKey decrtibe a master public key in DKG protocol.
+type MasterPublicKey struct {
+ ProposerID types.NodeID `json:"proposer_id"`
+ Round uint64 `json:"round"`
+ DKGID cryptoDKG.ID `json:"dkg_id"`
+ PublicKeyShares cryptoDKG.PublicKeyShares `json:"public_key_shares"`
+ Signature crypto.Signature `json:"signature"`
+}
+
+func (d *MasterPublicKey) String() string {
+ return fmt.Sprintf("MasterPublicKey[%s:%d]",
+ d.ProposerID.String()[:6],
+ d.Round)
+}
+
+// Equal check equality of two DKG master public keys.
+func (d *MasterPublicKey) Equal(other *MasterPublicKey) bool {
+ return d.ProposerID.Equal(other.ProposerID) &&
+ d.Round == other.Round &&
+ d.DKGID.GetHexString() == other.DKGID.GetHexString() &&
+ d.PublicKeyShares.Equal(&other.PublicKeyShares) &&
+ d.Signature.Type == other.Signature.Type &&
+ bytes.Compare(d.Signature.Signature, other.Signature.Signature) == 0
+}
+
+type rlpMasterPublicKey struct {
+ ProposerID types.NodeID
+ Round uint64
+ DKGID []byte
+ PublicKeyShares *cryptoDKG.PublicKeyShares
+ Signature crypto.Signature
+}
+
+// EncodeRLP implements rlp.Encoder
+func (d *MasterPublicKey) EncodeRLP(w io.Writer) error {
+ return rlp.Encode(w, rlpMasterPublicKey{
+ ProposerID: d.ProposerID,
+ Round: d.Round,
+ DKGID: d.DKGID.GetLittleEndian(),
+ PublicKeyShares: &d.PublicKeyShares,
+ Signature: d.Signature,
+ })
+}
+
+// DecodeRLP implements rlp.Decoder
+func (d *MasterPublicKey) DecodeRLP(s *rlp.Stream) error {
+ var dec rlpMasterPublicKey
+ if err := s.Decode(&dec); err != nil {
+ return err
+ }
+
+ id, err := cryptoDKG.BytesID(dec.DKGID)
+ if err != nil {
+ return err
+ }
+
+ *d = MasterPublicKey{
+ ProposerID: dec.ProposerID,
+ Round: dec.Round,
+ DKGID: id,
+ PublicKeyShares: *dec.PublicKeyShares,
+ Signature: dec.Signature,
+ }
+ return err
+}
+
+// NewMasterPublicKey returns a new MasterPublicKey instance.
+func NewMasterPublicKey() *MasterPublicKey {
+ return &MasterPublicKey{
+ PublicKeyShares: *cryptoDKG.NewEmptyPublicKeyShares(),
+ }
+}
+
+// UnmarshalJSON implements json.Unmarshaller.
+func (d *MasterPublicKey) UnmarshalJSON(data []byte) error {
+ type innertMasterPublicKey MasterPublicKey
+ d.PublicKeyShares = *cryptoDKG.NewEmptyPublicKeyShares()
+ return json.Unmarshal(data, (*innertMasterPublicKey)(d))
+}
+
+// Complaint describe a complaint in DKG protocol.
+type Complaint struct {
+ ProposerID types.NodeID `json:"proposer_id"`
+ Round uint64 `json:"round"`
+ PrivateShare PrivateShare `json:"private_share"`
+ Signature crypto.Signature `json:"signature"`
+}
+
+func (c *Complaint) String() string {
+ if c.IsNack() {
+ return fmt.Sprintf("DKGNackComplaint[%s:%d]%s",
+ c.ProposerID.String()[:6], c.Round,
+ c.PrivateShare.ProposerID.String()[:6])
+ }
+ return fmt.Sprintf("Complaint[%s:%d]%v",
+ c.ProposerID.String()[:6], c.Round, c.PrivateShare)
+}
+
+// Equal checks equality between two Complaint instances.
+func (c *Complaint) Equal(other *Complaint) bool {
+ return c.ProposerID.Equal(other.ProposerID) &&
+ c.Round == other.Round &&
+ c.PrivateShare.Equal(&other.PrivateShare) &&
+ c.Signature.Type == other.Signature.Type &&
+ bytes.Compare(c.Signature.Signature, other.Signature.Signature) == 0
+}
+
+// PartialSignature describe a partial signature in DKG protocol.
+type PartialSignature struct {
+ ProposerID types.NodeID `json:"proposer_id"`
+ Round uint64 `json:"round"`
+ Hash common.Hash `json:"hash"`
+ PartialSignature cryptoDKG.PartialSignature `json:"partial_signature"`
+ Signature crypto.Signature `json:"signature"`
+}
+
+// Finalize describe a dig finalize message in DKG protocol.
+type Finalize struct {
+ ProposerID types.NodeID `json:"proposer_id"`
+ Round uint64 `json:"round"`
+ Signature crypto.Signature `json:"signature"`
+}
+
+func (final *Finalize) String() string {
+ return fmt.Sprintf("DKGFinal[%s:%d]",
+ final.ProposerID.String()[:6],
+ final.Round)
+}
+
+// Equal check equality of two Finalize instances.
+func (final *Finalize) Equal(other *Finalize) bool {
+ return final.ProposerID.Equal(other.ProposerID) &&
+ final.Round == other.Round &&
+ final.Signature.Type == other.Signature.Type &&
+ bytes.Compare(final.Signature.Signature, other.Signature.Signature) == 0
+}
+
+// IsNack returns true if it's a nack complaint in DKG protocol.
+func (c *Complaint) IsNack() bool {
+ return len(c.PrivateShare.Signature.Signature) == 0
+}
diff --git a/vendor/github.com/dexon-foundation/dexon-consensus/core/types/node.go b/vendor/github.com/dexon-foundation/dexon-consensus/core/types/node.go
new file mode 100644
index 000000000..2c90f65c8
--- /dev/null
+++ b/vendor/github.com/dexon-foundation/dexon-consensus/core/types/node.go
@@ -0,0 +1,56 @@
+// Copyright 2018 The dexon-consensus Authors
+// This file is part of the dexon-consensus library.
+//
+// The dexon-consensus library is free software: you can redistribute it
+// and/or modify it under the terms of the GNU Lesser General Public License as
+// published by the Free Software Foundation, either version 3 of the License,
+// or (at your option) any later version.
+//
+// The dexon-consensus library is distributed in the hope that it will be
+// useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
+// General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with the dexon-consensus library. If not, see
+// <http://www.gnu.org/licenses/>.
+
+package types
+
+import (
+ "bytes"
+
+ "github.com/dexon-foundation/dexon-consensus/common"
+ "github.com/dexon-foundation/dexon-consensus/core/crypto"
+)
+
+// NodeID is the ID type for nodes.
+type NodeID struct {
+ common.Hash
+}
+
+// NewNodeID returns a NodeID with Hash set to the hash value of
+// public key.
+func NewNodeID(pubKey crypto.PublicKey) NodeID {
+ return NodeID{Hash: crypto.Keccak256Hash(pubKey.Bytes()[1:])}
+}
+
+// Equal checks if the hash representation is the same NodeID.
+func (v NodeID) Equal(v2 NodeID) bool {
+ return v.Hash == v2.Hash
+}
+
+// NodeIDs implements sort.Interface for NodeID.
+type NodeIDs []NodeID
+
+func (v NodeIDs) Len() int {
+ return len(v)
+}
+
+func (v NodeIDs) Less(i int, j int) bool {
+ return bytes.Compare([]byte(v[i].Hash[:]), []byte(v[j].Hash[:])) == -1
+}
+
+func (v NodeIDs) Swap(i int, j int) {
+ v[i], v[j] = v[j], v[i]
+}
diff --git a/vendor/github.com/dexon-foundation/dexon-consensus/core/types/nodeset.go b/vendor/github.com/dexon-foundation/dexon-consensus/core/types/nodeset.go
new file mode 100644
index 000000000..3222b3c2f
--- /dev/null
+++ b/vendor/github.com/dexon-foundation/dexon-consensus/core/types/nodeset.go
@@ -0,0 +1,145 @@
+// Copyright 2018 The dexon-consensus Authors
+// This file is part of the dexon-consensus library.
+//
+// The dexon-consensus library is free software: you can redistribute it
+// and/or modify it under the terms of the GNU Lesser General Public License as
+// published by the Free Software Foundation, either version 3 of the License,
+// or (at your option) any later version.
+//
+// The dexon-consensus library is distributed in the hope that it will be
+// useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
+// General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with the dexon-consensus library. If not, see
+// <http://www.gnu.org/licenses/>.
+
+package types
+
+import (
+ "container/heap"
+ "encoding/binary"
+ "math/big"
+
+ "github.com/dexon-foundation/dexon-consensus/common"
+ "github.com/dexon-foundation/dexon-consensus/core/crypto"
+)
+
+// NodeSet is the node set structure as defined in DEXON consensus core.
+type NodeSet struct {
+ IDs map[NodeID]struct{}
+}
+
+// SubSetTarget is the sub set target for GetSubSet().
+type SubSetTarget *big.Int
+
+type subSetTargetType byte
+
+const (
+ targetNotarySet subSetTargetType = iota
+ targetDKGSet
+)
+
+type nodeRank struct {
+ ID NodeID
+ rank *big.Int
+}
+
+// rankHeap is a MaxHeap structure.
+type rankHeap []*nodeRank
+
+func (h rankHeap) Len() int { return len(h) }
+func (h rankHeap) Less(i, j int) bool { return h[i].rank.Cmp(h[j].rank) > 0 }
+func (h rankHeap) Swap(i, j int) { h[i], h[j] = h[j], h[i] }
+func (h *rankHeap) Push(x interface{}) {
+ *h = append(*h, x.(*nodeRank))
+}
+func (h *rankHeap) Pop() interface{} {
+ old := *h
+ n := len(old)
+ x := old[n-1]
+ *h = old[0 : n-1]
+ return x
+}
+
+// NewNodeSet creates a new NodeSet instance.
+func NewNodeSet() *NodeSet {
+ return &NodeSet{
+ IDs: make(map[NodeID]struct{}),
+ }
+}
+
+// NewNotarySetTarget is the target for getting Notary Set.
+func NewNotarySetTarget(crs common.Hash, chainID uint32) SubSetTarget {
+ binaryChainID := make([]byte, 4)
+ binary.LittleEndian.PutUint32(binaryChainID, chainID)
+
+ return newTarget(targetNotarySet, crs[:], binaryChainID)
+}
+
+// NewDKGSetTarget is the target for getting DKG Set.
+func NewDKGSetTarget(crs common.Hash) SubSetTarget {
+ return newTarget(targetDKGSet, crs[:])
+}
+
+// Add a NodeID to the set.
+func (ns *NodeSet) Add(ID NodeID) {
+ ns.IDs[ID] = struct{}{}
+}
+
+// Clone the NodeSet.
+func (ns *NodeSet) Clone() *NodeSet {
+ nsCopy := NewNodeSet()
+ for ID := range ns.IDs {
+ nsCopy.Add(ID)
+ }
+ return nsCopy
+}
+
+// GetSubSet returns the subset of given target.
+func (ns *NodeSet) GetSubSet(
+ size int, target SubSetTarget) map[NodeID]struct{} {
+ h := rankHeap{}
+ idx := 0
+ for nID := range ns.IDs {
+ if idx < size {
+ h = append(h, newNodeRank(nID, target))
+ } else if idx == size {
+ heap.Init(&h)
+ }
+ if idx >= size {
+ rank := newNodeRank(nID, target)
+ if rank.rank.Cmp(h[0].rank) < 0 {
+ h[0] = rank
+ heap.Fix(&h, 0)
+ }
+ }
+ idx++
+ }
+
+ nIDs := make(map[NodeID]struct{}, size)
+ for _, rank := range h {
+ nIDs[rank.ID] = struct{}{}
+ }
+
+ return nIDs
+}
+
+func newTarget(targetType subSetTargetType, data ...[]byte) SubSetTarget {
+ data = append(data, []byte{byte(targetType)})
+ h := crypto.Keccak256Hash(data...)
+ num := big.NewInt(0)
+ num.SetBytes(h[:])
+ return SubSetTarget(num)
+}
+
+func newNodeRank(ID NodeID, target SubSetTarget) *nodeRank {
+ num := big.NewInt(0)
+ num.SetBytes(ID.Hash[:])
+ num.Abs(num.Sub((*big.Int)(target), num))
+ return &nodeRank{
+ ID: ID,
+ rank: num,
+ }
+}
diff --git a/vendor/github.com/dexon-foundation/dexon-consensus/core/types/position.go b/vendor/github.com/dexon-foundation/dexon-consensus/core/types/position.go
new file mode 100644
index 000000000..404f3035e
--- /dev/null
+++ b/vendor/github.com/dexon-foundation/dexon-consensus/core/types/position.go
@@ -0,0 +1,74 @@
+// Copyright 2018 The dexon-consensus Authors
+// This file is part of the dexon-consensus library.
+//
+// The dexon-consensus library is free software: you can redistribute it
+// and/or modify it under the terms of the GNU Lesser General Public License as
+// published by the Free Software Foundation, either version 3 of the License,
+// or (at your option) any later version.
+//
+// The dexon-consensus library is distributed in the hope that it will be
+// useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
+// General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with the dexon-consensus library. If not, see
+// <http://www.gnu.org/licenses/>.
+
+package types
+
+import (
+ "fmt"
+)
+
+// Position describes the position in the block lattice of an entity.
+type Position struct {
+ ChainID uint32 `json:"chain_id"`
+ Round uint64 `json:"round"`
+ Height uint64 `json:"height"`
+}
+
+func (pos *Position) String() string {
+ return fmt.Sprintf("pos[%d:%d:%d]", pos.Round, pos.ChainID, pos.Height)
+}
+
+// Equal checks if two positions are equal, it panics when their chainIDs
+// are different.
+func (pos *Position) Equal(other *Position) bool {
+ if pos.ChainID != other.ChainID {
+ panic(fmt.Errorf("unexpected chainID %d, should be %d",
+ other.ChainID, pos.ChainID))
+ }
+ return pos.Round == other.Round && pos.Height == other.Height
+}
+
+// Newer checks if one block is newer than another one on the same chain.
+// If two blocks on different chain compared by this function, it would panic.
+func (pos *Position) Newer(other *Position) bool {
+ if pos.ChainID != other.ChainID {
+ panic(fmt.Errorf("unexpected chainID %d, should be %d",
+ other.ChainID, pos.ChainID))
+ }
+ return pos.Round > other.Round ||
+ (pos.Round == other.Round && pos.Height > other.Height)
+}
+
+// Older checks if one block is older than another one on the same chain.
+// If two blocks on different chain compared by this function, it would panic.
+func (pos *Position) Older(other *Position) bool {
+ if pos.ChainID != other.ChainID {
+ panic(fmt.Errorf("unexpected chainID %d, should be %d",
+ other.ChainID, pos.ChainID))
+ }
+ return pos.Round < other.Round ||
+ (pos.Round == other.Round && pos.Height < other.Height)
+}
+
+// Clone a position instance.
+func (pos *Position) Clone() *Position {
+ return &Position{
+ ChainID: pos.ChainID,
+ Round: pos.Round,
+ Height: pos.Height,
+ }
+}
diff --git a/vendor/github.com/dexon-foundation/dexon-consensus/core/types/vote.go b/vendor/github.com/dexon-foundation/dexon-consensus/core/types/vote.go
new file mode 100644
index 000000000..32fb8982d
--- /dev/null
+++ b/vendor/github.com/dexon-foundation/dexon-consensus/core/types/vote.go
@@ -0,0 +1,65 @@
+// Copyright 2018 The dexon-consensus Authors
+// This file is part of the dexon-consensus library.
+//
+// The dexon-consensus library is free software: you can redistribute it
+// and/or modify it under the terms of the GNU Lesser General Public License as
+// published by the Free Software Foundation, either version 3 of the License,
+// or (at your option) any later version.
+//
+// The dexon-consensus library is distributed in the hope that it will be
+// useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
+// General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with the dexon-consensus library. If not, see
+// <http://www.gnu.org/licenses/>.
+
+package types
+
+import (
+ "fmt"
+
+ "github.com/dexon-foundation/dexon-consensus/common"
+ "github.com/dexon-foundation/dexon-consensus/core/crypto"
+)
+
+// VoteType is the type of vote.
+type VoteType byte
+
+// VoteType enum.
+const (
+ VoteInit VoteType = iota
+ VotePreCom
+ VoteCom
+ // Do not add any type below MaxVoteType.
+ MaxVoteType
+)
+
+// Vote is the vote structure defined in Crypto Shuffle Algorithm.
+type Vote struct {
+ ProposerID NodeID `json:"proposer_id"`
+ Type VoteType `json:"type"`
+ BlockHash common.Hash `json:"block_hash"`
+ Period uint64 `json:"period"`
+ Position Position `json:"position"`
+ Signature crypto.Signature `json:"signature"`
+}
+
+func (v *Vote) String() string {
+ return fmt.Sprintf("Vote[%s:%d:%d](%d:%d):%s",
+ v.ProposerID.String()[:6], v.Position.ChainID, v.Position.Height,
+ v.Period, v.Type, v.BlockHash.String()[:6])
+}
+
+// Clone returns a deep copy of a vote.
+func (v *Vote) Clone() *Vote {
+ return &Vote{
+ ProposerID: v.ProposerID,
+ Type: v.Type,
+ BlockHash: v.BlockHash,
+ Period: v.Period,
+ Position: v.Position,
+ Signature: v.Signature.Clone(),
+ }
+}