diff options
author | Wei-Ning Huang <w@dexon.org> | 2018-10-31 14:02:39 +0800 |
---|---|---|
committer | Wei-Ning Huang <w@dexon.org> | 2019-04-09 21:32:52 +0800 |
commit | 2e2bf34bc283647b206b870a01e8e2fb668c39fa (patch) | |
tree | 9fc165f5db52c3dc33dd6243ca50fd088e75a103 | |
parent | 89b4e46f7c319e48425fc0a3af810f66d6778a1e (diff) | |
download | dexon-2e2bf34bc283647b206b870a01e8e2fb668c39fa.tar.gz dexon-2e2bf34bc283647b206b870a01e8e2fb668c39fa.tar.zst dexon-2e2bf34bc283647b206b870a01e8e2fb668c39fa.zip |
vendor: sync consensus core and fix conflict
12 files changed, 177 insertions, 52 deletions
diff --git a/vendor/github.com/dexon-foundation/dexon-consensus-core/core/agreement-state.go b/vendor/github.com/dexon-foundation/dexon-consensus-core/core/agreement-state.go index 56c6c274d..77195ace1 100644 --- a/vendor/github.com/dexon-foundation/dexon-consensus-core/core/agreement-state.go +++ b/vendor/github.com/dexon-foundation/dexon-consensus-core/core/agreement-state.go @@ -19,7 +19,6 @@ package core import ( "fmt" - "math" "github.com/dexon-foundation/dexon-consensus-core/common" "github.com/dexon-foundation/dexon-consensus-core/core/types" @@ -40,6 +39,7 @@ const ( statePreCommit stateCommit stateForward + stateRepeatVote ) var nullBlockHash = common.Hash{} @@ -127,26 +127,54 @@ func (s *commitState) nextState() (agreementState, error) { } else { hash = skipBlockHash } - s.a.recv.ProposeVote(&types.Vote{ + vote := &types.Vote{ Type: types.VoteCom, BlockHash: hash, Period: s.a.period, - }) - return newForwardState(s.a), nil + } + s.a.recv.ProposeVote(vote) + return newForwardState(s.a, vote), nil } // ----- ForwardState ----- type forwardState struct { - a *agreementData + a *agreementData + vote *types.Vote } -func newForwardState(a *agreementData) *forwardState { - return &forwardState{a: a} +func newForwardState(a *agreementData, vote *types.Vote) *forwardState { + return &forwardState{ + a: a, + vote: vote, + } } func (s *forwardState) state() agreementStateType { return stateForward } -func (s *forwardState) clocks() int { return math.MaxInt32 } +func (s *forwardState) clocks() int { return 4 } func (s *forwardState) nextState() (agreementState, error) { + return newRepeatVoteState(s.a, s.vote), nil +} + +// ----- RepeatVoteState ----- +// repeateVoteState is a special state to ensure the assumption in the consensus +// algorithm that every vote will eventually arrive for all nodes. +type repeatVoteState struct { + a *agreementData + vote *types.Vote +} + +func newRepeatVoteState(a *agreementData, vote *types.Vote) *repeatVoteState { + return &repeatVoteState{ + a: a, + vote: vote, + } +} + +func (s *repeatVoteState) state() agreementStateType { return stateRepeatVote } +func (s *repeatVoteState) clocks() int { return 4 } + +func (s *repeatVoteState) nextState() (agreementState, error) { + s.a.recv.ProposeVote(s.vote) return s, nil } diff --git a/vendor/github.com/dexon-foundation/dexon-consensus-core/core/authenticator.go b/vendor/github.com/dexon-foundation/dexon-consensus-core/core/authenticator.go index f773d5292..60a4cf847 100644 --- a/vendor/github.com/dexon-foundation/dexon-consensus-core/core/authenticator.go +++ b/vendor/github.com/dexon-foundation/dexon-consensus-core/core/authenticator.go @@ -44,6 +44,7 @@ func NewAuthenticator(prvKey crypto.PrivateKey) (auth *Authenticator) { // SignBlock signs a types.Block. func (au *Authenticator) SignBlock(b *types.Block) (err error) { b.ProposerID = au.proposerID + b.PayloadHash = crypto.Keccak256Hash(b.Payload) if b.Hash, err = hashBlock(b); err != nil { return } @@ -112,6 +113,11 @@ func (au *Authenticator) SignDKGFinalize( // VerifyBlock verifies the signature of types.Block. func (au *Authenticator) VerifyBlock(b *types.Block) (err error) { + payloadHash := crypto.Keccak256Hash(b.Payload) + if payloadHash != b.PayloadHash { + err = ErrIncorrectHash + return + } hash, err := hashBlock(b) if err != nil { return diff --git a/vendor/github.com/dexon-foundation/dexon-consensus-core/core/blockpool.go b/vendor/github.com/dexon-foundation/dexon-consensus-core/core/blockpool.go index 7441cf92a..60b8f5dcd 100644 --- a/vendor/github.com/dexon-foundation/dexon-consensus-core/core/blockpool.go +++ b/vendor/github.com/dexon-foundation/dexon-consensus-core/core/blockpool.go @@ -38,7 +38,7 @@ func newBlockPool(chainNum uint32) (pool blockPool) { // resize the pool if new chain is added. func (p *blockPool) resize(num uint32) { - if uint32(len(*p)) < num { + if uint32(len(*p)) >= num { return } newPool := make([]types.ByPosition, num) diff --git a/vendor/github.com/dexon-foundation/dexon-consensus-core/core/consensus-timestamp.go b/vendor/github.com/dexon-foundation/dexon-consensus-core/core/consensus-timestamp.go index 49270d491..03a6f10d7 100644 --- a/vendor/github.com/dexon-foundation/dexon-consensus-core/core/consensus-timestamp.go +++ b/vendor/github.com/dexon-foundation/dexon-consensus-core/core/consensus-timestamp.go @@ -34,6 +34,8 @@ type consensusTimestamp struct { // dMoment represents the genesis time. dMoment time.Time + // lastTimestamp represents previous assigned consensus timestamp. + lastTimestamp time.Time } var ( @@ -42,6 +44,9 @@ var ( ErrTimestampNotIncrease = errors.New("timestamp is not increasing") // ErrNoRoundConfig for no round config found. ErrNoRoundConfig = errors.New("no round config found") + // ErrConsensusTimestampRewind would be reported if the generated timestamp + // is rewinded. + ErrConsensusTimestampRewind = errors.New("consensus timestamp rewind") ) // newConsensusTimestamp creates timestamper object. @@ -95,13 +100,13 @@ func (ct *consensusTimestamp) processBlocks(blocks []*types.Block) (err error) { if len(ct.numChainsOfRounds) < 2 { return ErrNoRoundConfig } + ct.numChainsBase++ + ct.numChainsOfRounds = ct.numChainsOfRounds[1:] if ct.numChainsOfRounds[0] > ct.numChainsOfRounds[1] { ct.resizeChainTimetamps(ct.numChainsOfRounds[0]) } else { ct.resizeChainTimetamps(ct.numChainsOfRounds[1]) } - ct.numChainsBase++ - ct.numChainsOfRounds = ct.numChainsOfRounds[1:] } else { // Error if round < base or round > base + 2. return ErrInvalidRoundID @@ -114,6 +119,11 @@ func (ct *consensusTimestamp) processBlocks(blocks []*types.Block) (err error) { return ErrTimestampNotIncrease } ct.chainTimestamps[block.Position.ChainID] = block.Timestamp + if block.Finalization.Timestamp.Before(ct.lastTimestamp) { + block.Finalization.Timestamp = ct.lastTimestamp + } else { + ct.lastTimestamp = block.Finalization.Timestamp + } } return } diff --git a/vendor/github.com/dexon-foundation/dexon-consensus-core/core/consensus.go b/vendor/github.com/dexon-foundation/dexon-consensus-core/core/consensus.go index 938337f1c..394ae36a1 100644 --- a/vendor/github.com/dexon-foundation/dexon-consensus-core/core/consensus.go +++ b/vendor/github.com/dexon-foundation/dexon-consensus-core/core/consensus.go @@ -910,6 +910,20 @@ func (con *Consensus) preProcessBlock(b *types.Block) (err error) { return } +// deliverBlock deliver a block to application layer. +func (con *Consensus) deliverBlock(b *types.Block) { + // TODO(mission): clone types.FinalizationResult + con.logger.Debug("Calling Application.BlockDelivered", "block", b) + con.app.BlockDelivered(b.Hash, b.Finalization) + if b.Position.Round+2 == con.roundToNotify { + // Only the first block delivered of that round would + // trigger this noitification. + con.gov.NotifyRoundHeight( + con.roundToNotify, b.Finalization.Height) + con.roundToNotify++ + } +} + // processBlock is the entry point to submit one block to a Consensus instance. func (con *Consensus) processBlock(block *types.Block) (err error) { if err = con.db.Put(*block); err != nil && err != blockdb.ErrBlockExists { @@ -936,8 +950,7 @@ func (con *Consensus) processBlock(block *types.Block) (err error) { panic(err) } con.cfgModule.untouchTSigHash(b.Hash) - // TODO(mission): clone types.FinalizationResult - con.app.BlockDelivered(b.Hash, b.Finalization) + con.deliverBlock(b) } if err = con.lattice.PurgeBlocks(deliveredBlocks); err != nil { return @@ -966,14 +979,7 @@ func (con *Consensus) processFinalizedBlock(block *types.Block) (err error) { } err = nil } - con.app.BlockDelivered(b.Hash, b.Finalization) - if b.Position.Round+2 == con.roundToNotify { - // Only the first block delivered of that round would - // trigger this noitification. - con.gov.NotifyRoundHeight( - con.roundToNotify, b.Finalization.Height) - con.roundToNotify++ - } + con.deliverBlock(b) } } return diff --git a/vendor/github.com/dexon-foundation/dexon-consensus-core/core/crypto.go b/vendor/github.com/dexon-foundation/dexon-consensus-core/core/crypto.go index 8eb57fcd8..52f1c9167 100644 --- a/vendor/github.com/dexon-foundation/dexon-consensus-core/core/crypto.go +++ b/vendor/github.com/dexon-foundation/dexon-consensus-core/core/crypto.go @@ -50,7 +50,6 @@ func hashBlock(block *types.Block) (common.Hash, error) { if err != nil { return common.Hash{}, err } - payloadHash := crypto.Keccak256Hash(block.Payload) hash := crypto.Keccak256Hash( block.ProposerID.Hash[:], @@ -58,7 +57,7 @@ func hashBlock(block *types.Block) (common.Hash, error) { hashPosition[:], hashAcks[:], binaryTimestamp[:], - payloadHash[:], + block.PayloadHash[:], binaryWitness[:]) return hash, nil } diff --git a/vendor/github.com/dexon-foundation/dexon-consensus-core/core/dkg-tsig-protocol.go b/vendor/github.com/dexon-foundation/dexon-consensus-core/core/dkg-tsig-protocol.go index f3a596e2b..e3fdbccf3 100644 --- a/vendor/github.com/dexon-foundation/dexon-consensus-core/core/dkg-tsig-protocol.go +++ b/vendor/github.com/dexon-foundation/dexon-consensus-core/core/dkg-tsig-protocol.go @@ -106,9 +106,25 @@ type TSigVerifier interface { VerifySignature(hash common.Hash, sig crypto.Signature) bool } +// TSigVerifierCacheInterface specifies interface used by TSigVerifierCache. +type TSigVerifierCacheInterface interface { + // Configuration returns the configuration at a given round. + // Return the genesis configuration if round == 0. + Configuration(round uint64) *types.Config + + // DKGComplaints gets all the DKGComplaints of round. + DKGComplaints(round uint64) []*typesDKG.Complaint + + // DKGMasterPublicKeys gets all the DKGMasterPublicKey of round. + DKGMasterPublicKeys(round uint64) []*typesDKG.MasterPublicKey + + // IsDKGFinal checks if DKG is final. + IsDKGFinal(round uint64) bool +} + // TSigVerifierCache is the cache for TSigVerifier. type TSigVerifierCache struct { - gov Governance + intf TSigVerifierCacheInterface verifier map[uint64]TSigVerifier minRound uint64 cacheSize int @@ -431,9 +447,10 @@ func (gpk *DKGGroupPublicKey) VerifySignature( } // NewTSigVerifierCache creats a DKGGroupPublicKey instance. -func NewTSigVerifierCache(gov Governance, cacheSize int) *TSigVerifierCache { +func NewTSigVerifierCache( + intf TSigVerifierCacheInterface, cacheSize int) *TSigVerifierCache { return &TSigVerifierCache{ - gov: gov, + intf: intf, verifier: make(map[uint64]TSigVerifier), cacheSize: cacheSize, } @@ -463,13 +480,13 @@ func (tc *TSigVerifierCache) Update(round uint64) (bool, error) { if _, exist := tc.verifier[round]; exist { return true, nil } - if !tc.gov.IsDKGFinal(round) { + if !tc.intf.IsDKGFinal(round) { return false, nil } gpk, err := NewDKGGroupPublicKey(round, - tc.gov.DKGMasterPublicKeys(round), - tc.gov.DKGComplaints(round), - int(tc.gov.Configuration(round).DKGSetSize/3)+1) + tc.intf.DKGMasterPublicKeys(round), + tc.intf.DKGComplaints(round), + int(tc.intf.Configuration(round).DKGSetSize/3)+1) if err != nil { return false, err } diff --git a/vendor/github.com/dexon-foundation/dexon-consensus-core/core/lattice-data.go b/vendor/github.com/dexon-foundation/dexon-consensus-core/core/lattice-data.go index 2a3ec299e..dd0b534b5 100644 --- a/vendor/github.com/dexon-foundation/dexon-consensus-core/core/lattice-data.go +++ b/vendor/github.com/dexon-foundation/dexon-consensus-core/core/lattice-data.go @@ -389,6 +389,10 @@ func (data *latticeData) prepareBlock(b *types.Block) error { if config = data.getConfig(b.Position.Round); config == nil { return ErrUnknownRoundID } + // When this chain is illegal in this round, reject it. + if b.Position.ChainID >= config.numChains { + return ErrInvalidChainID + } // Reset fields to make sure we got these information from parent block. b.Position.Height = 0 b.ParentHash = common.Hash{} @@ -449,9 +453,12 @@ func (data *latticeData) prepareBlock(b *types.Block) error { // The reference block is already acked. continue } - // Can't ack block too old or too new to us. - if DiffUint64( - status.tip.Position.Round, b.Position.Round) > 1 { + if status.tip.Position.Round > b.Position.Round { + // Avoid forward acking: acking some block from later rounds. + continue + } + if b.Position.Round > status.tip.Position.Round+1 { + // Can't ack block too old or too new to us. continue } acks = append(acks, status.tip.Hash) diff --git a/vendor/github.com/dexon-foundation/dexon-consensus-core/core/total-ordering.go b/vendor/github.com/dexon-foundation/dexon-consensus-core/core/total-ordering.go index ec9e643f0..480cdd4b4 100644 --- a/vendor/github.com/dexon-foundation/dexon-consensus-core/core/total-ordering.go +++ b/vendor/github.com/dexon-foundation/dexon-consensus-core/core/total-ordering.go @@ -214,6 +214,11 @@ func (cache *totalOrderingObjectCache) requestAckedStatus() ( // recycleAckedStatys recycles the structure to record acking status. func (cache *totalOrderingObjectCache) recycleAckedStatus( acked []*totalOrderingHeightRecord) { + // If the recycled objects supports lower numChains than we required, + // don't recycle it. + if uint32(len(acked)) != cache.numChains { + return + } cache.ackedStatus = append(cache.ackedStatus, acked) } @@ -231,6 +236,11 @@ func (cache *totalOrderingObjectCache) recycleWinRecord( if win == nil { return } + // If the recycled objects supports lower numChains than we required, + // don't recycle it. + if uint32(len(win.wins)) != cache.numChains { + return + } cache.winRecordPool.Put(win) } @@ -253,6 +263,11 @@ func (cache *totalOrderingObjectCache) requestHeightVector() (hv []uint64) { // recycleHeightVector recycles an instance to record acking heights // of one candidate. func (cache *totalOrderingObjectCache) recycleHeightVector(hv []uint64) { + // If the recycled objects supports lower numChains than we required, + // don't recycle it. + if uint32(len(hv)) != cache.numChains { + return + } cache.heightVectors = append(cache.heightVectors, hv) } @@ -275,6 +290,11 @@ func (cache *totalOrderingObjectCache) requestWinRecordContainer() ( // recycleWinRecordContainer recycles a map of totalOrderingWinRecord. func (cache *totalOrderingObjectCache) recycleWinRecordContainer( con []*totalOrderingWinRecord) { + // If the recycled objects supports lower numChains than we required, + // don't recycle it. + if uint32(len(con)) != cache.numChains { + return + } cache.winRecordContainers = append(cache.winRecordContainers, con) } @@ -1292,9 +1312,15 @@ func (to *totalOrdering) deliverBlocks() ( if !cfg.isValidLastBlock(b) { continue } - to.flushReadyChains[b.Position.ChainID] = struct{}{} to.flushed[b.Position.ChainID] = struct{}{} } + // Some last blocks for the round to be flushed might not be delivered + // yet. + for _, tip := range to.globalVector.tips[:cfg.numChains] { + if tip.Position.Round > to.curRound || cfg.isValidLastBlock(tip) { + to.flushReadyChains[tip.Position.ChainID] = struct{}{} + } + } } return } diff --git a/vendor/github.com/dexon-foundation/dexon-consensus-core/core/types/block.go b/vendor/github.com/dexon-foundation/dexon-consensus-core/core/types/block.go index 67226927f..008805743 100644 --- a/vendor/github.com/dexon-foundation/dexon-consensus-core/core/types/block.go +++ b/vendor/github.com/dexon-foundation/dexon-consensus-core/core/types/block.go @@ -143,6 +143,7 @@ type Block struct { 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"` @@ -158,6 +159,7 @@ type rlpBlock struct { Timestamp *rlpTimestamp Acks common.SortedHashes Payload []byte + PayloadHash common.Hash Witness *Witness Finalization *FinalizationResult Signature crypto.Signature @@ -175,6 +177,7 @@ func (b *Block) EncodeRLP(w io.Writer) error { Timestamp: &rlpTimestamp{b.Timestamp}, Acks: b.Acks, Payload: b.Payload, + PayloadHash: b.PayloadHash, Witness: &b.Witness, Finalization: &b.Finalization, Signature: b.Signature, @@ -195,6 +198,7 @@ func (b *Block) DecodeRLP(s *rlp.Stream) error { Timestamp: dec.Timestamp.Time, Acks: dec.Acks, Payload: dec.Payload, + PayloadHash: dec.PayloadHash, Witness: *dec.Witness, Finalization: *dec.Finalization, Signature: dec.Signature, @@ -231,6 +235,7 @@ func (b *Block) Clone() (bcopy *Block) { 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 diff --git a/vendor/github.com/dexon-foundation/dexon-consensus-core/core/utils.go b/vendor/github.com/dexon-foundation/dexon-consensus-core/core/utils.go index ac9567811..38e874606 100644 --- a/vendor/github.com/dexon-foundation/dexon-consensus-core/core/utils.go +++ b/vendor/github.com/dexon-foundation/dexon-consensus-core/core/utils.go @@ -131,6 +131,27 @@ func HashConfigurationBlock( ) } +// VerifyBlock verifies the signature of types.Block. +func VerifyBlock(b *types.Block) (err error) { + hash, err := hashBlock(b) + if err != nil { + return + } + if hash != b.Hash { + err = ErrIncorrectHash + return + } + pubKey, err := crypto.SigToPub(b.Hash, b.Signature) + if err != nil { + return + } + if !b.ProposerID.Equal(types.NewNodeID(pubKey)) { + err = ErrIncorrectSignature + return + } + return +} + // DiffUint64 calculates difference between two uint64. func DiffUint64(a, b uint64) uint64 { if a > b { diff --git a/vendor/vendor.json b/vendor/vendor.json index 78a3f8b60..5ceaf2838 100644 --- a/vendor/vendor.json +++ b/vendor/vendor.json @@ -105,50 +105,50 @@ { "checksumSHA1": "IKOLx0ZjJoT9x9zO/bVAXWcNXs8=", "path": "github.com/dexon-foundation/dexon-consensus-core/common", - "revision": "b64211c448f12368730356d1e36a208246a663d8", - "revisionTime": "2018-10-29T06:23:39Z" + "revision": "d7262107807dad33a8fd6219718c977748de4313", + "revisionTime": "2018-10-31T04:51:54Z" }, { - "checksumSHA1": "lq2Fwm6LM1oHq7iRUVXKwuNz5Og=", + "checksumSHA1": "sskLEXy7lUSdWbJPgU43UY+MIE0=", "path": "github.com/dexon-foundation/dexon-consensus-core/core", - "revision": "b64211c448f12368730356d1e36a208246a663d8", - "revisionTime": "2018-10-29T06:23:39Z" + "revision": "d7262107807dad33a8fd6219718c977748de4313", + "revisionTime": "2018-10-31T04:51:54Z" }, { "checksumSHA1": "69/j3ROwzhdGPWKymJnGjaJ5QzY=", "path": "github.com/dexon-foundation/dexon-consensus-core/core/blockdb", - "revision": "b64211c448f12368730356d1e36a208246a663d8", - "revisionTime": "2018-10-29T06:23:39Z" + "revision": "d7262107807dad33a8fd6219718c977748de4313", + "revisionTime": "2018-10-31T04:51:54Z" }, { "checksumSHA1": "GXHmtn3UlUftllBXI+M8RBkilzY=", "path": "github.com/dexon-foundation/dexon-consensus-core/core/crypto", - "revision": "b64211c448f12368730356d1e36a208246a663d8", - "revisionTime": "2018-10-29T06:23:39Z" + "revision": "d7262107807dad33a8fd6219718c977748de4313", + "revisionTime": "2018-10-31T04:51:54Z" }, { "checksumSHA1": "sh19Kk6G7esEcBPC2QsaFF3V/Ds=", "path": "github.com/dexon-foundation/dexon-consensus-core/core/crypto/dkg", - "revision": "b64211c448f12368730356d1e36a208246a663d8", - "revisionTime": "2018-10-29T06:23:39Z" + "revision": "d7262107807dad33a8fd6219718c977748de4313", + "revisionTime": "2018-10-31T04:51:54Z" }, { "checksumSHA1": "priVCcv7H4LTooiN/1EUu8qFiSs=", "path": "github.com/dexon-foundation/dexon-consensus-core/core/crypto/ecdsa", - "revision": "b64211c448f12368730356d1e36a208246a663d8", - "revisionTime": "2018-10-29T06:23:39Z" + "revision": "d7262107807dad33a8fd6219718c977748de4313", + "revisionTime": "2018-10-31T04:51:54Z" }, { - "checksumSHA1": "WQjNg/86ikGl9ZXli+S5ltLY78U=", + "checksumSHA1": "ZWmUF+3/pobzITsGZSOOtvK1nvs=", "path": "github.com/dexon-foundation/dexon-consensus-core/core/types", - "revision": "b64211c448f12368730356d1e36a208246a663d8", - "revisionTime": "2018-10-29T06:23:39Z" + "revision": "d7262107807dad33a8fd6219718c977748de4313", + "revisionTime": "2018-10-31T04:51:54Z" }, { "checksumSHA1": "ZOjAnqYE7HayNBTsMIgRQPLxndI=", "path": "github.com/dexon-foundation/dexon-consensus-core/core/types/dkg", - "revision": "b64211c448f12368730356d1e36a208246a663d8", - "revisionTime": "2018-10-29T06:23:39Z" + "revision": "d7262107807dad33a8fd6219718c977748de4313", + "revisionTime": "2018-10-31T04:51:54Z" }, { "checksumSHA1": "TAkwduKZqLyimyTPPWIllZWYFuE=", |