aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWei-Ning Huang <w@dexon.org>2019-01-04 23:59:17 +0800
committerWei-Ning Huang <w@byzantine-lab.io>2019-06-12 17:27:21 +0800
commitf2865a49b3a18f7d02886a831a14d99033bf43ae (patch)
treed6f3d8fab446222fe3d5f4d3bea557a9f279ee30
parent30950e88c8c96b583b34da0a8ec1e2b44b4e1b0b (diff)
downloadgo-tangerine-f2865a49b3a18f7d02886a831a14d99033bf43ae.tar.gz
go-tangerine-f2865a49b3a18f7d02886a831a14d99033bf43ae.tar.zst
go-tangerine-f2865a49b3a18f7d02886a831a14d99033bf43ae.zip
vendor: sync to latest core (#129)
-rw-r--r--dex/governance.go9
-rw-r--r--vendor/github.com/dexon-foundation/dexon-consensus/common/logger.go15
-rw-r--r--vendor/github.com/dexon-foundation/dexon-consensus/core/blockpool.go4
-rw-r--r--vendor/github.com/dexon-foundation/dexon-consensus/core/configuration-chain.go1
-rw-r--r--vendor/github.com/dexon-foundation/dexon-consensus/core/consensus.go7
-rw-r--r--vendor/github.com/dexon-foundation/dexon-consensus/core/interfaces.go6
-rw-r--r--vendor/github.com/dexon-foundation/dexon-consensus/core/syncer/agreement.go11
-rw-r--r--vendor/github.com/dexon-foundation/dexon-consensus/core/syncer/consensus.go19
-rw-r--r--vendor/github.com/dexon-foundation/dexon-consensus/core/types/block.go25
-rw-r--r--vendor/github.com/dexon-foundation/dexon-consensus/core/utils/crypto.go5
-rw-r--r--vendor/github.com/dexon-foundation/dexon-consensus/core/utils/signer.go2
-rw-r--r--vendor/github.com/dexon-foundation/dexon-consensus/core/utils/utils.go16
-rw-r--r--vendor/vendor.json74
13 files changed, 104 insertions, 90 deletions
diff --git a/dex/governance.go b/dex/governance.go
index bcc2cca51..199bcdc87 100644
--- a/dex/governance.go
+++ b/dex/governance.go
@@ -27,6 +27,7 @@ import (
dexCore "github.com/dexon-foundation/dexon-consensus/core"
coreCrypto "github.com/dexon-foundation/dexon-consensus/core/crypto"
coreEcdsa "github.com/dexon-foundation/dexon-consensus/core/crypto/ecdsa"
+ coreTypes "github.com/dexon-foundation/dexon-consensus/core/types"
dkgTypes "github.com/dexon-foundation/dexon-consensus/core/types/dkg"
"github.com/dexon-foundation/dexon/common"
@@ -291,3 +292,11 @@ func (d *DexconGovernance) DKGSet(round uint64) (map[string]struct{}, error) {
}
return r, nil
}
+
+func (d *DexconGovernance) ReportForkVote(vote1, vote2 *coreTypes.Vote) {
+ // TODO: finish this.
+}
+
+func (d *DexconGovernance) ReportForkBlock(block1, block2 *coreTypes.Block) {
+ // TODO: finish this.
+}
diff --git a/vendor/github.com/dexon-foundation/dexon-consensus/common/logger.go b/vendor/github.com/dexon-foundation/dexon-consensus/common/logger.go
index 29eac3595..3328e939a 100644
--- a/vendor/github.com/dexon-foundation/dexon-consensus/common/logger.go
+++ b/vendor/github.com/dexon-foundation/dexon-consensus/common/logger.go
@@ -29,6 +29,7 @@ import "log"
// })
type Logger interface {
// Info logs info level logs.
+ Trace(msg string, ctx ...interface{})
Debug(msg string, ctx ...interface{})
Info(msg string, ctx ...interface{})
Warn(msg string, ctx ...interface{})
@@ -38,6 +39,10 @@ type Logger interface {
// NullLogger logs nothing.
type NullLogger struct{}
+// Trace implements Logger interface.
+func (logger *NullLogger) Trace(msg string, ctx ...interface{}) {
+}
+
// Debug implements Logger interface.
func (logger *NullLogger) Debug(msg string, ctx ...interface{}) {
}
@@ -66,6 +71,11 @@ func composeVargs(msg string, ctxs []interface{}) []interface{} {
return args
}
+// Trace implements Logger interface.
+func (logger *SimpleLogger) Trace(msg string, ctx ...interface{}) {
+ log.Println(composeVargs(msg, ctx)...)
+}
+
// Debug implements Logger interface.
func (logger *SimpleLogger) Debug(msg string, ctx ...interface{}) {
log.Println(composeVargs(msg, ctx)...)
@@ -98,6 +108,11 @@ func NewCustomLogger(logger *log.Logger) *CustomLogger {
}
}
+// Trace implements Logger interface.
+func (logger *CustomLogger) Trace(msg string, ctx ...interface{}) {
+ logger.logger.Println(composeVargs(msg, ctx)...)
+}
+
// Debug implements Logger interface.
func (logger *CustomLogger) Debug(msg string, ctx ...interface{}) {
logger.logger.Println(composeVargs(msg, ctx)...)
diff --git a/vendor/github.com/dexon-foundation/dexon-consensus/core/blockpool.go b/vendor/github.com/dexon-foundation/dexon-consensus/core/blockpool.go
index fbd84f21c..4e41aa7c4 100644
--- a/vendor/github.com/dexon-foundation/dexon-consensus/core/blockpool.go
+++ b/vendor/github.com/dexon-foundation/dexon-consensus/core/blockpool.go
@@ -29,8 +29,8 @@ type blockPool []types.ByPosition
func newBlockPool(chainNum uint32) (pool blockPool) {
pool = make(blockPool, chainNum)
- for _, p := range pool {
- heap.Init(&p)
+ for i := range pool {
+ heap.Init(&pool[i])
}
return
}
diff --git a/vendor/github.com/dexon-foundation/dexon-consensus/core/configuration-chain.go b/vendor/github.com/dexon-foundation/dexon-consensus/core/configuration-chain.go
index a4636cb7b..fbd691f73 100644
--- a/vendor/github.com/dexon-foundation/dexon-consensus/core/configuration-chain.go
+++ b/vendor/github.com/dexon-foundation/dexon-consensus/core/configuration-chain.go
@@ -91,6 +91,7 @@ func (cc *configurationChain) registerDKG(round uint64, threshold int) {
defer cc.dkgLock.Unlock()
if cc.dkg != nil {
cc.logger.Error("Previous DKG is not finished")
+ // TODO(mission): return here and fix CI failure.
}
dkgSet, err := cc.cache.GetDKGSet(round)
if err != nil {
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 faadbe9bd..0e5a1fbdb 100644
--- a/vendor/github.com/dexon-foundation/dexon-consensus/core/consensus.go
+++ b/vendor/github.com/dexon-foundation/dexon-consensus/core/consensus.go
@@ -1015,8 +1015,11 @@ func (con *Consensus) pullRandomness() {
case <-time.After(1500 * time.Millisecond):
// TODO(jimmy): pulling period should be related to lambdaBA.
hashes := con.ccModule.pendingBlocksWithoutRandomness()
- con.logger.Debug("Calling Network.PullRandomness", "blocks", hashes)
- con.network.PullRandomness(hashes)
+ if len(hashes) > 0 {
+ con.logger.Debug(
+ "Calling Network.PullRandomness", "blocks", hashes)
+ con.network.PullRandomness(hashes)
+ }
}
}
}
diff --git a/vendor/github.com/dexon-foundation/dexon-consensus/core/interfaces.go b/vendor/github.com/dexon-foundation/dexon-consensus/core/interfaces.go
index 20770328c..aa87e38f7 100644
--- a/vendor/github.com/dexon-foundation/dexon-consensus/core/interfaces.go
+++ b/vendor/github.com/dexon-foundation/dexon-consensus/core/interfaces.go
@@ -144,6 +144,12 @@ type Governance interface {
// IsDKGFinal checks if DKG is final.
IsDKGFinal(round uint64) bool
+
+ // ReportForkVote reports a node for forking votes.
+ ReportForkVote(vote1, vote2 *types.Vote)
+
+ // ReportForkBlock reports a node for forking blocks.
+ ReportForkBlock(block1, block2 *types.Block)
}
// Ticker define the capability to tick by interval.
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 32ea6547a..9b351eabc 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
@@ -18,8 +18,6 @@
package syncer
import (
- "sync"
-
"github.com/dexon-foundation/dexon-consensus/common"
"github.com/dexon-foundation/dexon-consensus/core"
"github.com/dexon-foundation/dexon-consensus/core/types"
@@ -29,7 +27,6 @@ import (
// Struct agreement implements struct of BA (Byzantine Agreement) protocol
// needed in syncer, which only receives agreement results.
type agreement struct {
- wg *sync.WaitGroup
cache *utils.NodeSetCache
inputChan chan interface{}
outputChan chan<- *types.Block
@@ -47,12 +44,10 @@ func newAgreement(
ch chan<- *types.Block,
pullChan chan<- common.Hash,
cache *utils.NodeSetCache,
- wg *sync.WaitGroup,
logger common.Logger) *agreement {
return &agreement{
cache: cache,
- wg: wg,
inputChan: make(chan interface{}, 1000),
outputChan: ch,
pullChan: pullChan,
@@ -68,8 +63,6 @@ func newAgreement(
// run starts the agreement, this does not start a new routine, go a new
// routine explicitly in the caller.
func (a *agreement) run() {
- a.wg.Add(1)
- defer a.wg.Done()
for {
select {
case val, ok := <-a.inputChan:
@@ -106,7 +99,7 @@ func (a *agreement) processBlock(b *types.Block) {
func (a *agreement) processAgreementResult(r *types.AgreementResult) {
// Cache those results that CRS is not ready yet.
if _, exists := a.confirmedBlocks[r.BlockHash]; exists {
- a.logger.Debug("agreement result already confirmed", "result", r)
+ a.logger.Trace("agreement result already confirmed", "result", r)
return
}
if r.Position.Round > a.latestCRSRound {
@@ -116,7 +109,7 @@ func (a *agreement) processAgreementResult(r *types.AgreementResult) {
a.pendings[r.Position.Round] = pendingsForRound
}
pendingsForRound[r.BlockHash] = r
- a.logger.Debug("agreement result cached", "result", r)
+ a.logger.Trace("agreement result cached", "result", r)
return
}
if err := core.VerifyAgreementResult(r, a.cache); err != nil {
diff --git a/vendor/github.com/dexon-foundation/dexon-consensus/core/syncer/consensus.go b/vendor/github.com/dexon-foundation/dexon-consensus/core/syncer/consensus.go
index d334bbd88..92f8fd8d0 100644
--- a/vendor/github.com/dexon-foundation/dexon-consensus/core/syncer/consensus.go
+++ b/vendor/github.com/dexon-foundation/dexon-consensus/core/syncer/consensus.go
@@ -262,12 +262,12 @@ func (con *Consensus) ensureAgreementOverlapRound() bool {
for r = range tipRoundMap {
break
}
- con.logger.Info("check agreement round cut",
+ con.logger.Debug("check agreement round cut",
"tip-round", r,
"configs", len(con.configs))
if tipRoundMap[r] == con.configs[r].NumChains {
con.agreementRoundCut = r
- con.logger.Debug("agreement round cut found, round", r)
+ con.logger.Info("agreement round cut found, round", r)
return true
}
}
@@ -416,7 +416,7 @@ func (con *Consensus) SyncBlocks(
"expected", tipHeight+1)
return false, ErrInvalidSyncingFinalizationHeight
}
- con.logger.Debug("syncBlocks",
+ con.logger.Trace("syncBlocks",
"position", &blocks[0].Position,
"final height", blocks[0].Finalization.Height,
"len", len(blocks),
@@ -601,7 +601,7 @@ func (con *Consensus) setupConfigs(blocks []*types.Block) {
maxRound = b.Position.Round
}
}
- con.logger.Info("syncer setupConfigs",
+ con.logger.Debug("syncer setupConfigs",
"max", maxRound,
"lattice", con.latticeLastRound)
// Get configs from governance.
@@ -623,10 +623,13 @@ func (con *Consensus) resizeByNumChains(numChains uint32) {
// Resize the pool of blocks.
con.blocks = append(con.blocks, types.ByPosition{})
// Resize agreement modules.
- a := newAgreement(con.receiveChan, con.pullChan, con.nodeSetCache,
- &con.agreementWaitGroup, con.logger)
+ a := newAgreement(con.receiveChan, con.pullChan, con.nodeSetCache, con.logger)
con.agreements = append(con.agreements, a)
- go a.run()
+ con.agreementWaitGroup.Add(1)
+ go func() {
+ defer con.agreementWaitGroup.Done()
+ a.run()
+ }()
}
}
}
@@ -734,7 +737,7 @@ func (con *Consensus) startCRSMonitor() {
if round == lastNotifiedRound {
return
}
- con.logger.Info("CRS is ready", "round", round)
+ con.logger.Debug("CRS is ready", "round", round)
lastNotifiedRound = round
for _, a := range con.agreements {
a.inputChan <- round
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
index f42b70267..b2a8f57f8 100644
--- a/vendor/github.com/dexon-foundation/dexon-consensus/core/types/block.go
+++ b/vendor/github.com/dexon-foundation/dexon-consensus/core/types/block.go
@@ -24,7 +24,6 @@ import (
"fmt"
"io"
"sort"
- "sync"
"time"
"github.com/dexon-foundation/dexon/rlp"
@@ -47,15 +46,6 @@ const (
VerifyInvalidBlock
)
-var (
- // blockPool is the blocks cache to reuse allocated blocks.
- blockPool = sync.Pool{
- New: func() interface{} {
- return &Block{}
- },
- }
-)
-
type rlpTimestamp struct {
time.Time
}
@@ -133,19 +123,6 @@ type Witness struct {
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"`
@@ -226,7 +203,7 @@ func (b *Block) String() string {
// Clone returns a deep copy of a block.
func (b *Block) Clone() (bcopy *Block) {
- bcopy = NewBlock()
+ bcopy = &Block{}
bcopy.ProposerID = b.ProposerID
bcopy.ParentHash = b.ParentHash
bcopy.Hash = b.Hash
diff --git a/vendor/github.com/dexon-foundation/dexon-consensus/core/utils/crypto.go b/vendor/github.com/dexon-foundation/dexon-consensus/core/utils/crypto.go
index 60424115e..43bbde13d 100644
--- a/vendor/github.com/dexon-foundation/dexon-consensus/core/utils/crypto.go
+++ b/vendor/github.com/dexon-foundation/dexon-consensus/core/utils/crypto.go
@@ -90,7 +90,8 @@ func VerifyBlockSignature(b *types.Block) (err error) {
}
-func hashVote(vote *types.Vote) common.Hash {
+// HashVote generates hash of a types.Vote.
+func HashVote(vote *types.Vote) common.Hash {
binaryPeriod := make([]byte, 8)
binary.LittleEndian.PutUint64(binaryPeriod, vote.Period)
@@ -108,7 +109,7 @@ func hashVote(vote *types.Vote) common.Hash {
// VerifyVoteSignature verifies the signature of types.Vote.
func VerifyVoteSignature(vote *types.Vote) (bool, error) {
- hash := hashVote(vote)
+ hash := HashVote(vote)
pubKey, err := crypto.SigToPub(hash, vote.Signature)
if err != nil {
return false, err
diff --git a/vendor/github.com/dexon-foundation/dexon-consensus/core/utils/signer.go b/vendor/github.com/dexon-foundation/dexon-consensus/core/utils/signer.go
index 47bea3f3d..7694dab4e 100644
--- a/vendor/github.com/dexon-foundation/dexon-consensus/core/utils/signer.go
+++ b/vendor/github.com/dexon-foundation/dexon-consensus/core/utils/signer.go
@@ -66,7 +66,7 @@ func (s *Signer) SignBlock(b *types.Block) (err error) {
// SignVote signs a types.Vote.
func (s *Signer) SignVote(v *types.Vote) (err error) {
v.ProposerID = s.proposerID
- v.Signature, err = s.prvKey.Sign(hashVote(v))
+ v.Signature, err = s.prvKey.Sign(HashVote(v))
return
}
diff --git a/vendor/github.com/dexon-foundation/dexon-consensus/core/utils/utils.go b/vendor/github.com/dexon-foundation/dexon-consensus/core/utils/utils.go
index 687d0ea22..8c9f77a69 100644
--- a/vendor/github.com/dexon-foundation/dexon-consensus/core/utils/utils.go
+++ b/vendor/github.com/dexon-foundation/dexon-consensus/core/utils/utils.go
@@ -15,22 +15,6 @@
// along with the dexon-consensus library. If not, see
// <http://www.gnu.org/licenses/>.
-// 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 utils
import (
diff --git a/vendor/vendor.json b/vendor/vendor.json
index 7ca44b2c0..f2da6e117 100644
--- a/vendor/vendor.json
+++ b/vendor/vendor.json
@@ -139,70 +139,92 @@
"versionExact": "dev"
},
{
- "checksumSHA1": "65L1yf+f0OCiLFniljqfRxVdsQA=",
+ "checksumSHA1": "ZUuiRqS6PnoNIvBmLStVQiyhkOM=",
"path": "github.com/dexon-foundation/dexon-consensus/common",
- "revision": "beaef47dd5dd4b342cef3c8b26508ce3c334be06",
- "revisionTime": "2019-01-04T06:43:20Z"
+ "revision": "af8c182a07f9bf3a7a17c938c87f4eef489bb903",
+ "revisionTime": "2019-01-05T09:58:34Z",
+ "version": "master",
+ "versionExact": "master"
},
{
- "checksumSHA1": "Udj+vrFiUDboPRspH3S7URdKj+0=",
+ "checksumSHA1": "aqhVp5CBDq52ytHUH3HatpWhTDQ=",
"path": "github.com/dexon-foundation/dexon-consensus/core",
- "revision": "beaef47dd5dd4b342cef3c8b26508ce3c334be06",
- "revisionTime": "2019-01-04T06:43:20Z"
+ "revision": "af8c182a07f9bf3a7a17c938c87f4eef489bb903",
+ "revisionTime": "2019-01-05T09:58:34Z",
+ "version": "master",
+ "versionExact": "master"
},
{
"checksumSHA1": "v4fKR7uhoyufi6hAVO44cFEb+tY=",
"path": "github.com/dexon-foundation/dexon-consensus/core/blockdb",
"revision": "56e872f84131348adbc0861afb3554bba4a8e5db",
- "revisionTime": "2018-12-05T06:29:54Z"
+ "revisionTime": "2018-12-05T06:29:54Z",
+ "version": "master",
+ "versionExact": "master"
},
{
"checksumSHA1": "tQSbYCu5P00lUhKsx3IbBZCuSLY=",
"path": "github.com/dexon-foundation/dexon-consensus/core/crypto",
- "revision": "beaef47dd5dd4b342cef3c8b26508ce3c334be06",
- "revisionTime": "2019-01-04T06:43:20Z"
+ "revision": "af8c182a07f9bf3a7a17c938c87f4eef489bb903",
+ "revisionTime": "2019-01-05T09:58:34Z",
+ "version": "master",
+ "versionExact": "master"
},
{
"checksumSHA1": "W2P7pkuJ+26BpJg03K4Y0nB5obI=",
"path": "github.com/dexon-foundation/dexon-consensus/core/crypto/dkg",
- "revision": "beaef47dd5dd4b342cef3c8b26508ce3c334be06",
- "revisionTime": "2019-01-04T06:43:20Z"
+ "revision": "af8c182a07f9bf3a7a17c938c87f4eef489bb903",
+ "revisionTime": "2019-01-05T09:58:34Z",
+ "version": "master",
+ "versionExact": "master"
},
{
"checksumSHA1": "6Pf6caC8LTNCI7IflFmglKYnxYo=",
"path": "github.com/dexon-foundation/dexon-consensus/core/crypto/ecdsa",
- "revision": "beaef47dd5dd4b342cef3c8b26508ce3c334be06",
- "revisionTime": "2019-01-04T06:43:20Z"
+ "revision": "af8c182a07f9bf3a7a17c938c87f4eef489bb903",
+ "revisionTime": "2019-01-05T09:58:34Z",
+ "version": "master",
+ "versionExact": "master"
},
{
"checksumSHA1": "PJXR1OuWwVVYrdJMK3skPr1/8ls=",
"path": "github.com/dexon-foundation/dexon-consensus/core/db",
- "revision": "beaef47dd5dd4b342cef3c8b26508ce3c334be06",
- "revisionTime": "2019-01-04T06:43:20Z"
+ "revision": "af8c182a07f9bf3a7a17c938c87f4eef489bb903",
+ "revisionTime": "2019-01-05T09:58:34Z",
+ "version": "master",
+ "versionExact": "master"
},
{
- "checksumSHA1": "tFFonPHlve/3JqqRSopnLb6Rn2o=",
+ "checksumSHA1": "h674l/hugVujbZUy/NSeDmio3/U=",
"path": "github.com/dexon-foundation/dexon-consensus/core/syncer",
- "revision": "beaef47dd5dd4b342cef3c8b26508ce3c334be06",
- "revisionTime": "2019-01-04T06:43:20Z"
+ "revision": "af8c182a07f9bf3a7a17c938c87f4eef489bb903",
+ "revisionTime": "2019-01-05T09:58:34Z",
+ "version": "master",
+ "versionExact": "master"
},
{
- "checksumSHA1": "Kpmnp6XIAnnSSncijzOBo77OshY=",
+ "checksumSHA1": "GRiBmU5T1LAoGHs5g1owGE1tNNo=",
"path": "github.com/dexon-foundation/dexon-consensus/core/types",
- "revision": "beaef47dd5dd4b342cef3c8b26508ce3c334be06",
- "revisionTime": "2019-01-04T06:43:20Z"
+ "revision": "af8c182a07f9bf3a7a17c938c87f4eef489bb903",
+ "revisionTime": "2019-01-05T09:58:34Z",
+ "version": "master",
+ "versionExact": "master"
},
{
"checksumSHA1": "rmv8uxwrqMhJAeA3RPvwYP8mFro=",
"path": "github.com/dexon-foundation/dexon-consensus/core/types/dkg",
- "revision": "beaef47dd5dd4b342cef3c8b26508ce3c334be06",
- "revisionTime": "2019-01-04T06:43:20Z"
+ "revision": "af8c182a07f9bf3a7a17c938c87f4eef489bb903",
+ "revisionTime": "2019-01-05T09:58:34Z",
+ "version": "master",
+ "versionExact": "master"
},
{
- "checksumSHA1": "zvk7bSkUGBwMGi9j+15Ve10noyg=",
+ "checksumSHA1": "NCAEGRVPfM0jCKdrBN2yvEXkeIo=",
"path": "github.com/dexon-foundation/dexon-consensus/core/utils",
- "revision": "beaef47dd5dd4b342cef3c8b26508ce3c334be06",
- "revisionTime": "2019-01-04T06:43:20Z"
+ "revision": "af8c182a07f9bf3a7a17c938c87f4eef489bb903",
+ "revisionTime": "2019-01-05T09:58:34Z",
+ "version": "master",
+ "versionExact": "master"
},
{
"checksumSHA1": "TAkwduKZqLyimyTPPWIllZWYFuE=",