aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJimmy Hu <jimmy.hu@dexon.org>2019-05-02 21:07:49 +0800
committerJimmy Hu <jimmy.hu@dexon.org>2019-05-02 21:35:46 +0800
commitc361083f3f04c2a4e9b50bd2f8fb963e2985ab1d (patch)
tree40b129b57bc7cd3de8659238550d369afe64a5ad
parent528b0252cdf359b5c3bd0dd22c96641c06eb5659 (diff)
downloaddexon-testnet.tar.gz
dexon-testnet.tar.zst
dexon-testnet.zip
vendor: sync to latest coretestnet
-rw-r--r--vendor/github.com/dexon-foundation/dexon-consensus/core/agreement-mgr.go70
-rw-r--r--vendor/github.com/dexon-foundation/dexon-consensus/core/agreement.go47
-rw-r--r--vendor/github.com/dexon-foundation/dexon-consensus/core/blockchain.go7
-rw-r--r--vendor/github.com/dexon-foundation/dexon-consensus/core/consensus.go20
-rw-r--r--vendor/github.com/dexon-foundation/dexon-consensus/core/dkg-tsig-protocol.go7
-rw-r--r--vendor/github.com/dexon-foundation/dexon-consensus/core/syncer/agreement.go14
-rw-r--r--vendor/github.com/dexon-foundation/dexon-consensus/core/utils.go6
-rw-r--r--vendor/github.com/dexon-foundation/dexon-consensus/core/utils/vote-filter.go6
-rw-r--r--vendor/vendor.json90
9 files changed, 169 insertions, 98 deletions
diff --git a/vendor/github.com/dexon-foundation/dexon-consensus/core/agreement-mgr.go b/vendor/github.com/dexon-foundation/dexon-consensus/core/agreement-mgr.go
index af0adf259..ab4840acc 100644
--- a/vendor/github.com/dexon-foundation/dexon-consensus/core/agreement-mgr.go
+++ b/vendor/github.com/dexon-foundation/dexon-consensus/core/agreement-mgr.go
@@ -24,6 +24,8 @@ import (
"sync"
"time"
+ lru "github.com/hashicorp/golang-lru"
+
"github.com/dexon-foundation/dexon-consensus/common"
"github.com/dexon-foundation/dexon-consensus/core/types"
typesDKG "github.com/dexon-foundation/dexon-consensus/core/types/dkg"
@@ -39,6 +41,7 @@ var (
)
const maxResultCache = 100
+const settingLimit = 3
// genValidLeader generate a validLeader function for agreement modules.
func genValidLeader(
@@ -114,12 +117,15 @@ type agreementMgr struct {
recv *consensusBAReceiver
processedBAResult map[types.Position]struct{}
voteFilter *utils.VoteFilter
+ settingCache *lru.Cache
+ curRoundSetting *baRoundSetting
waitGroup sync.WaitGroup
isRunning bool
lock sync.RWMutex
}
func newAgreementMgr(con *Consensus) (mgr *agreementMgr, err error) {
+ settingCache, _ := lru.New(settingLimit)
mgr = &agreementMgr{
con: con,
ID: con.ID,
@@ -133,6 +139,7 @@ func newAgreementMgr(con *Consensus) (mgr *agreementMgr, err error) {
ctx: con.ctx,
processedBAResult: make(map[types.Position]struct{}, maxResultCache),
voteFilter: utils.NewVoteFilter(),
+ settingCache: settingCache,
}
mgr.recv = &consensusBAReceiver{
consensus: con,
@@ -149,21 +156,18 @@ func (mgr *agreementMgr) prepare() {
newLeaderSelector(genValidLeader(mgr), mgr.logger),
mgr.signer,
mgr.logger)
- nodes, err := mgr.cache.GetNodeSet(round)
- if err != nil {
+ setting := mgr.generateSetting(round)
+ if setting == nil {
+ mgr.logger.Warn("Unable to prepare init setting", "round", round)
return
}
- agr.notarySet = nodes.GetSubSet(
- int(mgr.config(round).notarySetSize),
- types.NewNotarySetTarget(mgr.config(round).crs))
+ mgr.curRoundSetting = setting
+ agr.notarySet = mgr.curRoundSetting.dkgSet
// Hacky way to make agreement module self contained.
mgr.recv.agreementModule = agr
mgr.baModule = agr
if round >= DKGDelayRound {
- setting := mgr.generateSetting(round)
- if setting == nil {
- mgr.logger.Warn("Unable to prepare init setting", "round", round)
- } else if _, exist := setting.dkgSet[mgr.ID]; exist {
+ if _, exist := setting.dkgSet[mgr.ID]; exist {
mgr.logger.Debug("Preparing signer and npks.", "round", round)
npk, signer, err := mgr.con.cfgModule.getDKGInfo(round, false)
if err != nil {
@@ -251,10 +255,34 @@ func (mgr *agreementMgr) notifyRoundEvents(evts []utils.RoundEventParam) error {
return nil
}
+func (mgr *agreementMgr) checkProposer(
+ round uint64, proposerID types.NodeID) error {
+ if round == mgr.curRoundSetting.round {
+ if _, exist := mgr.curRoundSetting.dkgSet[proposerID]; !exist {
+ return ErrNotInNotarySet
+ }
+ } else if round == mgr.curRoundSetting.round+1 {
+ setting := mgr.generateSetting(round)
+ if setting == nil {
+ return ErrConfigurationNotReady
+ }
+ if _, exist := setting.dkgSet[proposerID]; !exist {
+ return ErrNotInNotarySet
+ }
+ }
+ return nil
+}
+
func (mgr *agreementMgr) processVote(v *types.Vote) (err error) {
+ if !mgr.recv.isNotary {
+ return nil
+ }
if mgr.voteFilter.Filter(v) {
return nil
}
+ if err := mgr.checkProposer(v.Position.Round, v.ProposerID); err != nil {
+ return err
+ }
if err = mgr.baModule.processVote(v); err == nil {
mgr.baModule.updateFilter(mgr.voteFilter)
mgr.voteFilter.AddVote(v)
@@ -263,6 +291,9 @@ func (mgr *agreementMgr) processVote(v *types.Vote) (err error) {
}
func (mgr *agreementMgr) processBlock(b *types.Block) error {
+ if err := mgr.checkProposer(b.Position.Round, b.ProposerID); err != nil {
+ return err
+ }
return mgr.baModule.processBlock(b)
}
@@ -323,6 +354,7 @@ func (mgr *agreementMgr) processAgreementResult(
result.Position.Round)
return ErrConfigurationNotReady
}
+ mgr.curRoundSetting = setting
leader, err := mgr.calcLeader(setting.dkgSet, setting.crs, result.Position)
if err != nil {
return err
@@ -358,6 +390,9 @@ func (mgr *agreementMgr) stop() {
}
func (mgr *agreementMgr) generateSetting(round uint64) *baRoundSetting {
+ if setting, exist := mgr.settingCache.Get(round); exist {
+ return setting.(*baRoundSetting)
+ }
curConfig := mgr.config(round)
if curConfig == nil {
return nil
@@ -383,13 +418,15 @@ func (mgr *agreementMgr) generateSetting(round uint64) *baRoundSetting {
return nil
}
}
- return &baRoundSetting{
+ setting := &baRoundSetting{
crs: curConfig.crs,
dkgSet: dkgSet,
round: round,
threshold: utils.GetBAThreshold(&types.Config{
NotarySetSize: curConfig.notarySetSize}),
}
+ mgr.settingCache.Add(round, setting)
+ return setting
}
func (mgr *agreementMgr) runBA(initRound uint64) {
@@ -449,6 +486,7 @@ Loop:
}
mgr.recv.isNotary = checkRound()
mgr.voteFilter = utils.NewVoteFilter()
+ mgr.voteFilter.Position.Round = currentRound
mgr.recv.emptyBlockHashMap = &sync.Map{}
if currentRound >= DKGDelayRound && mgr.recv.isNotary {
var err error
@@ -521,11 +559,13 @@ func (mgr *agreementMgr) baRoutineForOneRound(
default:
}
nextHeight, nextTime = mgr.bcModule.nextBlock()
- if isStop(restartPos) {
- break
- }
- if nextHeight > restartPos.Height {
- break
+ if nextHeight != notReadyHeight {
+ if isStop(restartPos) {
+ break
+ }
+ if nextHeight > restartPos.Height {
+ break
+ }
}
mgr.logger.Debug("BlockChain not ready!!!",
"old", oldPos, "restart", restartPos, "next", nextHeight)
diff --git a/vendor/github.com/dexon-foundation/dexon-consensus/core/agreement.go b/vendor/github.com/dexon-foundation/dexon-consensus/core/agreement.go
index b122a4ddf..a2cac11f4 100644
--- a/vendor/github.com/dexon-foundation/dexon-consensus/core/agreement.go
+++ b/vendor/github.com/dexon-foundation/dexon-consensus/core/agreement.go
@@ -361,9 +361,6 @@ func (a *agreement) sanityCheck(vote *types.Vote) error {
if vote.Type >= types.MaxVoteType {
return ErrInvalidVote
}
- if _, exist := a.notarySet[vote.ProposerID]; !exist {
- return ErrNotInNotarySet
- }
ok, err := utils.VerifyVoteSignature(vote)
if err != nil {
return err
@@ -371,6 +368,10 @@ func (a *agreement) sanityCheck(vote *types.Vote) error {
if !ok {
return ErrIncorrectVoteSignature
}
+ if vote.Position.Round != a.agreementID().Round {
+ // TODO(jimmy): maybe we can verify partial signature at agreement-mgr.
+ return nil
+ }
if !a.data.recv.VerifyPartialSignature(vote) {
return ErrIncorrectVotePartialSignature
}
@@ -412,7 +413,7 @@ func (a *agreement) updateFilter(filter *utils.VoteFilter) {
filter.Confirm = a.hasOutput
filter.LockIter = a.data.lockIter
filter.Period = a.data.period
- filter.Height = a.agreementID().Height
+ filter.Position.Height = a.agreementID().Height
}
// processVote is the entry point for processing Vote.
@@ -426,14 +427,15 @@ func (a *agreement) processVote(vote *types.Vote) error {
// Agreement module has stopped.
if isStop(aID) {
- // Hacky way to not drop first votes for genesis height.
- if vote.Position.Height == types.GenesisHeight {
+ // Hacky way to not drop first votes when round just begins.
+ if vote.Position.Round == aID.Round {
a.pendingVote = append(a.pendingVote, pendingVote{
vote: vote,
receivedTime: time.Now().UTC(),
})
+ return nil
}
- return nil
+ return ErrSkipButNoError
}
if vote.Position != aID {
if aID.Newer(vote.Position) {
@@ -636,19 +638,34 @@ func (a *agreement) confirmedNoLock() bool {
// processBlock is the entry point for processing Block.
func (a *agreement) processBlock(block *types.Block) error {
+ checkSkip := func() bool {
+ aID := a.agreementID()
+ if block.Position != aID {
+ // Agreement module has stopped.
+ if !isStop(aID) {
+ if aID.Newer(block.Position) {
+ return true
+ }
+ }
+ }
+ return false
+ }
+ if checkSkip() {
+ return nil
+ }
+ if err := utils.VerifyBlockSignature(block); err != nil {
+ return err
+ }
+
a.lock.Lock()
defer a.lock.Unlock()
a.data.blocksLock.Lock()
defer a.data.blocksLock.Unlock()
-
aID := a.agreementID()
- if block.Position != aID {
- // Agreement module has stopped.
- if !isStop(aID) {
- if aID.Newer(block.Position) {
- return nil
- }
- }
+ // a.agreementID might change during lock, so we need to checkSkip again.
+ if checkSkip() {
+ return nil
+ } else if aID != block.Position {
a.pendingBlock = append(a.pendingBlock, pendingBlock{
block: block,
receivedTime: time.Now().UTC(),
diff --git a/vendor/github.com/dexon-foundation/dexon-consensus/core/blockchain.go b/vendor/github.com/dexon-foundation/dexon-consensus/core/blockchain.go
index 9fbb86162..335e75cca 100644
--- a/vendor/github.com/dexon-foundation/dexon-consensus/core/blockchain.go
+++ b/vendor/github.com/dexon-foundation/dexon-consensus/core/blockchain.go
@@ -21,6 +21,7 @@ import (
"bytes"
"errors"
"fmt"
+ "math"
"sort"
"sync"
"time"
@@ -49,6 +50,8 @@ var (
ErrMissingRandomness = errors.New("missing block randomness")
)
+const notReadyHeight uint64 = math.MaxUint64
+
type pendingBlockRecord struct {
position types.Position
block *types.Block
@@ -387,6 +390,10 @@ func (bc *blockChain) nextBlock() (uint64, time.Time) {
if tip == nil {
return types.GenesisHeight, bc.dMoment
}
+ if tip != bc.lastDelivered {
+ // If tip is not delivered, we should not proceed to next block.
+ return notReadyHeight, time.Time{}
+ }
return tip.Position.Height + 1, tip.Timestamp.Add(config.minBlockInterval)
}
diff --git a/vendor/github.com/dexon-foundation/dexon-consensus/core/consensus.go b/vendor/github.com/dexon-foundation/dexon-consensus/core/consensus.go
index 966c70aaa..b5baace86 100644
--- a/vendor/github.com/dexon-foundation/dexon-consensus/core/consensus.go
+++ b/vendor/github.com/dexon-foundation/dexon-consensus/core/consensus.go
@@ -93,13 +93,23 @@ func (recv *consensusBAReceiver) VerifyPartialSignature(vote *types.Vote) bool {
if vote.Position.Round >= DKGDelayRound && vote.BlockHash != types.SkipBlockHash {
if vote.Type == types.VoteCom || vote.Type == types.VoteFastCom {
if recv.npks == nil {
+ recv.consensus.logger.Debug(
+ "Unable to verify psig, npks is nil",
+ "vote", vote)
return false
}
if vote.Position.Round != recv.npks.Round {
+ recv.consensus.logger.Debug(
+ "Unable to verify psig, round of npks mismatch",
+ "vote", vote,
+ "npksRound", recv.npks.Round)
return false
}
pubKey, exist := recv.npks.PublicKeys[vote.ProposerID]
if !exist {
+ recv.consensus.logger.Debug(
+ "Unable to verify psig, proposer is not qualified",
+ "vote", vote)
return false
}
blockHash := vote.BlockHash
@@ -1114,6 +1124,10 @@ func (con *Consensus) generateBlockRandomness(blocks []*types.Block) {
"block", block,
"result", result)
con.network.BroadcastAgreementResult(result)
+ if err := con.deliverFinalizedBlocks(); err != nil {
+ con.logger.Error("Failed to deliver finalized block",
+ "error", err)
+ }
}
}(block)
}
@@ -1354,11 +1368,7 @@ func (con *Consensus) ProcessAgreementResult(
return nil
}
// Sanity Check.
- notarySet, err := con.nodeSetCache.GetNotarySet(rand.Position.Round)
- if err != nil {
- return err
- }
- if err := VerifyAgreementResult(rand, notarySet); err != nil {
+ if err := VerifyAgreementResult(rand, con.nodeSetCache); err != nil {
con.baMgr.untouchAgreementResult(rand)
return err
}
diff --git a/vendor/github.com/dexon-foundation/dexon-consensus/core/dkg-tsig-protocol.go b/vendor/github.com/dexon-foundation/dexon-consensus/core/dkg-tsig-protocol.go
index 0612bda4b..d81d485c3 100644
--- a/vendor/github.com/dexon-foundation/dexon-consensus/core/dkg-tsig-protocol.go
+++ b/vendor/github.com/dexon-foundation/dexon-consensus/core/dkg-tsig-protocol.go
@@ -487,10 +487,13 @@ func (d *dkgProtocol) processPrivateShare(
if _, exist := d.antiComplaintReceived[prvShare.ReceiverID]; !exist {
d.antiComplaintReceived[prvShare.ReceiverID] =
make(map[types.NodeID]struct{})
+ }
+ if _, exist :=
+ d.antiComplaintReceived[prvShare.ReceiverID][prvShare.ProposerID]; !exist {
d.recv.ProposeDKGAntiNackComplaint(prvShare)
+ d.antiComplaintReceived[prvShare.ReceiverID][prvShare.ProposerID] =
+ struct{}{}
}
- d.antiComplaintReceived[prvShare.ReceiverID][prvShare.ProposerID] =
- struct{}{}
}
return nil
}
diff --git a/vendor/github.com/dexon-foundation/dexon-consensus/core/syncer/agreement.go b/vendor/github.com/dexon-foundation/dexon-consensus/core/syncer/agreement.go
index b414e1146..d39c24627 100644
--- a/vendor/github.com/dexon-foundation/dexon-consensus/core/syncer/agreement.go
+++ b/vendor/github.com/dexon-foundation/dexon-consensus/core/syncer/agreement.go
@@ -176,12 +176,7 @@ func (a *agreement) processAgreementResult(r *types.AgreementResult) {
a.logger.Trace("Agreement result cached", "result", r)
return
}
- notarySet, err := a.cache.GetNotarySet(r.Position.Round)
- if err != nil {
- a.logger.Error("unable to get notary set", "result", r, "error", err)
- return
- }
- if err := core.VerifyAgreementResult(r, notarySet); err != nil {
+ if err := core.VerifyAgreementResult(r, a.cache); err != nil {
a.logger.Error("Agreement result verification failed",
"result", r,
"error", err)
@@ -257,18 +252,13 @@ func (a *agreement) processNewCRS(round uint64) {
a.latestCRSRound = round
// Verify all pending results.
for r := prevRound; r <= a.latestCRSRound; r++ {
- notarySet, err := a.cache.GetNotarySet(r)
- if err != nil {
- a.logger.Error("Unable to get notary set", "round", r, "error", err)
- continue
- }
pendingsForRound := a.pendingAgrs[r]
if pendingsForRound == nil {
continue
}
delete(a.pendingAgrs, r)
for _, res := range pendingsForRound {
- if err := core.VerifyAgreementResult(res, notarySet); err != nil {
+ if err := core.VerifyAgreementResult(res, a.cache); err != nil {
a.logger.Error("Invalid agreement result",
"result", res,
"error", err)
diff --git a/vendor/github.com/dexon-foundation/dexon-consensus/core/utils.go b/vendor/github.com/dexon-foundation/dexon-consensus/core/utils.go
index c9d5f840f..c4d7b0fc3 100644
--- a/vendor/github.com/dexon-foundation/dexon-consensus/core/utils.go
+++ b/vendor/github.com/dexon-foundation/dexon-consensus/core/utils.go
@@ -158,13 +158,17 @@ func HashConfigurationBlock(
// VerifyAgreementResult perform sanity check against a types.AgreementResult
// instance.
func VerifyAgreementResult(
- res *types.AgreementResult, notarySet map[types.NodeID]struct{}) error {
+ res *types.AgreementResult, cache *NodeSetCache) error {
if res.Position.Round >= DKGDelayRound {
if len(res.Randomness) == 0 {
return ErrMissingRandomness
}
return nil
}
+ notarySet, err := cache.GetNotarySet(res.Position.Round)
+ if err != nil {
+ return err
+ }
if len(res.Votes) < len(notarySet)*2/3+1 {
return ErrNotEnoughVotes
}
diff --git a/vendor/github.com/dexon-foundation/dexon-consensus/core/utils/vote-filter.go b/vendor/github.com/dexon-foundation/dexon-consensus/core/utils/vote-filter.go
index 2fc18bb34..446d88a64 100644
--- a/vendor/github.com/dexon-foundation/dexon-consensus/core/utils/vote-filter.go
+++ b/vendor/github.com/dexon-foundation/dexon-consensus/core/utils/vote-filter.go
@@ -25,7 +25,7 @@ import (
// To maximize performance, this structure is not thread-safe and will never be.
type VoteFilter struct {
Voted map[types.VoteHeader]struct{}
- Height uint64
+ Position types.Position
LockIter uint64
Period uint64
Confirm bool
@@ -43,9 +43,9 @@ func (vf *VoteFilter) Filter(vote *types.Vote) bool {
if vote.Type == types.VoteInit {
return true
}
- if vote.Position.Height < vf.Height {
+ if vote.Position.Older(vf.Position) {
return true
- } else if vote.Position.Height > vf.Height {
+ } else if vote.Position.Newer(vf.Position) {
// It's impossible to check the vote of other height.
return false
}
diff --git a/vendor/vendor.json b/vendor/vendor.json
index 85bda6aa5..6c6c9f6a8 100644
--- a/vendor/vendor.json
+++ b/vendor/vendor.json
@@ -141,90 +141,90 @@
{
"checksumSHA1": "In6vBHYUsX7DUIGiFN2hQggBgvI=",
"path": "github.com/dexon-foundation/dexon-consensus/common",
- "revision": "b9492bc09f8bb53b2a36e505ddad0d26373e71a3",
- "revisionTime": "2019-04-10T01:52:20Z",
- "version": "single-chain",
- "versionExact": "single-chain"
+ "revision": "1edd55a2ff91bbbe94b8c1e8564ea2e5a45cf37c",
+ "revisionTime": "2019-05-02T12:35:18Z",
+ "version": "testnet",
+ "versionExact": "testnet"
},
{
- "checksumSHA1": "lY1KAGWRuwd7OpzAz5yN7IysMvU=",
+ "checksumSHA1": "cpz6BH7Hn3SWM/vdKqLmn5T2mZc=",
"path": "github.com/dexon-foundation/dexon-consensus/core",
- "revision": "b9492bc09f8bb53b2a36e505ddad0d26373e71a3",
- "revisionTime": "2019-04-10T01:52:20Z",
- "version": "single-chain",
- "versionExact": "single-chain"
+ "revision": "1edd55a2ff91bbbe94b8c1e8564ea2e5a45cf37c",
+ "revisionTime": "2019-05-02T12:35:18Z",
+ "version": "testnet",
+ "versionExact": "testnet"
},
{
"checksumSHA1": "v4fKR7uhoyufi6hAVO44cFEb+tY=",
"path": "github.com/dexon-foundation/dexon-consensus/core/blockdb",
"revision": "56e872f84131348adbc0861afb3554bba4a8e5db",
"revisionTime": "2018-12-05T06:29:54Z",
- "version": "single-chain",
- "versionExact": "single-chain"
+ "version": "testnet",
+ "versionExact": "testnet"
},
{
"checksumSHA1": "tQSbYCu5P00lUhKsx3IbBZCuSLY=",
"path": "github.com/dexon-foundation/dexon-consensus/core/crypto",
- "revision": "b9492bc09f8bb53b2a36e505ddad0d26373e71a3",
- "revisionTime": "2019-04-10T01:52:20Z",
- "version": "single-chain",
- "versionExact": "single-chain"
+ "revision": "1edd55a2ff91bbbe94b8c1e8564ea2e5a45cf37c",
+ "revisionTime": "2019-05-02T12:35:18Z",
+ "version": "testnet",
+ "versionExact": "testnet"
},
{
"checksumSHA1": "m5lUT04qSHKtFukvxjnFX5Jo2hI=",
"path": "github.com/dexon-foundation/dexon-consensus/core/crypto/dkg",
- "revision": "b9492bc09f8bb53b2a36e505ddad0d26373e71a3",
- "revisionTime": "2019-04-10T01:52:20Z",
- "version": "single-chain",
- "versionExact": "single-chain"
+ "revision": "1edd55a2ff91bbbe94b8c1e8564ea2e5a45cf37c",
+ "revisionTime": "2019-05-02T12:35:18Z",
+ "version": "testnet",
+ "versionExact": "testnet"
},
{
"checksumSHA1": "BhLKK8RveoLaeXc9UyUKMwQqchU=",
"path": "github.com/dexon-foundation/dexon-consensus/core/crypto/ecdsa",
- "revision": "b9492bc09f8bb53b2a36e505ddad0d26373e71a3",
- "revisionTime": "2019-04-10T01:52:20Z",
- "version": "single-chain",
- "versionExact": "single-chain"
+ "revision": "1edd55a2ff91bbbe94b8c1e8564ea2e5a45cf37c",
+ "revisionTime": "2019-05-02T12:35:18Z",
+ "version": "testnet",
+ "versionExact": "testnet"
},
{
"checksumSHA1": "hj/KetWUHp+1CX+50V0QnCthfWc=",
"path": "github.com/dexon-foundation/dexon-consensus/core/db",
- "revision": "b9492bc09f8bb53b2a36e505ddad0d26373e71a3",
- "revisionTime": "2019-04-10T01:52:20Z",
- "version": "single-chain",
- "versionExact": "single-chain"
+ "revision": "1edd55a2ff91bbbe94b8c1e8564ea2e5a45cf37c",
+ "revisionTime": "2019-05-02T12:35:18Z",
+ "version": "testnet",
+ "versionExact": "testnet"
},
{
- "checksumSHA1": "/OcEQKdtWDyRZibazIsAxJWHUyg=",
+ "checksumSHA1": "eMoqaQX9T9oO67QM2KHsVVulohA=",
"path": "github.com/dexon-foundation/dexon-consensus/core/syncer",
- "revision": "b9492bc09f8bb53b2a36e505ddad0d26373e71a3",
- "revisionTime": "2019-04-10T01:52:20Z",
- "version": "single-chain",
- "versionExact": "single-chain"
+ "revision": "1edd55a2ff91bbbe94b8c1e8564ea2e5a45cf37c",
+ "revisionTime": "2019-05-02T12:35:18Z",
+ "version": "testnet",
+ "versionExact": "testnet"
},
{
"checksumSHA1": "zIgCdN4FJiAuPGMhB+/9YGK/Wgk=",
"path": "github.com/dexon-foundation/dexon-consensus/core/types",
- "revision": "b9492bc09f8bb53b2a36e505ddad0d26373e71a3",
- "revisionTime": "2019-04-10T01:52:20Z",
- "version": "single-chain",
- "versionExact": "single-chain"
+ "revision": "1edd55a2ff91bbbe94b8c1e8564ea2e5a45cf37c",
+ "revisionTime": "2019-05-02T12:35:18Z",
+ "version": "testnet",
+ "versionExact": "testnet"
},
{
"checksumSHA1": "lbG7yqVgzo2CV/CQPYjG78xp5jg=",
"path": "github.com/dexon-foundation/dexon-consensus/core/types/dkg",
- "revision": "b9492bc09f8bb53b2a36e505ddad0d26373e71a3",
- "revisionTime": "2019-04-10T01:52:20Z",
- "version": "single-chain",
- "versionExact": "single-chain"
+ "revision": "1edd55a2ff91bbbe94b8c1e8564ea2e5a45cf37c",
+ "revisionTime": "2019-05-02T12:35:18Z",
+ "version": "testnet",
+ "versionExact": "testnet"
},
{
- "checksumSHA1": "1VsJIshz0loXnGwCtrMM8SuIo6Y=",
+ "checksumSHA1": "9O5eHd40xQTizw3wt9JQfUtxw80=",
"path": "github.com/dexon-foundation/dexon-consensus/core/utils",
- "revision": "b9492bc09f8bb53b2a36e505ddad0d26373e71a3",
- "revisionTime": "2019-04-10T01:52:20Z",
- "version": "single-chain",
- "versionExact": "single-chain"
+ "revision": "1edd55a2ff91bbbe94b8c1e8564ea2e5a45cf37c",
+ "revisionTime": "2019-05-02T12:35:18Z",
+ "version": "testnet",
+ "versionExact": "testnet"
},
{
"checksumSHA1": "TAkwduKZqLyimyTPPWIllZWYFuE=",