From ad6c88e859134d234145664077b3c909e3a920f3 Mon Sep 17 00:00:00 2001 From: stefano galassi Date: Mon, 9 Mar 2020 12:35:48 +0800 Subject: [PATCH 01/11] Bug fixing * Add (dummy) ValidatePayloadHash to be used to validate payload data when downloading a block + attached data from other peers * Add GetPayloadHash and separated logic to compute block's payload hash from GenerateBlock to an individual method to make it reusable (eg. in GenerateBlock and ValidatePayloadHash) * Fix tests --- common/schema | 2 +- core/service/blockCoreService.go | 2 + core/service/blockMainService.go | 68 +++++++++++++-------- core/service/blockMainService_test.go | 13 ++-- core/service/blockSpineService.go | 83 ++++++++++++++++---------- core/service/blockSpineService_test.go | 13 ++-- 6 files changed, 106 insertions(+), 75 deletions(-) diff --git a/common/schema b/common/schema index 5ef391404..6558d9252 160000 --- a/common/schema +++ b/common/schema @@ -1 +1 @@ -Subproject commit 5ef39140434481b2ce5cb8f9632477a38756864d +Subproject commit 6558d9252a95e48bb3188139ce091f1bc1ce5e22 diff --git a/core/service/blockCoreService.go b/core/service/blockCoreService.go index afeb9bcbe..37b538817 100644 --- a/core/service/blockCoreService.go +++ b/core/service/blockCoreService.go @@ -22,6 +22,8 @@ type ( timestamp int64, ) (*model.Block, error) ValidateBlock(block, previousLastBlock *model.Block, curTime int64) error + ValidatePayloadHash(block *model.Block) error + GetPayloadHash(block *model.Block) (payloadHash []byte, payloadLength uint32, err error) PushBlock(previousBlock, block *model.Block, broadcast, persist bool) error GetBlockByID(id int64, withAttachedData bool) (*model.Block, error) GetBlockByHeight(uint32) (*model.Block, error) diff --git a/core/service/blockMainService.go b/core/service/blockMainService.go index 5c9610204..29ddbf13c 100644 --- a/core/service/blockMainService.go +++ b/core/service/blockMainService.go @@ -163,10 +163,12 @@ func (bs *BlockService) NewMainBlock( totalCoinBase int64, transactions []*model.Transaction, publishedReceipts []*model.PublishedReceipt, - payloadHash []byte, - payloadLength uint32, secretPhrase string, ) (*model.Block, error) { + var ( + err error + ) + block := &model.Block{ Version: version, PreviousBlockHash: previousBlockHash, @@ -179,9 +181,13 @@ func (bs *BlockService) NewMainBlock( TotalCoinBase: totalCoinBase, Transactions: transactions, PublishedReceipts: publishedReceipts, - PayloadHash: payloadHash, - PayloadLength: payloadLength, } + + // compute block's payload hash and length and add it to block struct + if block.PayloadHash, block.PayloadLength, err = bs.GetPayloadHash(block); err != nil { + return nil, err + } + blockUnsignedByte, err := util.GetBlockByte(block, false, bs.Chaintype) if err != nil { bs.Logger.Error(err.Error()) @@ -258,6 +264,11 @@ func (bs *BlockService) NewGenesisBlock( return block, nil } +// ValidatePayloadHash validate block's payload data hash against block's payload hash +func (*BlockService) ValidatePayloadHash(block *model.Block) error { + return nil +} + // PreValidateBlock valdiate block without it's transactions func (bs *BlockService) PreValidateBlock(block, previousLastBlock *model.Block) error { // check if blocksmith can smith at the time @@ -875,6 +886,33 @@ func (bs *BlockService) RemoveMempoolTransactions(transactions []*model.Transact return nil } +func (bs *BlockService) GetPayloadHash(block *model.Block) (payloadHash []byte, payloadLength uint32, err error) { + var ( + digest = sha3.New256() + ) + for _, tx := range block.GetTransactions() { + if _, err := digest.Write(tx.GetTransactionHash()); err != nil { + return nil, 0, err + } + txType, err := bs.ActionTypeSwitcher.GetTransactionType(tx) + if err != nil { + return nil, 0, err + } + payloadLength += txType.GetSize() + } + // filter only good receipt + for _, br := range block.GetPublishedReceipts() { + brBytes := bs.ReceiptUtil.GetSignedBatchReceiptBytes(br.BatchReceipt) + _, err = digest.Write(brBytes) + if err != nil { + return nil, 0, err + } + payloadLength += uint32(len(brBytes)) + } + payloadHash = digest.Sum([]byte{}) + return +} + // GenerateBlock generate block from transactions in mempool func (bs *BlockService) GenerateBlock( previousBlock *model.Block, @@ -883,11 +921,9 @@ func (bs *BlockService) GenerateBlock( ) (*model.Block, error) { var ( totalAmount, totalFee, totalCoinbase int64 - payloadLength uint32 // only for mainchain sortedTransactions []*model.Transaction publishedReceipts []*model.PublishedReceipt - payloadHash []byte err error digest = sha3.New256() blockSmithPublicKey = crypto.NewEd25519Signature().GetPublicKeyFromSeed(secretPhrase) @@ -901,16 +937,12 @@ func (bs *BlockService) GenerateBlock( } // select transactions from mempool to be added to the block for _, tx := range sortedTransactions { - if _, err := digest.Write(tx.TransactionHash); err != nil { - return nil, err - } txType, err := bs.ActionTypeSwitcher.GetTransactionType(tx) if err != nil { return nil, err } totalAmount += txType.GetAmount() totalFee += tx.Fee - payloadLength += txType.GetSize() } // select published receipts to be added to the block publishedReceipts, err = bs.ReceiptService.SelectReceipts( @@ -918,27 +950,15 @@ func (bs *BlockService) GenerateBlock( len(bs.BlocksmithStrategy.GetSortedBlocksmiths(previousBlock))), previousBlock.Height, ) - // FIXME: add published receipts to block payload length - if err != nil { return nil, err } - // filter only good receipt - for _, br := range publishedReceipts { - _, err = digest.Write(bs.ReceiptUtil.GetSignedBatchReceiptBytes(br.BatchReceipt)) - if err != nil { - return nil, err - } - } - payloadHash = digest.Sum([]byte{}) - // loop through transaction to build block hash - digest.Reset() // reset the digest if _, err := digest.Write(previousBlock.GetBlockSeed()); err != nil { return nil, err } - previousSeedHash := digest.Sum([]byte{}) + blockSeed := bs.Signature.SignByNode(previousSeedHash, secretPhrase) digest.Reset() // reset the digest // compute the previous block hash @@ -958,8 +978,6 @@ func (bs *BlockService) GenerateBlock( totalCoinbase, sortedTransactions, publishedReceipts, - payloadHash, - payloadLength, secretPhrase, ) if err != nil { diff --git a/core/service/blockMainService_test.go b/core/service/blockMainService_test.go index 5e0d44c42..36aa54d26 100644 --- a/core/service/blockMainService_test.go +++ b/core/service/blockMainService_test.go @@ -615,9 +615,10 @@ func TestBlockService_NewBlock(t *testing.T) { TotalCoinBase: 0, Transactions: []*model.Transaction{}, PublishedReceipts: []*model.PublishedReceipt{}, - PayloadHash: []byte{}, - PayloadLength: 0, - BlockSignature: []byte{}, + PayloadHash: []byte{167, 255, 198, 248, 191, 30, 215, 102, 81, 193, 71, 86, 160, 97, 214, 98, 245, 128, + 255, 77, 228, 59, 73, 250, 130, 216, 10, 75, 128, 248, 67, 74}, + PayloadLength: 0, + BlockSignature: []byte{}, } mockBlockHash, _ = util.GetBlockHash(mockBlock, &chaintype.MainChain{}) ) @@ -644,8 +645,6 @@ func TestBlockService_NewBlock(t *testing.T) { totalCoinBase int64 transactions []*model.Transaction publishedReceipts []*model.PublishedReceipt - payloadHash []byte - payloadLength uint32 secretPhrase string } tests := []struct { @@ -673,8 +672,6 @@ func TestBlockService_NewBlock(t *testing.T) { totalCoinBase: 0, transactions: []*model.Transaction{}, publishedReceipts: []*model.PublishedReceipt{}, - payloadHash: []byte{}, - payloadLength: 0, secretPhrase: "secretphrase", }, want: mockBlock, @@ -703,8 +700,6 @@ func TestBlockService_NewBlock(t *testing.T) { tt.args.totalCoinBase, tt.args.transactions, tt.args.publishedReceipts, - tt.args.payloadHash, - tt.args.payloadLength, tt.args.secretPhrase, ) if (err != nil) != tt.wantErr { diff --git a/core/service/blockSpineService.go b/core/service/blockSpineService.go index 5701c7b3b..a9007b6ca 100644 --- a/core/service/blockSpineService.go +++ b/core/service/blockSpineService.go @@ -84,12 +84,14 @@ func (bs *BlockSpineService) NewSpineBlock( blockSeed, blockSmithPublicKey []byte, previousBlockHeight uint32, timestamp int64, - payloadHash []byte, - payloadLength uint32, secretPhrase string, spinePublicKeys []*model.SpinePublicKey, spineBlockManifests []*model.SpineBlockManifest, ) (*model.Block, error) { + var ( + payloadLength uint32 + err error + ) block := &model.Block{ Version: version, PreviousBlockHash: previousBlockHash, @@ -97,11 +99,16 @@ func (bs *BlockSpineService) NewSpineBlock( BlocksmithPublicKey: blockSmithPublicKey, Height: previousBlockHeight, Timestamp: timestamp, - PayloadHash: payloadHash, PayloadLength: payloadLength, SpinePublicKeys: spinePublicKeys, SpineBlockManifests: spineBlockManifests, } + + // compute block's payload hash and length and add it to block struct + if block.PayloadHash, block.PayloadLength, err = bs.GetPayloadHash(block); err != nil { + return nil, err + } + blockUnsignedByte, err := util.GetBlockByte(block, false, bs.Chaintype) if err != nil { bs.Logger.Error(err.Error()) @@ -178,10 +185,18 @@ func (bs *BlockSpineService) NewGenesisBlock( return block, nil } +// ValidatePayloadHash validate block's payload data hash against block's payload hash +func (*BlockSpineService) ValidatePayloadHash(block *model.Block) error { + + return nil +} + // ValidateBlock validate block to be pushed into the blockchain func (bs *BlockSpineService) ValidateBlock(block, previousLastBlock *model.Block, curTime int64) error { - // TODO: validate spine block manifest if part of block data - // - re-calculate block payload hash using data from 'block' func argument and compare it with block.PayloadHash + // validate block's payload data + if err := bs.ValidatePayloadHash(block); err != nil { + return err + } // todo: validate previous time if block.GetTimestamp() > curTime+constant.GenerateBlockTimeoutSec { @@ -475,6 +490,31 @@ func (bs *BlockSpineService) PopulateBlockData(block *model.Block) error { return nil } +// GetPayloadBytes compute and return the block's payload hash +func (bs *BlockSpineService) GetPayloadHash(block *model.Block) (payloadHash []byte, payloadLength uint32, err error) { + var ( + digest = sha3.New256() + ) + for _, spinePubKey := range block.GetSpinePublicKeys() { + spinePubKeyBytes := commonUtils.GetSpinePublicKeyBytes(spinePubKey) + if _, err := digest.Write(spinePubKeyBytes); err != nil { + return nil, 0, err + } + payloadLength += uint32(len(spinePubKeyBytes)) + + } + // compute the block payload length and hash by parsing all file chunks db entities into their bytes representation + for _, spineBlockManifest := range block.GetSpineBlockManifests() { + spineBlockManifestBytes := bs.SpineBlockManifestService.GetSpineBlockManifestBytes(spineBlockManifest) + if _, err := digest.Write(spineBlockManifestBytes); err != nil { + return nil, 0, err + } + payloadLength += uint32(len(spineBlockManifestBytes)) + } + payloadHash = digest.Sum([]byte{}) + return +} + // GenerateBlock generate block from transactions in mempool func (bs *BlockSpineService) GenerateBlock( previousBlock *model.Block, @@ -482,26 +522,21 @@ func (bs *BlockSpineService) GenerateBlock( timestamp int64, ) (*model.Block, error) { var ( - payloadLength uint32 - spinePublicKeys []*model.SpinePublicKey - payloadBytes, payloadHash []byte - err error - digest = sha3.New256() - blockSmithPublicKey = crypto.NewEd25519Signature().GetPublicKeyFromSeed(secretPhrase) - fromTimestamp = previousBlock.Timestamp - spineBlockManifests []*model.SpineBlockManifest + spinePublicKeys []*model.SpinePublicKey + err error + digest = sha3.New256() + blockSmithPublicKey = crypto.NewEd25519Signature().GetPublicKeyFromSeed(secretPhrase) + fromTimestamp = previousBlock.Timestamp + spineBlockManifests []*model.SpineBlockManifest ) newBlockHeight := previousBlock.Height + 1 // compute spine pub keys from mainchain node registrations // Note: since spine blocks are not in sync with main blocks and they are unaware of the height (on mainchain) where to retrieve - // node registration's public keys, we use timestamps for now + // node registration's public keys, we use timestamps instead of block heights if fromTimestamp == bs.GetChainType().GetGenesisBlockTimestamp() { fromTimestamp++ } spinePublicKeys, err = bs.SpinePublicKeyService.BuildSpinePublicKeysFromNodeRegistry(fromTimestamp, timestamp, newBlockHeight) - for _, spinePubKey := range spinePublicKeys { - payloadBytes = append(payloadBytes, commonUtils.GetSpinePublicKeyBytes(spinePubKey)...) - } if err != nil { return nil, err } @@ -511,19 +546,7 @@ func (bs *BlockSpineService) GenerateBlock( if err != nil { return nil, err } - // compute the block payload length and hash by parsing all file chunks db entities into their bytes representation - if len(spineBlockManifests) > 0 { - for _, spineBlockManifest := range spineBlockManifests { - megablockBytes := bs.SpineBlockManifestService.GetSpineBlockManifestBytes(spineBlockManifest) - payloadBytes = append(payloadBytes, megablockBytes...) - } - } - if _, err := digest.Write(payloadBytes); err != nil { - return nil, err - } - payloadHash = digest.Sum([]byte{}) - payloadLength = uint32(len(payloadBytes)) // loop through transaction to build block hash digest.Reset() // reset the digest if _, err := digest.Write(previousBlock.GetBlockSeed()); err != nil { @@ -545,8 +568,6 @@ func (bs *BlockSpineService) GenerateBlock( blockSmithPublicKey, newBlockHeight, timestamp, - payloadHash, - payloadLength, secretPhrase, spinePublicKeys, spineBlockManifests, diff --git a/core/service/blockSpineService_test.go b/core/service/blockSpineService_test.go index 30e1a5bea..3f45672f3 100644 --- a/core/service/blockSpineService_test.go +++ b/core/service/blockSpineService_test.go @@ -556,9 +556,10 @@ func TestBlockSpineService_NewSpineBlock(t *testing.T) { BlocksmithPublicKey: bcsNodePubKey1, Timestamp: 15875392, SpinePublicKeys: []*model.SpinePublicKey{}, - PayloadHash: []byte{}, - PayloadLength: 0, - BlockSignature: []byte{}, + PayloadHash: []byte{167, 255, 198, 248, 191, 30, 215, 102, 81, 193, 71, 86, 160, 97, 214, 98, 245, 128, + 255, 77, 228, 59, 73, 250, 130, 216, 10, 75, 128, 248, 67, 74}, + PayloadLength: 0, + BlockSignature: []byte{}, } mockSpineBlockHash, _ = util.GetBlockHash(mockSpineBlock, &chaintype.SpineChain{}) ) @@ -581,8 +582,6 @@ func TestBlockSpineService_NewSpineBlock(t *testing.T) { previousBlockHeight uint32 timestamp int64 spinePublicKeys []*model.SpinePublicKey - payloadHash []byte - payloadLength uint32 secretPhrase string spineBlockManifests []*model.SpineBlockManifest } @@ -607,8 +606,6 @@ func TestBlockSpineService_NewSpineBlock(t *testing.T) { previousBlockHeight: 0, timestamp: 15875392, spinePublicKeys: []*model.SpinePublicKey{}, - payloadHash: []byte{}, - payloadLength: 0, secretPhrase: "secretphrase", }, want: mockSpineBlock, @@ -629,8 +626,6 @@ func TestBlockSpineService_NewSpineBlock(t *testing.T) { tt.args.blockSmithPublicKey, tt.args.previousBlockHeight, tt.args.timestamp, - tt.args.payloadHash, - tt.args.payloadLength, tt.args.secretPhrase, tt.args.spinePublicKeys, tt.args.spineBlockManifests, From 95d3b19eab5e02872e18ecf1698d0ff84704257c Mon Sep 17 00:00:00 2001 From: stefano galassi Date: Mon, 9 Mar 2020 12:44:06 +0800 Subject: [PATCH 02/11] Code Refactoring * Refactored method's name from GetPayloadHash to GetPayloadHashAndLength --- core/service/blockCoreService.go | 2 +- core/service/blockMainService.go | 4 ++-- core/service/blockSpineService.go | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/core/service/blockCoreService.go b/core/service/blockCoreService.go index 37b538817..71b719e2a 100644 --- a/core/service/blockCoreService.go +++ b/core/service/blockCoreService.go @@ -23,7 +23,7 @@ type ( ) (*model.Block, error) ValidateBlock(block, previousLastBlock *model.Block, curTime int64) error ValidatePayloadHash(block *model.Block) error - GetPayloadHash(block *model.Block) (payloadHash []byte, payloadLength uint32, err error) + GetPayloadHashAndLength(block *model.Block) (payloadHash []byte, payloadLength uint32, err error) PushBlock(previousBlock, block *model.Block, broadcast, persist bool) error GetBlockByID(id int64, withAttachedData bool) (*model.Block, error) GetBlockByHeight(uint32) (*model.Block, error) diff --git a/core/service/blockMainService.go b/core/service/blockMainService.go index 29ddbf13c..0eea215e9 100644 --- a/core/service/blockMainService.go +++ b/core/service/blockMainService.go @@ -184,7 +184,7 @@ func (bs *BlockService) NewMainBlock( } // compute block's payload hash and length and add it to block struct - if block.PayloadHash, block.PayloadLength, err = bs.GetPayloadHash(block); err != nil { + if block.PayloadHash, block.PayloadLength, err = bs.GetPayloadHashAndLength(block); err != nil { return nil, err } @@ -886,7 +886,7 @@ func (bs *BlockService) RemoveMempoolTransactions(transactions []*model.Transact return nil } -func (bs *BlockService) GetPayloadHash(block *model.Block) (payloadHash []byte, payloadLength uint32, err error) { +func (bs *BlockService) GetPayloadHashAndLength(block *model.Block) (payloadHash []byte, payloadLength uint32, err error) { var ( digest = sha3.New256() ) diff --git a/core/service/blockSpineService.go b/core/service/blockSpineService.go index a9007b6ca..b95ba5bce 100644 --- a/core/service/blockSpineService.go +++ b/core/service/blockSpineService.go @@ -105,7 +105,7 @@ func (bs *BlockSpineService) NewSpineBlock( } // compute block's payload hash and length and add it to block struct - if block.PayloadHash, block.PayloadLength, err = bs.GetPayloadHash(block); err != nil { + if block.PayloadHash, block.PayloadLength, err = bs.GetPayloadHashAndLength(block); err != nil { return nil, err } @@ -491,7 +491,7 @@ func (bs *BlockSpineService) PopulateBlockData(block *model.Block) error { } // GetPayloadBytes compute and return the block's payload hash -func (bs *BlockSpineService) GetPayloadHash(block *model.Block) (payloadHash []byte, payloadLength uint32, err error) { +func (bs *BlockSpineService) GetPayloadHashAndLength(block *model.Block) (payloadHash []byte, payloadLength uint32, err error) { var ( digest = sha3.New256() ) From 34a15455e89a419f889c7ec9f439f9721bcbb0df Mon Sep 17 00:00:00 2001 From: stefano galassi Date: Mon, 9 Mar 2020 14:23:17 +0800 Subject: [PATCH 03/11] Added logic to validate block's payload on block push * Add ValidatePayloadHash logic to blockMainService and blockSpineService * Fix tests --- core/service/blockMainService.go | 17 ++++++++++++++--- core/service/blockMainService_test.go | 5 +++-- core/service/blockSpineService.go | 12 +++++++++--- core/service/blockSpineService_test.go | 8 ++++++-- 4 files changed, 32 insertions(+), 10 deletions(-) diff --git a/core/service/blockMainService.go b/core/service/blockMainService.go index 0eea215e9..2c29675dc 100644 --- a/core/service/blockMainService.go +++ b/core/service/blockMainService.go @@ -264,12 +264,19 @@ func (bs *BlockService) NewGenesisBlock( return block, nil } -// ValidatePayloadHash validate block's payload data hash against block's payload hash -func (*BlockService) ValidatePayloadHash(block *model.Block) error { +// ValidatePayloadHash validate (computed) block's payload data hash against block's payload hash +func (bs *BlockService) ValidatePayloadHash(block *model.Block) error { + hash, length, err := bs.GetPayloadHashAndLength(block) + if err != nil { + return err + } + if !bytes.Equal(hash, block.GetPayloadHash()) || length != block.GetPayloadLength() { + return blocker.NewBlocker(blocker.ValidationErr, "InvalidBlockPayload") + } return nil } -// PreValidateBlock valdiate block without it's transactions +// PreValidateBlock validate block without it's transactions func (bs *BlockService) PreValidateBlock(block, previousLastBlock *model.Block) error { // check if blocksmith can smith at the time blocksmithsMap := bs.BlocksmithStrategy.GetSortedBlocksmithsMap(previousLastBlock) @@ -287,6 +294,10 @@ func (bs *BlockService) PreValidateBlock(block, previousLastBlock *model.Block) // ValidateBlock validate block to be pushed into the blockchain func (bs *BlockService) ValidateBlock(block, previousLastBlock *model.Block, curTime int64) error { + if err := bs.ValidatePayloadHash(block); err != nil { + return err + } + // check block timestamp if block.GetTimestamp() > curTime+constant.GenerateBlockTimeoutSec { return blocker.NewBlocker(blocker.BlockErr, "InvalidTimestamp") diff --git a/core/service/blockMainService_test.go b/core/service/blockMainService_test.go index 36aa54d26..7cf50e36a 100644 --- a/core/service/blockMainService_test.go +++ b/core/service/blockMainService_test.go @@ -3570,8 +3570,9 @@ var ( 45, 118, 97, 219, 80, 242, 244, 100, 134, 144, 246, 37, 144, 213, 135}, BlockSignature: []byte{144, 246, 37, 144, 213, 135}, CumulativeDifficulty: "1000", - PayloadLength: 1, - PayloadHash: []byte{}, + PayloadLength: 0, + PayloadHash: []byte{167, 255, 198, 248, 191, 30, 215, 102, 81, 193, 71, 86, 160, + 97, 214, 98, 245, 128, 255, 77, 228, 59, 73, 250, 130, 216, 10, 75, 128, 248, 67, 74}, BlocksmithPublicKey: []byte{1, 2, 3, 200, 7, 61, 108, 229, 204, 48, 199, 145, 21, 99, 125, 75, 49, 45, 118, 97, 219, 80, 242, 244, 100, 134, 144, 246, 37, 144, 213, 135}, TotalAmount: 1000, diff --git a/core/service/blockSpineService.go b/core/service/blockSpineService.go index b95ba5bce..05d437164 100644 --- a/core/service/blockSpineService.go +++ b/core/service/blockSpineService.go @@ -185,9 +185,15 @@ func (bs *BlockSpineService) NewGenesisBlock( return block, nil } -// ValidatePayloadHash validate block's payload data hash against block's payload hash -func (*BlockSpineService) ValidatePayloadHash(block *model.Block) error { - +// ValidatePayloadHash validate (computed) block's payload data hash against block's payload hash +func (bs *BlockSpineService) ValidatePayloadHash(block *model.Block) error { + hash, length, err := bs.GetPayloadHashAndLength(block) + if err != nil { + return err + } + if !bytes.Equal(hash, block.GetPayloadHash()) || length != block.GetPayloadLength() { + return blocker.NewBlocker(blocker.ValidationErr, "InvalidBlockPayload") + } return nil } diff --git a/core/service/blockSpineService_test.go b/core/service/blockSpineService_test.go index 3f45672f3..c91c051e4 100644 --- a/core/service/blockSpineService_test.go +++ b/core/service/blockSpineService_test.go @@ -2235,6 +2235,9 @@ func TestBlockSpineService_ReceiveBlock(t *testing.T) { SpinePublicKeys: []*model.SpinePublicKey{ mockSpinePublicKey, }, + PayloadLength: 44, + PayloadHash: []byte{55, 140, 121, 255, 150, 51, 177, 63, 86, 185, 40, 206, 151, 168, 77, 67, 61, 43, 54, 73, 162, 230, + 10, 202, 83, 1, 185, 208, 203, 232, 73, 215}, } mockSpineBlockData.BlockHash = mockSpineGoodLastBlockHash @@ -2804,8 +2807,9 @@ var ( 45, 118, 97, 219, 80, 242, 244, 100, 134, 144, 246, 37, 144, 213, 135}, BlockSignature: []byte{144, 246, 37, 144, 213, 135}, CumulativeDifficulty: "1000", - PayloadLength: 1, - PayloadHash: []byte{}, + PayloadLength: 0, + PayloadHash: []byte{167, 255, 198, 248, 191, 30, 215, 102, 81, 193, 71, 86, 160, 97, 214, 98, 245, 128, 255, 77, + 228, 59, 73, 250, 130, 216, 10, 75, 128, 248, 67, 74}, BlocksmithPublicKey: []byte{1, 2, 3, 200, 7, 61, 108, 229, 204, 48, 199, 145, 21, 99, 125, 75, 49, 45, 118, 97, 219, 80, 242, 244, 100, 134, 144, 246, 37, 144, 213, 135}, TotalAmount: 1000, From fe7e55589c8546812821e8e3620b21497e420540 Mon Sep 17 00:00:00 2001 From: stefano galassi Date: Mon, 9 Mar 2020 17:51:28 +0800 Subject: [PATCH 04/11] Add logic to validate spine block manifest against its relative spine block of reference * Add GetBlockFromTimestamp to blockQuery to be able to get the spine block of reference for a spine block manifest (which is the first block with timestamp >= spineBlockManifest.ExpirationTimestamp) * Add blockSpineService-specific method ValidateSpineBlockManifest to validate a spine block manifest after is downloaded from the p2p network * Add unit tests for new methods --- common/query/blockQuery.go | 15 +- common/query/blockQuery_test.go | 88 +++++++++- core/service/blockSpineService.go | 44 +++++ core/service/blockSpineService_test.go | 228 ++++++++++++++++++++++++- main.go | 5 +- 5 files changed, 369 insertions(+), 11 deletions(-) diff --git a/common/query/blockQuery.go b/common/query/blockQuery.go index 44e9dec28..4bc5031fa 100644 --- a/common/query/blockQuery.go +++ b/common/query/blockQuery.go @@ -15,9 +15,10 @@ type ( GetBlocks(height, size uint32) string GetLastBlock() string GetGenesisBlock() string - GetBlockByID(int64) string - GetBlockByHeight(uint32) string - GetBlockFromHeight(uint32, uint32) string + GetBlockByID(id int64) string + GetBlockByHeight(height uint32) string + GetBlockFromHeight(startHeight, limit uint32) string + GetBlockFromTimestamp(startTimestamp int64, limit uint32) string InsertBlock(block *model.Block) (str string, args []interface{}) ExtractModel(block *model.Block) []interface{} BuildModel(blocks []*model.Block, rows *sql.Rows) ([]*model.Block, error) @@ -93,10 +94,16 @@ func (bq *BlockQuery) GetBlockByHeight(height uint32) string { // GetBlockFromHeight returns query string to get blocks from a certain height func (bq *BlockQuery) GetBlockFromHeight(startHeight, limit uint32) string { - return fmt.Sprintf("SELECT %s FROM %s WHERE HEIGHT >= %d ORDER BY HEIGHT LIMIT %d", + return fmt.Sprintf("SELECT %s FROM %s WHERE height >= %d ORDER BY height LIMIT %d", strings.Join(bq.Fields, ", "), bq.getTableName(), startHeight, limit) } +// GetBlockFromHeight returns query string to get blocks from a certain height +func (bq *BlockQuery) GetBlockFromTimestamp(startTimestamp int64, limit uint32) string { + return fmt.Sprintf("SELECT %s FROM %s WHERE timestamp >= %d ORDER BY timestamp LIMIT %d", + strings.Join(bq.Fields, ", "), bq.getTableName(), startTimestamp, limit) +} + // ExtractModel extract the model struct fields to the order of BlockQuery.Fields func (*BlockQuery) ExtractModel(block *model.Block) []interface{} { return []interface{}{ diff --git a/common/query/blockQuery_test.go b/common/query/blockQuery_test.go index 23645d2da..246d8af40 100644 --- a/common/query/blockQuery_test.go +++ b/common/query/blockQuery_test.go @@ -5,10 +5,8 @@ import ( "testing" "github.com/DATA-DOG/go-sqlmock" - - "github.com/zoobc/zoobc-core/common/model" - "github.com/zoobc/zoobc-core/common/chaintype" + "github.com/zoobc/zoobc-core/common/model" ) var ( @@ -249,3 +247,87 @@ func TestBlockQuery_Rollback(t *testing.T) { }) } } + +func TestBlockQuery_GetBlockFromHeight(t *testing.T) { + type fields struct { + Fields []string + TableName string + ChainType chaintype.ChainType + } + type args struct { + startHeight uint32 + limit uint32 + } + tests := []struct { + name string + fields fields + args args + want string + }{ + { + name: "GetBlockFromHeight:success", + fields: fields(*mockBlockQuery), + args: args{ + limit: 1, + startHeight: 1, + }, + want: "SELECT id, block_hash, previous_block_hash, height, timestamp, block_seed, block_signature, " + + "cumulative_difficulty, payload_length, payload_hash, blocksmith_public_key, total_amount, total_fee, " + + "total_coinbase, version FROM main_block WHERE height >= 1 ORDER BY height LIMIT 1", + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + bq := &BlockQuery{ + Fields: tt.fields.Fields, + TableName: tt.fields.TableName, + ChainType: tt.fields.ChainType, + } + if got := bq.GetBlockFromHeight(tt.args.startHeight, tt.args.limit); got != tt.want { + t.Errorf("BlockQuery.GetBlockFromHeight() = %v, want %v", got, tt.want) + } + }) + } +} + +func TestBlockQuery_GetBlockFromTimestamp(t *testing.T) { + type fields struct { + Fields []string + TableName string + ChainType chaintype.ChainType + } + type args struct { + startTimestamp int64 + limit uint32 + } + tests := []struct { + name string + fields fields + args args + want string + }{ + { + name: "GetBlockFromTimestamp:success", + fields: fields(*mockBlockQuery), + args: args{ + limit: 1, + startTimestamp: 15875392, + }, + want: "SELECT id, block_hash, previous_block_hash, height, timestamp, block_seed, block_signature, " + + "cumulative_difficulty, payload_length, payload_hash, blocksmith_public_key, total_amount, total_fee, " + + "total_coinbase, version FROM main_block WHERE timestamp >= 15875392 ORDER BY timestamp LIMIT 1", + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + bq := &BlockQuery{ + Fields: tt.fields.Fields, + TableName: tt.fields.TableName, + ChainType: tt.fields.ChainType, + } + if got := bq.GetBlockFromTimestamp(tt.args.startTimestamp, tt.args.limit); got != tt.want { + t.Errorf("BlockQuery.GetBlockFromTimestamp() = %v, want %v", got, tt.want) + } + }) + } +} diff --git a/core/service/blockSpineService.go b/core/service/blockSpineService.go index 05d437164..62547bfce 100644 --- a/core/service/blockSpineService.go +++ b/core/service/blockSpineService.go @@ -906,3 +906,47 @@ func (bs *BlockSpineService) WillSmith( } return blockchainProcessorLastBlockID, nil } + +func (bs *BlockSpineService) ValidateSpineBlockManifest(spineBlockManifest *model.SpineBlockManifest) error { + var ( + block model.Block + found bool + ) + qry := bs.BlockQuery.GetBlockFromTimestamp(spineBlockManifest.GetExpirationTimestamp(), 1) + row, _ := bs.QueryExecutor.ExecuteSelectRow(qry, false) + if err := bs.BlockQuery.Scan(&block, row); err != nil { + if err != sql.ErrNoRows { + return blocker.NewBlocker(blocker.DBErr, err.Error()) + } + return blocker.NewBlocker(blocker.ValidationErr, "InvalidSpineBlockManifestTimestamp") + } + if err := bs.PopulateBlockData(&block); err != nil { + return err + } + + // first check if spineBlockManifest is included in block data + spineBlockManifestBytes := bs.SpineBlockManifestService.GetSpineBlockManifestBytes(spineBlockManifest) + for _, blSpineBlockManifest := range block.GetSpineBlockManifests() { + blSpineBlockManifestBytes := bs.SpineBlockManifestService.GetSpineBlockManifestBytes(blSpineBlockManifest) + if bytes.Equal(spineBlockManifestBytes, blSpineBlockManifestBytes) { + found = true + break + } + } + if !found { + return blocker.NewBlocker(blocker.ValidationErr, "InvalidSpineBlockManifestData") + } + + // now validate against block payload hash + computedHash, computedLength, err := bs.GetPayloadHashAndLength(&block) + if err != nil { + return err + } + if !bytes.Equal(computedHash, block.GetPayloadHash()) || computedLength != block.PayloadLength { + // in this case it could be that one or more spine block manifest entries have been manually added to db after the block + // has been pushed to db + return blocker.NewBlocker(blocker.ValidationErr, "InvalidComputedSpineBlockPayloadHash") + } + + return nil +} diff --git a/core/service/blockSpineService_test.go b/core/service/blockSpineService_test.go index c91c051e4..94d240ecd 100644 --- a/core/service/blockSpineService_test.go +++ b/core/service/blockSpineService_test.go @@ -106,8 +106,16 @@ type ( mockSpineNodeRegistrationServiceFail struct { NodeRegistrationService } + + mockBlockSpinePublicKeyService struct { + BlockSpinePublicKeyService + } ) +func (*mockBlockSpinePublicKeyService) GetSpinePublicKeysByBlockHeight(height uint32) (spinePublicKeys []*model.SpinePublicKey, err error) { + return nil, nil +} + func (*mockSpineNodeRegistrationServiceSuccess) AddParticipationScore( nodeID, scoreDelta int64, height uint32, @@ -1282,8 +1290,9 @@ type ( } mockSpineBlockManifestService struct { SpineBlockManifestService - ResSpineBlockManifests []*model.SpineBlockManifest - ResError error + ResSpineBlockManifests []*model.SpineBlockManifest + ResError error + ResSpineBlockManifestBytes []byte } ) @@ -3585,7 +3594,7 @@ type ( ) func (*mockSpineExecutorPopulateBlockDataFail) ExecuteSelect(qStr string, tx bool, args ...interface{}) (*sql.Rows, error) { - return nil, errors.New("Mock Error") + return nil, errors.New("MockError") } func (*mockSpineExecutorPopulateBlockDataSuccess) ExecuteSelect(qStr string, tx bool, args ...interface{}) (*sql.Rows, error) { @@ -3707,3 +3716,216 @@ func TestBlockSpineService_PopulateBlockData(t *testing.T) { }) } } + +type ( + mockSpineExecutorValidateSpineBlockManifest struct { + query.Executor + success bool + noRows bool + } +) + +func (msExQ *mockSpineExecutorValidateSpineBlockManifest) ExecuteSelectRow(qStr string, tx bool, args ...interface{}) (*sql.Row, error) { + db, mock, _ := sqlmock.New() + defer db.Close() + + if !msExQ.success { + return nil, errors.New("ExecuteSelectRowFailed") + } + if msExQ.noRows { + mock.ExpectQuery(regexp.QuoteMeta(qStr)).WillReturnRows(sqlmock.NewRows(query.NewBlockQuery(&chaintype.SpineChain{}).Fields)) + } + switch qStr { + case "SELECT id, block_hash, previous_block_hash, height, timestamp, block_seed, block_signature, cumulative_difficulty, " + + "payload_length, payload_hash, blocksmith_public_key, total_amount, total_fee, total_coinbase, " + + "version FROM spine_block WHERE timestamp >= 15875392 ORDER BY timestamp LIMIT 1": + mock.ExpectQuery(regexp.QuoteMeta(qStr)).WillReturnRows(sqlmock.NewRows(query.NewBlockQuery(&chaintype.SpineChain{}).Fields). + AddRow( + mockSpineBlockData.GetID(), + mockSpineBlockData.GetBlockHash(), + mockSpineBlockData.GetPreviousBlockHash(), + mockSpineBlockData.GetHeight(), + mockSpineBlockData.GetTimestamp(), + mockSpineBlockData.GetBlockSeed(), + mockSpineBlockData.GetBlockSignature(), + mockSpineBlockData.GetCumulativeDifficulty(), + uint32(8), + []byte{28, 122, 181, 212, 11, 147, 147, 173, 220, 102, 150, 8, 100, 164, 82, 120, 228, 253, 53, 160, 5, 21, + 103, 1, 127, 243, 215, 57, 88, 97, 137, 113}, + mockSpineBlockData.GetBlocksmithPublicKey(), + mockSpineBlockData.GetTotalAmount(), + mockSpineBlockData.GetTotalFee(), + mockSpineBlockData.GetTotalCoinBase(), + mockSpineBlockData.GetVersion(), + )) + default: + return nil, errors.New("UnmockedQuery") + } + row := db.QueryRow(qStr) + return row, nil +} + +func (ss *mockSpineBlockManifestService) GetSpineBlockManifestBytes(spineBlockManifest *model.SpineBlockManifest) []byte { + if spineBlockManifest.ID == 12345678 || ss.ResSpineBlockManifestBytes != nil { + return ss.ResSpineBlockManifestBytes + } + return []byte{} +} + +func TestBlockSpineService_ValidateSpineBlockManifest(t *testing.T) { + type fields struct { + RWMutex sync.RWMutex + Chaintype chaintype.ChainType + QueryExecutor query.ExecutorInterface + BlockQuery query.BlockQueryInterface + Signature crypto.SignatureInterface + BlocksmithStrategy strategy.BlocksmithStrategyInterface + Observer *observer.Observer + Logger *log.Logger + SpinePublicKeyService BlockSpinePublicKeyServiceInterface + SpineBlockManifestService SpineBlockManifestServiceInterface + } + type args struct { + spineBlockManifest *model.SpineBlockManifest + } + tests := []struct { + name string + fields fields + args args + wantErr bool + }{ + { + name: "ValidateSpineBlockManifest:success", + fields: fields{ + QueryExecutor: &mockSpineExecutorValidateSpineBlockManifest{ + success: true, + }, + BlockQuery: query.NewBlockQuery(&chaintype.SpineChain{}), + Logger: logrus.New(), + SpinePublicKeyService: &mockBlockSpinePublicKeyService{}, + SpineBlockManifestService: &mockSpineBlockManifestService{ + ResSpineBlockManifestBytes: []byte{1, 1, 1, 1, 1, 1, 1, 1}, + ResSpineBlockManifests: []*model.SpineBlockManifest{ + { + ID: 12345678, + FullFileHash: make([]byte, 64), + FileChunkHashes: make([]byte, 0), + SpineBlockManifestHeight: 720, + SpineBlockManifestType: model.SpineBlockManifestType_Snapshot, + ExpirationTimestamp: int64(1000), + }, + }, + }, + }, + args: args{ + spineBlockManifest: &model.SpineBlockManifest{ + ID: 12345678, + ExpirationTimestamp: 15875392, + }, + }, + wantErr: false, + }, + { + name: "ValidateSpineBlockManifest:fail-{InvalidSpineBlockManifestTimestamp}", + fields: fields{ + QueryExecutor: &mockSpineExecutorValidateSpineBlockManifest{ + success: true, + noRows: true, + }, + BlockQuery: query.NewBlockQuery(&chaintype.SpineChain{}), + Logger: logrus.New(), + SpinePublicKeyService: &mockBlockSpinePublicKeyService{}, + SpineBlockManifestService: &mockSpineBlockManifestService{ + ResSpineBlockManifestBytes: []byte{1, 1, 1, 1, 1, 1, 1, 1}, + ResSpineBlockManifests: []*model.SpineBlockManifest{ + { + ID: 12345678, + SpineBlockManifestType: model.SpineBlockManifestType_Snapshot, + ExpirationTimestamp: int64(1000), + }, + }, + }, + }, + args: args{ + spineBlockManifest: &model.SpineBlockManifest{ + ID: 12345678, + ExpirationTimestamp: 15875392, + }, + }, + wantErr: true, + }, + { + name: "ValidateSpineBlockManifest:fail-{InvalidSpineBlockManifestData}", + fields: fields{ + QueryExecutor: &mockSpineExecutorValidateSpineBlockManifest{ + success: true, + }, + BlockQuery: query.NewBlockQuery(&chaintype.SpineChain{}), + Logger: logrus.New(), + SpinePublicKeyService: &mockBlockSpinePublicKeyService{}, + SpineBlockManifestService: &mockSpineBlockManifestService{ + ResSpineBlockManifestBytes: []byte{1, 1, 1, 1, 1, 1, 1, 1}, + }, + }, + args: args{ + spineBlockManifest: &model.SpineBlockManifest{ + ID: 11111111, + ExpirationTimestamp: 15875392, + }, + }, + wantErr: true, + }, + { + name: "ValidateSpineBlockManifest:fail-{InvalidComputedSpineBlockPayloadHash}", + fields: fields{ + QueryExecutor: &mockSpineExecutorValidateSpineBlockManifest{ + success: true, + }, + BlockQuery: query.NewBlockQuery(&chaintype.SpineChain{}), + Logger: logrus.New(), + SpinePublicKeyService: &mockBlockSpinePublicKeyService{}, + SpineBlockManifestService: &mockSpineBlockManifestService{ + ResSpineBlockManifestBytes: []byte{1, 1, 1, 1, 1, 1, 1, 1}, + ResSpineBlockManifests: []*model.SpineBlockManifest{ + { + ID: 11111111, + SpineBlockManifestType: model.SpineBlockManifestType_Snapshot, + ExpirationTimestamp: int64(1000), + }, + { + ID: 22222222, + SpineBlockManifestType: model.SpineBlockManifestType_Snapshot, + ExpirationTimestamp: int64(1000), + }, + }, + }, + }, + args: args{ + spineBlockManifest: &model.SpineBlockManifest{ + ID: 11111111, + ExpirationTimestamp: 15875392, + }, + }, + wantErr: true, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + bs := &BlockSpineService{ + RWMutex: tt.fields.RWMutex, + Chaintype: tt.fields.Chaintype, + QueryExecutor: tt.fields.QueryExecutor, + BlockQuery: tt.fields.BlockQuery, + Signature: tt.fields.Signature, + BlocksmithStrategy: tt.fields.BlocksmithStrategy, + Observer: tt.fields.Observer, + Logger: tt.fields.Logger, + SpinePublicKeyService: tt.fields.SpinePublicKeyService, + SpineBlockManifestService: tt.fields.SpineBlockManifestService, + } + if err := bs.ValidateSpineBlockManifest(tt.args.spineBlockManifest); (err != nil) != tt.wantErr { + t.Errorf("BlockSpineService.ValidateSpineBlockManifest() error = %v, wantErr %v", err, tt.wantErr) + } + }) + } +} diff --git a/main.go b/main.go index 654b9d4be..8f664a297 100644 --- a/main.go +++ b/main.go @@ -802,7 +802,10 @@ func startBlockchainSyncronizers() { ct.GetName()) break } - if lastSpineBlockManifest != nil { + err = spinechainBlockService.ValidateSpineBlockManifest(lastSpineBlockManifest) + loggerCoreService.Errorf("Invalid spineBlockManifest for chaintype %s Snapshot won't be downloaded. %s", + ct.GetName(), err) + if lastSpineBlockManifest != nil && err == nil { loggerCoreService.Infof("found a Snapshot Spine Block Manifest for chaintype %s, "+ "at height is %d. Start downloading...", ct.GetName(), lastSpineBlockManifest.SpineBlockManifestHeight) From a2f7ee7958624dc03f1767b2e2c6f740c31823fc Mon Sep 17 00:00:00 2001 From: stefano galassi Date: Mon, 9 Mar 2020 18:33:02 +0800 Subject: [PATCH 05/11] Merge remote-tracking branch 'origin/develop' into 627-spine-block-manifest-publickeys-validation # Conflicts: # core/service/blockMainService.go --- go.mod | 64 +++++++--------------- go.sum | 165 ++++++++++++++++++++++++++++++++++----------------------- 2 files changed, 117 insertions(+), 112 deletions(-) diff --git a/go.mod b/go.mod index 63a432de5..eab26ce92 100644 --- a/go.mod +++ b/go.mod @@ -1,54 +1,28 @@ module github.com/zoobc/zoobc-core -go 1.12 +go 1.14 require ( - github.com/AndreasBriese/bbloom v0.0.0-20190825152654-46b345b51c96 - github.com/DATA-DOG/go-sqlmock v1.3.3 - github.com/StackExchange/wmi v0.0.0-20180116203802-5d049714c4a6 - github.com/beorn7/perks v1.0.1 + github.com/DATA-DOG/go-sqlmock v1.4.1 + github.com/StackExchange/wmi v0.0.0-20190523213315-cbe66965904d // indirect github.com/btcsuite/btcd v0.20.1-beta - github.com/btcsuite/btcutil v0.0.0-20190425235716-9e5f4b9a998d + github.com/btcsuite/btcutil v1.0.1 github.com/dgraph-io/badger v1.6.0 - github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2 - github.com/dustin/go-humanize v1.0.0 - github.com/fsnotify/fsnotify v1.4.7 - github.com/go-ole/go-ole v1.2.4 - github.com/golang/mock v1.3.1-0.20190508161146-9fa652df1129 - github.com/golang/protobuf v1.3.2 - github.com/google/go-cmp v0.3.1 - github.com/grpc-ecosystem/grpc-gateway v1.11.3 - github.com/hashicorp/hcl v1.0.0 - github.com/inconshreveable/mousetrap v1.0.0 - github.com/konsorten/go-windows-terminal-sequences v1.0.2 - github.com/magiconair/properties v1.8.1 - github.com/mattn/go-sqlite3 v1.11.0 - github.com/matttproud/golang_protobuf_extensions v1.0.1 - github.com/mitchellh/mapstructure v1.1.2 - github.com/mmcloughlin/avo v0.0.0-20190927041150-15d6a9a17e53 - github.com/pelletier/go-toml v1.5.0 - github.com/pkg/errors v0.8.1 - github.com/prometheus/client_golang v1.1.0 - github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4 - github.com/prometheus/common v0.7.0 - github.com/prometheus/procfs v0.0.5 - github.com/shirou/gopsutil v2.19.9+incompatible - github.com/shirou/w32 v0.0.0-20160930032740-bb4de0191aa4 + github.com/go-ole/go-ole v1.2.4 // indirect + github.com/golang/mock v1.4.1 + github.com/golang/protobuf v1.3.4 + github.com/google/go-cmp v0.4.0 + github.com/grpc-ecosystem/grpc-gateway v1.14.1 + github.com/mattn/go-sqlite3 v2.0.3+incompatible + github.com/pkg/errors v0.9.1 + github.com/prometheus/client_golang v1.5.0 + github.com/shirou/gopsutil v2.20.2+incompatible github.com/sirupsen/logrus v1.4.2 - github.com/spf13/afero v1.2.2 - github.com/spf13/cast v1.3.0 - github.com/spf13/cobra v0.0.5 - github.com/spf13/jwalterweatherman v1.1.0 - github.com/spf13/pflag v1.0.5 - github.com/spf13/viper v1.4.0 - github.com/tyler-smith/go-bip39 v0.0.0-20190808214741-c55f737395bc + github.com/spf13/cobra v0.0.6 + github.com/spf13/viper v1.6.2 + github.com/tyler-smith/go-bip39 v1.0.2 github.com/ugorji/go/codec v1.1.7 - golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550 - golang.org/x/net v0.0.0-20191021144547-ec77196f6094 - golang.org/x/sys v0.0.0-20191025021431-6c3a3bfe00ae - golang.org/x/text v0.3.2 - golang.org/x/tools v0.0.0-20200124013708-a4b4a6733aae - google.golang.org/genproto v0.0.0-20191009194640-548a555dbc03 - google.golang.org/grpc v1.24.0 - gopkg.in/yaml.v2 v2.2.4 + golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073 + google.golang.org/genproto v0.0.0-20200306153348-d950eab6f860 + google.golang.org/grpc v1.27.0 ) diff --git a/go.sum b/go.sum index a8043ba9d..b84698b66 100644 --- a/go.sum +++ b/go.sum @@ -1,19 +1,20 @@ cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +github.com/AndreasBriese/bbloom v0.0.0-20190306092124-e2d15f34fcf9 h1:HD8gA2tkByhMAwYaFAX9w2l7vxvBQ5NMoxDrkhqhtn4= github.com/AndreasBriese/bbloom v0.0.0-20190306092124-e2d15f34fcf9/go.mod h1:bOvUY6CB00SOBii9/FifXqc0awNKxLFCL/+pkDPuyl8= -github.com/AndreasBriese/bbloom v0.0.0-20190825152654-46b345b51c96 h1:cTp8I5+VIoKjsnZuH8vjyaysT/ses3EvZeaV/1UkF2M= -github.com/AndreasBriese/bbloom v0.0.0-20190825152654-46b345b51c96/go.mod h1:bOvUY6CB00SOBii9/FifXqc0awNKxLFCL/+pkDPuyl8= +github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= -github.com/DATA-DOG/go-sqlmock v1.3.3 h1:CWUqKXe0s8A2z6qCgkP4Kru7wC11YoAnoupUKFDnH08= -github.com/DATA-DOG/go-sqlmock v1.3.3/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM= +github.com/DATA-DOG/go-sqlmock v1.4.1 h1:ThlnYciV1iM/V0OSF/dtkqWb6xo5qITT1TJBG1MRDJM= +github.com/DATA-DOG/go-sqlmock v1.4.1/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= -github.com/StackExchange/wmi v0.0.0-20180116203802-5d049714c4a6 h1:fLjPD/aNc3UIOA6tDi6QXUemppXK3P9BI7mr2hd6gx8= -github.com/StackExchange/wmi v0.0.0-20180116203802-5d049714c4a6/go.mod h1:3eOhrUMpNV+6aFIbp5/iudMxNCF27Vw2OZgy4xEx0Fg= +github.com/StackExchange/wmi v0.0.0-20190523213315-cbe66965904d h1:G0m3OIz70MZUWq3EgK3CesDbo8upS2Vm9/P3FtgI+Jk= +github.com/StackExchange/wmi v0.0.0-20190523213315-cbe66965904d/go.mod h1:3eOhrUMpNV+6aFIbp5/iudMxNCF27Vw2OZgy4xEx0Fg= github.com/aead/siphash v1.0.1 h1:FwHfE/T45KPKYuuSAKyyvE+oPWcaQ+CUmFW0bPlM+kg= github.com/aead/siphash v1.0.1/go.mod h1:Nywa3cDsYNNK3gaciGTWPwHt0wlpNV15vwmswBAUSII= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= +github.com/antihax/optional v0.0.0-20180407024304-ca021399b1a6/go.mod h1:V8iCPQYkqmusNa815XgQio277wI47sdRh1dUOLdyC6Q= github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= @@ -25,6 +26,8 @@ github.com/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f h1:bAs4lUbRJpnnkd9 github.com/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f/go.mod h1:TdznJufoqS23FtqVCzL0ZqgP5MqXbb4fg/WgDys70nA= github.com/btcsuite/btcutil v0.0.0-20190425235716-9e5f4b9a998d h1:yJzD/yFppdVCf6ApMkVy8cUxV0XrxdP9rVf6D87/Mng= github.com/btcsuite/btcutil v0.0.0-20190425235716-9e5f4b9a998d/go.mod h1:+5NJ2+qvTyV9exUAL/rxXi3DcLg2Ts+ymUAY5y4NvMg= +github.com/btcsuite/btcutil v1.0.1 h1:GKOz8BnRjYrb/JTKgaOk+zh26NWNdSNvdvv0xoAZMSA= +github.com/btcsuite/btcutil v1.0.1/go.mod h1:j9HUFwoQRsZL3V4n+qG+CUnEGHOarIxfC3Le2Yhbcts= github.com/btcsuite/go-socks v0.0.0-20170105172521-4720035b7bfd h1:R/opQEbFEy9JGkIguV40SvRY1uliPX8ifOvi6ICsFCw= github.com/btcsuite/go-socks v0.0.0-20170105172521-4720035b7bfd/go.mod h1:HHNXQzUsZCxOoE+CPiyCTO6x34Zs86zZUiwtpXoGdtg= github.com/btcsuite/goleveldb v0.0.0-20160330041536-7834afc9e8cd h1:qdGvebPBDuYDPGi1WCPjy1tGyMpmDK8IEapSsszn7HE= @@ -34,7 +37,11 @@ github.com/btcsuite/snappy-go v0.0.0-20151229074030-0bdef8d06723/go.mod h1:8woku github.com/btcsuite/websocket v0.0.0-20150119174127-31079b680792 h1:R8vQdOQdZ9Y3SkEwmHoWBmX1DNXhXZqlTpq6s4tyJGc= github.com/btcsuite/websocket v0.0.0-20150119174127-31079b680792/go.mod h1:ghJtEyQwv5/p4Mg4C0fgbePVuGr935/5ddU9Z3TmDRY= github.com/btcsuite/winsvc v1.0.0/go.mod h1:jsenWakMcC0zFBFurPLEAyrnc/teJEM1O46fmI40EZs= +github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= +github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko= github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= +github.com/cespare/xxhash/v2 v2.1.1 h1:6MnRN8NT7+YBpUIWxHtefFZOKTAPgGjpQSxqLNn0+qY= +github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= @@ -43,6 +50,7 @@ github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3Ee github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= +github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= github.com/davecgh/go-spew v0.0.0-20171005155431-ecdeabc65495/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= @@ -55,6 +63,8 @@ github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2/go.mod h1:SqUrOPUn github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no= github.com/dustin/go-humanize v1.0.0 h1:VSnTsYCnlFHaM2/igO1h6X3HA71jcobQuxemgkq4zYo= github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= +github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= @@ -67,29 +77,35 @@ github.com/go-ole/go-ole v1.2.4/go.mod h1:XCwSNxSkXRo4vlyPy93sltvi/qJq0jqQhjqQNI github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= +github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/mock v0.0.0-20190508161146-9fa652df1129/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= github.com/golang/mock v1.1.1 h1:G5FRp8JnTd7RQH5kemVNlMeyXQAztQ3mOWV95KxsXH8= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= -github.com/golang/mock v1.3.1-0.20190508161146-9fa652df1129 h1:tT8iWCYw4uOem71yYA3htfH+LNopJvcqZQshm56G5L4= -github.com/golang/mock v1.3.1-0.20190508161146-9fa652df1129/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= +github.com/golang/mock v1.4.1 h1:ocYkMQY5RrXTYgXl7ICpV0IXwlEQGwKIsery4gyXa1U= +github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.2 h1:6nsPYzhq5kReh6QImI3k5qWzO4PEbvbIW2cwSfR/6xs= github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= +github.com/golang/protobuf v1.3.4 h1:87PNWwrRvUSnqS4dlcBU/ftvOIBep4sYuBLlh6rX2wk= +github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= -github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1 h1:Xye71clBPdm5HgqGwUkwhbynsUJZhDbS20FvLhQ2izg= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.4.0 h1:xsAVV57WRhGj6kEIi8ReJzQlHHqcBYCElAvkovg3B/4= +github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8= +github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= -github.com/grpc-ecosystem/grpc-gateway v1.11.3 h1:h8+NsYENhxNTuq+dobk3+ODoJtwY4Fu0WQXsxJfL8aM= -github.com/grpc-ecosystem/grpc-gateway v1.11.3/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= +github.com/grpc-ecosystem/grpc-gateway v1.14.1 h1:YuM9SXYy583fxvSOkzCDyBPCtY+/IMSHEG1dKFMLZsA= +github.com/grpc-ecosystem/grpc-gateway v1.14.1/go.mod h1:6CwZWGDSPRJidgKAtJVvND6soZe6fT7iteq8wDPdhb0= github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= @@ -101,30 +117,32 @@ github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22 github.com/jrick/logrotate v1.0.0 h1:lQ1bL/n9mBNeIXoTUoYRlK4dHuNJVofX9oWqBtPnSzI= github.com/jrick/logrotate v1.0.0/go.mod h1:LNinyqDIJnpAur+b8yyulnQw/wDuN1+BYKlTRt3OuAQ= github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= -github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo= +github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/kkdai/bstream v0.0.0-20161212061736-f391b8402d23 h1:FOOIBWrEkLgmlgGfMuZT83xIwfPDxEI2OHu6xUmJMFE= github.com/kkdai/bstream v0.0.0-20161212061736-f391b8402d23/go.mod h1:J+Gs4SYgM6CZQHDETBtE9HaSEkGmuNXF86RwHhHUvq4= +github.com/konsorten/go-windows-terminal-sequences v1.0.1 h1:mweAR1A6xJ3oS2pRaGiHgQ4OO8tzTaLawm8vnODuwDk= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= -github.com/konsorten/go-windows-terminal-sequences v1.0.2 h1:DB17ag19krx9CFsz4o3enTrPXyIXCl+2iCXH/aMAp9s= -github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= +github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= github.com/magiconair/properties v1.8.1 h1:ZC2Vc7/ZFkGmsVC9KvOjumD+G5lXy2RtTKyzRKO2BQ4= github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= -github.com/mattn/go-sqlite3 v1.11.0 h1:LDdKkqtYlom37fkvqs8rMPFKAMe8+SgjbwZ6ex1/A/Q= -github.com/mattn/go-sqlite3 v1.11.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= +github.com/mattn/go-sqlite3 v2.0.3+incompatible h1:gXHsfypPkaMZrKbD5209QV9jbUTJKjyR5WD3HYQSd+U= +github.com/mattn/go-sqlite3 v2.0.3+incompatible/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQzvN1EDeE= github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= -github.com/mmcloughlin/avo v0.0.0-20190927041150-15d6a9a17e53/go.mod h1:L0u9qfRMLNBO97u6pPukRp6ncoQz0Q25W69fvtht3vA= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= @@ -134,71 +152,82 @@ github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= +github.com/pelletier/go-toml v1.2.0 h1:T5zMGML61Wp+FlcbWjRDT7yAxhJNAiPPLOFECq181zc= github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= -github.com/pelletier/go-toml v1.5.0 h1:5BakdOZdtKJ1FFk6QdL8iSGrMWsXgchNJcrnarjbmJQ= -github.com/pelletier/go-toml v1.5.0/go.mod h1:5N711Q9dKgbdkxHL+MEfF31hpT7l0S0s/t2kKREewys= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso= github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= -github.com/prometheus/client_golang v1.1.0 h1:BQ53HtBmfOitExawJ6LokA4x8ov/z0SYYb0+HxJfRI8= -github.com/prometheus/client_golang v1.1.0/go.mod h1:I1FGZT9+L76gKKOs5djB6ezCbFQP1xR9D75/vuwEF3g= +github.com/prometheus/client_golang v1.5.0 h1:Ctq0iGpCmr3jeP77kbF2UxgvRwzWWz+4Bh9/vJTyg1A= +github.com/prometheus/client_golang v1.5.0/go.mod h1:e9GMxYsXl05ICDXkRhurwBS4Q3OK1iX/F2sw+iXX5zU= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4 h1:gQz4mCbXsO+nc9n1hCxHcGA3Zx3Eo+UHZoInFGUIXNM= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/client_model v0.2.0 h1:uq5h0d+GuxiXLJLNABMgp2qUWDPiLvgCzz2dUR+/W/M= +github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= -github.com/prometheus/common v0.6.0/go.mod h1:eBmuwkDJBwy6iBfxCBob6t6dR6ENT/y+J+Zk0j9GMYc= -github.com/prometheus/common v0.7.0 h1:L+1lyG48J1zAQXA3RBX/nG/B3gjlHq0zTt2tlbJLyCY= -github.com/prometheus/common v0.7.0/go.mod h1:DjGbpBbp5NYNiECxcL/VnbXCCaQpKd3tt26CguLLsqA= +github.com/prometheus/common v0.9.1 h1:KOMtN28tlbam3/7ZKEYKHhKoJZYYj3gMH4uc62x7X7U= +github.com/prometheus/common v0.9.1/go.mod h1:yhUN8i9wzaXS3w1O07YhxHEBxD+W35wd8bs7vj7HSQ4= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= -github.com/prometheus/procfs v0.0.3/go.mod h1:4A/X28fw3Fc593LaREMrKMqOKvUAntwMDaekg4FpcdQ= -github.com/prometheus/procfs v0.0.5 h1:3+auTFlqw+ZaQYJARz6ArODtkaIwtvBTx3N2NehQlL8= -github.com/prometheus/procfs v0.0.5/go.mod h1:4A/X28fw3Fc593LaREMrKMqOKvUAntwMDaekg4FpcdQ= +github.com/prometheus/procfs v0.0.8 h1:+fpWZdT24pJBiqJdAwYBjPSk+5YmQzYNPYzQsdzLkt8= +github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A= github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= +github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= -github.com/shirou/gopsutil v2.19.9+incompatible h1:IrPVlK4nfwW10DF7pW+7YJKws9NkgNzWozwwWv9FsgY= -github.com/shirou/gopsutil v2.19.9+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA= -github.com/shirou/w32 v0.0.0-20160930032740-bb4de0191aa4 h1:udFKJ0aHUL60LboW/A+DfgoHVedieIzIXE8uylPue0U= -github.com/shirou/w32 v0.0.0-20160930032740-bb4de0191aa4/go.mod h1:qsXQc7+bwAM3Q1u/4XEfrquwF8Lw7D7y5cD8CuHnfIc= +github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/shirou/gopsutil v2.20.2+incompatible h1:ucK79BhBpgqQxPASyS2cu9HX8cfDVljBN1WWFvbNvgY= +github.com/shirou/gopsutil v2.20.2+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA= +github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/sirupsen/logrus v1.4.2 h1:SPIRibHv4MatM3XXNO2BJeFLZwZ2LvZgfQ5+UNI2im4= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= +github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM= +github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= +github.com/smartystreets/goconvey v1.6.4 h1:fv0U8FUIMPNf1L9lnHLvLhgicrIVChEkdzIKYqbNC9s= +github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= +github.com/spf13/afero v1.1.2 h1:m8/z1t7/fwjysjQRYbP0RD+bUIF/8tJwPdEZsI83ACI= github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= -github.com/spf13/afero v1.2.2 h1:5jhuqJyZCZf2JRofRvN/nIFgIWNzPa3/Vz8mYylgbWc= -github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk= github.com/spf13/cast v1.3.0 h1:oget//CVOEoFewqQxwr0Ej5yjygnqGkvggSE/gB35Q8= github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= github.com/spf13/cobra v0.0.5 h1:f0B+LkLX6DtmRH1isoNA9VTtNUK9K8xYd28JNNfOv/s= github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU= +github.com/spf13/cobra v0.0.6 h1:breEStsVwemnKh2/s6gMvSdMEkwW0sK8vGStnlVBMCs= +github.com/spf13/cobra v0.0.6/go.mod h1:/6GTrnGXV9HjY+aR4k0oJ5tcvakLuG6EuKReYlHNrgE= +github.com/spf13/jwalterweatherman v1.0.0 h1:XHEdyB+EcvlqZamSM4ZOMGlc93t6AcsBEu9Gc1vn7yk= github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= -github.com/spf13/jwalterweatherman v1.1.0 h1:ue6voC5bR5F8YxI5S67j9i582FU4Qvo2bmqnqMYADFk= -github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo= +github.com/spf13/pflag v1.0.3 h1:zPAT6CGy6wXeQ7NtTnaTerfKOsV6V6F8agHXFiazDkg= github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= -github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= -github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s= github.com/spf13/viper v1.4.0 h1:yXHLWeravcrgGyFSyCgdYpXQ9dR9c/WED3pg1RhxqEU= github.com/spf13/viper v1.4.0/go.mod h1:PTJ7Z/lr49W6bUbkmS1V3by4uWynFiR9p7+dSq/yZzE= +github.com/spf13/viper v1.6.2 h1:7aKfF+e8/k68gda3LOjo5RxiUqddoFxVq4BKBPrxk5E= +github.com/spf13/viper v1.6.2/go.mod h1:t3iDnF5Jlj76alVNuyFBk5oUMCvsrkbvZK0WQdfDi5k= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk= +github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= +github.com/subosito/gotenv v1.2.0 h1:Slr1R9HxAlEKefgq5jn9U+DnETlIUa6HfgEzj0g5d7s= +github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= -github.com/tyler-smith/go-bip39 v0.0.0-20190808214741-c55f737395bc h1:IQziJgvy3j6NMoUGlqtLRuCEk3xQpjhFgATvh3srhz4= -github.com/tyler-smith/go-bip39 v0.0.0-20190808214741-c55f737395bc/go.mod h1:sJ5fKU0s6JVwZjjcUEX2zFOnvq0ASQ2K9Zr6cf67kNs= +github.com/tyler-smith/go-bip39 v1.0.2 h1:+t3w+KwLXO6154GNJY+qUtIxLTmFjfUmpguQT1OlOT8= +github.com/tyler-smith/go-bip39 v1.0.2/go.mod h1:sJ5fKU0s6JVwZjjcUEX2zFOnvq0ASQ2K9Zr6cf67kNs= github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc= github.com/ugorji/go v1.1.7 h1:/68gy2h+1mWMrwZFeD1kQialdSzAb432dtpeJ42ovdo= github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw= @@ -211,19 +240,17 @@ go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= -golang.org/x/arch v0.0.0-20190909030613-46d78d1859ac/go.mod h1:flIaEI6LNU6xOCD5PaJvn9wGP0agmIOqjrtsKGRguv4= golang.org/x/crypto v0.0.0-20170930174604-9419663f5a44/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550 h1:ObdrDkeb4kJdCP557AjRjq69pTHfNouLtWZG7j9rPN8= -golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20200221231518-2aa609cf4a9d h1:1ZiEyfaQIg3Qh0EoqpwAakHVhecoE5wlSg5GjnafJGw= +golang.org/x/crypto v0.0.0-20200115085410-6d4e4cb37c7d/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073 h1:xMPOj6Pz6UipU1wXLkrtqpHbR0AVFnyPEQq/wRWz9lM= +golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -235,13 +262,14 @@ golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn golang.org/x/net v0.0.0-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20191021144547-ec77196f6094 h1:5O4U9trLjNpuhpynaDsqwCk+Tw6seqJz1EbqbnzHrc8= -golang.org/x/net v0.0.0-20191021144547-ec77196f6094/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20191002035440-2ec189313ef0 h1:2mqDk8w/o6UmeUCu5Qiq2y7iMf6anbx+YA8d1JFoFrs= +golang.org/x/net v0.0.0-20191002035440-2ec189313ef0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -252,51 +280,54 @@ golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5h golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190626221950-04f50cda93cb/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190801041406-cbf593c0f2f3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191025021431-6c3a3bfe00ae h1:QoJmnb9uyPCrH8GIg9uRLn4Ta45yhcQtpymCd0AavO8= -golang.org/x/sys v0.0.0-20191025021431-6c3a3bfe00ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200122134326-e047566fdf82 h1:ywK/j/KkyTHcdyYSZNXGjMwgmDSfjglYZ3vStQ/gSCU= +golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs= -golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= -golang.org/x/tools v0.0.0-20190914235951-31e00f45c22e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191025023517-2077df36852e h1:ejUPpxsbZzyShOEURCSvFIT0ltnmBW92Vsc3i8QRcw8= -golang.org/x/tools v0.0.0-20191025023517-2077df36852e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20200123022218-593de606220b h1:ztSlcncMErSAUzXwnVO1iTPxHwtvOHBB26SGiyYXIEE= -golang.org/x/tools v0.0.0-20200123022218-593de606220b/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200124000348-5ecc1643ff52 h1:qcflTWncI+2hZ23p9/UXHxFTa6PdbD2/bx5QmtHCFFM= -golang.org/x/tools v0.0.0-20200124000348-5ecc1643ff52/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200124013708-a4b4a6733aae h1:Qne8kdVxnc6C1freDlPRw9dyI/FXMDNX25Anv4GFhl0= -golang.org/x/tools v0.0.0-20200124013708-a4b4a6733aae/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= -google.golang.org/genproto v0.0.0-20191009194640-548a555dbc03 h1:4HYDjxeNXAOTv3o1N2tjo8UUSlhQgAD52FVkwxnWgM8= -google.golang.org/genproto v0.0.0-20191009194640-548a555dbc03/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/genproto v0.0.0-20190927181202-20e1ac93f88c/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= +google.golang.org/genproto v0.0.0-20200306153348-d950eab6f860 h1:QmnwU8dKvY8c/vZikd2jhBNwrrGS5qeyK/2Aeeh9Grk= +google.golang.org/genproto v0.0.0-20200306153348-d950eab6f860/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= +google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.24.0 h1:vb/1TCsVn3DcJlQ0Gs1yB1pKI6Do2/QNwxdKqmc/b0s= google.golang.org/grpc v1.24.0/go.mod h1:XDChyiUovWa60DnaeDeZmSW86xtLtjtZbwvSiRnRtcA= +google.golang.org/grpc v1.27.0 h1:rRYRFMVgRv6E0D70Skyfsr28tDXIuuPZyWGMPdMcnXg= +google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo= +gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= +gopkg.in/ini.v1 v1.51.0 h1:AQvPpx3LzTDM0AjnIRlVFwFFGC+npRopjZxLJj6gdno= +gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74= gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.4 h1:/eiJrUcujPVeJ3xlSWaiNi3uSVmDGBK1pDHUHAnao1I= gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.5 h1:ymVxjfMaHvXD8RqPRmzHHsB3VvucivSkIAvJFDI5O3c= +gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4= +rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= +rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= From dff310ed8ef7d4c172f5054fe2e918441421130f Mon Sep 17 00:00:00 2001 From: stefano galassi Date: Tue, 10 Mar 2020 10:10:49 +0800 Subject: [PATCH 06/11] Code Refactoring * Update genesis block ID after changes to Generate block (added published receipts to payload length) * Add unit test for validateblockhash --- common/constant/blockchainSync.go | 5 +- common/constant/genesis.go | 2 +- common/constant/snapshot.go | 2 +- core/service/blockMainService_test.go | 145 ++++++++++++++++++++++++++ 4 files changed, 150 insertions(+), 4 deletions(-) diff --git a/common/constant/blockchainSync.go b/common/constant/blockchainSync.go index 34e400af2..e7cf03383 100644 --- a/common/constant/blockchainSync.go +++ b/common/constant/blockchainSync.go @@ -11,6 +11,7 @@ const ( PeerGetBlocksLimit uint32 = 1440 CommonMilestoneBlockIdsLimit int32 = 10 SafeBlockGap uint32 = 1440 - MinRollbackBlocks uint32 = 720 - MaxCommonMilestoneRequestTrial uint32 = MinRollbackBlocks/uint32(CommonMilestoneBlockIdsLimit) + 1 + // @iltoga change this to 2 for testing snapshots + MinRollbackBlocks uint32 = 720 // production 720 + MaxCommonMilestoneRequestTrial uint32 = MinRollbackBlocks/uint32(CommonMilestoneBlockIdsLimit) + 1 ) diff --git a/common/constant/genesis.go b/common/constant/genesis.go index 853a86245..2004baa16 100644 --- a/common/constant/genesis.go +++ b/common/constant/genesis.go @@ -3,7 +3,7 @@ package constant const ( - MainchainGenesisBlockID int64 = 3638197708165910115 + MainchainGenesisBlockID int64 = 1070983609761144356 ) type ( diff --git a/common/constant/snapshot.go b/common/constant/snapshot.go index 48ac2bf00..8154c5d98 100644 --- a/common/constant/snapshot.go +++ b/common/constant/snapshot.go @@ -12,5 +12,5 @@ const ( // @iltoga reduce to 1 for testing locally SnapshotChunkSize int = int(100 * 1024) // 10 KB // DownloadSnapshotNumberOfRetries number of times to retry downloading failed snapshot file chunks from other peers - DownloadSnapshotNumberOfRetries uint32 = 3 + DownloadSnapshotNumberOfRetries uint32 = 5 ) diff --git a/core/service/blockMainService_test.go b/core/service/blockMainService_test.go index 7cf50e36a..fefaf13c5 100644 --- a/core/service/blockMainService_test.go +++ b/core/service/blockMainService_test.go @@ -5003,3 +5003,148 @@ func TestBlockService_canPersistBlock(t *testing.T) { }) } } + +type ( + mockReceiptUtil struct { + coreUtil.ReceiptUtil + resSignetBytes []byte + } +) + +func (mRu *mockReceiptUtil) GetSignedBatchReceiptBytes(receipt *model.BatchReceipt) []byte { + if mRu.resSignetBytes != nil { + return mRu.resSignetBytes + } + return []byte{} +} + +func TestBlockService_ValidatePayloadHash(t *testing.T) { + mockBlock := &model.Block{ + PayloadHash: []byte{102, 253, 86, 32, 28, 24, 212, 55, 129, 77, 244, 149, 6, 198, 243, 4, 86, 251, 61, 45, 48, 99, 191, + 108, 13, 232, 254, 123, 170, 190, 3, 141}, + PayloadLength: uint32(13), + Transactions: []*model.Transaction{ + mockTransaction, + }, + PublishedReceipts: mockPublishedReceipt, + } + mockInvalidBlock := &model.Block{ + PayloadHash: []byte{102, 253, 86, 32, 28, 24, 212, 55, 129, 77, 244, 149, 6, 198, 243, 4, 86, 251, 61, 45, 48, 99, 191, + 108, 13, 232, 254, 123, 170, 190, 3, 0}, + PayloadLength: uint32(13), + Transactions: []*model.Transaction{ + mockTransaction, + }, + PublishedReceipts: mockPublishedReceipt, + } + type fields struct { + RWMutex sync.RWMutex + Chaintype chaintype.ChainType + KVExecutor kvdb.KVExecutorInterface + QueryExecutor query.ExecutorInterface + BlockQuery query.BlockQueryInterface + MempoolQuery query.MempoolQueryInterface + TransactionQuery query.TransactionQueryInterface + PublishedReceiptQuery query.PublishedReceiptQueryInterface + SkippedBlocksmithQuery query.SkippedBlocksmithQueryInterface + Signature crypto.SignatureInterface + MempoolService MempoolServiceInterface + ReceiptService ReceiptServiceInterface + NodeRegistrationService NodeRegistrationServiceInterface + BlocksmithService BlocksmithServiceInterface + ActionTypeSwitcher transaction.TypeActionSwitcher + AccountBalanceQuery query.AccountBalanceQueryInterface + ParticipationScoreQuery query.ParticipationScoreQueryInterface + NodeRegistrationQuery query.NodeRegistrationQueryInterface + AccountLedgerQuery query.AccountLedgerQueryInterface + BlocksmithStrategy strategy.BlocksmithStrategyInterface + BlockIncompleteQueueService BlockIncompleteQueueServiceInterface + BlockPoolService BlockPoolServiceInterface + Observer *observer.Observer + Logger *log.Logger + TransactionUtil transaction.UtilInterface + ReceiptUtil coreUtil.ReceiptUtilInterface + PublishedReceiptUtil coreUtil.PublishedReceiptUtilInterface + TransactionCoreService TransactionCoreServiceInterface + CoinbaseService CoinbaseServiceInterface + ParticipationScoreService ParticipationScoreServiceInterface + PublishedReceiptService PublishedReceiptServiceInterface + } + type args struct { + block *model.Block + } + tests := []struct { + name string + fields fields + args args + wantErr bool + }{ + { + name: "ValidatePayloadHash:success", + fields: fields{ + BlockQuery: query.NewBlockQuery(&chaintype.MainChain{}), + ActionTypeSwitcher: &mockTypeActionSuccess{}, + ReceiptUtil: &mockReceiptUtil{ + resSignetBytes: []byte{1, 1, 1, 1, 1}, + }, + }, + args: args{ + block: mockBlock, + }, + }, + { + name: "ValidatePayloadHash:fail", + fields: fields{ + BlockQuery: query.NewBlockQuery(&chaintype.MainChain{}), + ActionTypeSwitcher: &mockTypeActionSuccess{}, + ReceiptUtil: &mockReceiptUtil{ + resSignetBytes: []byte{1, 1, 1, 1, 1}, + }, + }, + args: args{ + block: mockInvalidBlock, + }, + wantErr: true, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + bs := &BlockService{ + RWMutex: tt.fields.RWMutex, + Chaintype: tt.fields.Chaintype, + KVExecutor: tt.fields.KVExecutor, + QueryExecutor: tt.fields.QueryExecutor, + BlockQuery: tt.fields.BlockQuery, + MempoolQuery: tt.fields.MempoolQuery, + TransactionQuery: tt.fields.TransactionQuery, + PublishedReceiptQuery: tt.fields.PublishedReceiptQuery, + SkippedBlocksmithQuery: tt.fields.SkippedBlocksmithQuery, + Signature: tt.fields.Signature, + MempoolService: tt.fields.MempoolService, + ReceiptService: tt.fields.ReceiptService, + NodeRegistrationService: tt.fields.NodeRegistrationService, + BlocksmithService: tt.fields.BlocksmithService, + ActionTypeSwitcher: tt.fields.ActionTypeSwitcher, + AccountBalanceQuery: tt.fields.AccountBalanceQuery, + ParticipationScoreQuery: tt.fields.ParticipationScoreQuery, + NodeRegistrationQuery: tt.fields.NodeRegistrationQuery, + AccountLedgerQuery: tt.fields.AccountLedgerQuery, + BlocksmithStrategy: tt.fields.BlocksmithStrategy, + BlockIncompleteQueueService: tt.fields.BlockIncompleteQueueService, + BlockPoolService: tt.fields.BlockPoolService, + Observer: tt.fields.Observer, + Logger: tt.fields.Logger, + TransactionUtil: tt.fields.TransactionUtil, + ReceiptUtil: tt.fields.ReceiptUtil, + PublishedReceiptUtil: tt.fields.PublishedReceiptUtil, + TransactionCoreService: tt.fields.TransactionCoreService, + CoinbaseService: tt.fields.CoinbaseService, + ParticipationScoreService: tt.fields.ParticipationScoreService, + PublishedReceiptService: tt.fields.PublishedReceiptService, + } + if err := bs.ValidatePayloadHash(tt.args.block); (err != nil) != tt.wantErr { + t.Errorf("BlockService.ValidatePayloadHash() error = %v, wantErr %v", err, tt.wantErr) + } + }) + } +} From 6065dec0802211fabf2e56fcbb237da58fd736c9 Mon Sep 17 00:00:00 2001 From: stefano galassi Date: Tue, 10 Mar 2020 10:24:12 +0800 Subject: [PATCH 07/11] Code Refactoring * Add 'dummy' interface BlockServiceSpineInterface to collect all signatures of spine block-specific methods --- core/service/blockMainService.go | 1 + core/service/blockSpineService.go | 5 +++++ 2 files changed, 6 insertions(+) diff --git a/core/service/blockMainService.go b/core/service/blockMainService.go index 5b043cb9d..c34827542 100644 --- a/core/service/blockMainService.go +++ b/core/service/blockMainService.go @@ -33,6 +33,7 @@ import ( ) type ( + // BlockServiceMainInterface interface that contains methods specific of BlockService BlockServiceMainInterface interface { NewMainBlock( version uint32, diff --git a/core/service/blockSpineService.go b/core/service/blockSpineService.go index 62547bfce..97b72d122 100644 --- a/core/service/blockSpineService.go +++ b/core/service/blockSpineService.go @@ -27,6 +27,11 @@ import ( ) type ( + // BlockServiceSpineInterface interface that contains methods specific of BlockSpineService + BlockServiceSpineInterface interface { + ValidateSpineBlockManifest(spineBlockManifest *model.SpineBlockManifest) error + } + BlockSpineService struct { sync.RWMutex Chaintype chaintype.ChainType From 61b3c4e9f682b7c8d4713eb937af2127ec765104 Mon Sep 17 00:00:00 2001 From: stefano galassi Date: Tue, 10 Mar 2020 11:02:11 +0800 Subject: [PATCH 08/11] Code Refactoring * Removed unnecessary comment --- core/service/snapshotMainBlockService.go | 2 -- 1 file changed, 2 deletions(-) diff --git a/core/service/snapshotMainBlockService.go b/core/service/snapshotMainBlockService.go index 1a9116714..3d5932641 100644 --- a/core/service/snapshotMainBlockService.go +++ b/core/service/snapshotMainBlockService.go @@ -67,7 +67,6 @@ func (ss *SnapshotMainBlockService) NewSnapshotFile(block *model.Block) (snapsho snapshotExpirationTimestamp = block.Timestamp + int64(ss.chainType.GetSnapshotGenerationTimeout().Seconds()) ) - // @iltoga comment out for testing snapshots locally if block.Height <= constant.MinRollbackBlocks { return nil, blocker.NewBlocker(blocker.ValidationErr, fmt.Sprintf("invalid snapshot height: %d", block.Height)) @@ -150,7 +149,6 @@ func (ss *SnapshotMainBlockService) ImportSnapshotFile(snapshotFileInfo *model.S // IsSnapshotHeight returns true if chain height passed is a snapshot height func (ss *SnapshotMainBlockService) IsSnapshotHeight(height uint32) bool { snapshotInterval := ss.chainType.GetSnapshotInterval() - // @iltoga comment out for testing snapshots locally if snapshotInterval < constant.MinRollbackBlocks { if height < constant.MinRollbackBlocks { return false From 313cadbe5aa8ac0d6597dc7ef3905980cf6edeaa Mon Sep 17 00:00:00 2001 From: stefano galassi Date: Tue, 10 Mar 2020 12:28:42 +0800 Subject: [PATCH 09/11] Bug fixing * Remove fmt.println probably left from some internal test --- core/service/transactionCoreService_test.go | 2 -- 1 file changed, 2 deletions(-) diff --git a/core/service/transactionCoreService_test.go b/core/service/transactionCoreService_test.go index d7ad2df45..42795eb25 100644 --- a/core/service/transactionCoreService_test.go +++ b/core/service/transactionCoreService_test.go @@ -3,7 +3,6 @@ package service import ( "database/sql" "errors" - "fmt" "reflect" "regexp" "testing" @@ -282,7 +281,6 @@ func (*mockQueryExecutorExpiringEscrowSuccess) ExecuteSelect(qStr string, tx boo return db.Query(qStr) } func (*mockQueryExecutorExpiringEscrowSuccess) ExecuteTransactions(queries [][]interface{}) error { - fmt.Println(queries) return nil } From be1f20e8464c8905ce90566356c4af5983cad8b8 Mon Sep 17 00:00:00 2001 From: stefano galassi Date: Tue, 10 Mar 2020 14:02:26 +0800 Subject: [PATCH 10/11] Bug fixing * Update comment in query --- common/query/blockQuery.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/query/blockQuery.go b/common/query/blockQuery.go index 4bc5031fa..4280d132f 100644 --- a/common/query/blockQuery.go +++ b/common/query/blockQuery.go @@ -98,7 +98,7 @@ func (bq *BlockQuery) GetBlockFromHeight(startHeight, limit uint32) string { strings.Join(bq.Fields, ", "), bq.getTableName(), startHeight, limit) } -// GetBlockFromHeight returns query string to get blocks from a certain height +// GetBlockFromTimestamp returns query string to get blocks from a certain block timestamp func (bq *BlockQuery) GetBlockFromTimestamp(startTimestamp int64, limit uint32) string { return fmt.Sprintf("SELECT %s FROM %s WHERE timestamp >= %d ORDER BY timestamp LIMIT %d", strings.Join(bq.Fields, ", "), bq.getTableName(), startTimestamp, limit) From 07970e5c9f3cf484a32114fefa5bf54c0b7bc03c Mon Sep 17 00:00:00 2001 From: stefano galassi Date: Tue, 10 Mar 2020 14:36:41 +0800 Subject: [PATCH 11/11] Code Optimization * Optimize if statement by reversing conditions (courtesy of @ali) --- core/service/blockMainService.go | 2 +- core/service/blockSpineService.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/core/service/blockMainService.go b/core/service/blockMainService.go index 4467c449f..4a7af32d6 100644 --- a/core/service/blockMainService.go +++ b/core/service/blockMainService.go @@ -271,7 +271,7 @@ func (bs *BlockService) ValidatePayloadHash(block *model.Block) error { if err != nil { return err } - if !bytes.Equal(hash, block.GetPayloadHash()) || length != block.GetPayloadLength() { + if length != block.GetPayloadLength() || !bytes.Equal(hash, block.GetPayloadHash()) { return blocker.NewBlocker(blocker.ValidationErr, "InvalidBlockPayload") } return nil diff --git a/core/service/blockSpineService.go b/core/service/blockSpineService.go index 8c194226e..a7aa926d6 100644 --- a/core/service/blockSpineService.go +++ b/core/service/blockSpineService.go @@ -196,7 +196,7 @@ func (bs *BlockSpineService) ValidatePayloadHash(block *model.Block) error { if err != nil { return err } - if !bytes.Equal(hash, block.GetPayloadHash()) || length != block.GetPayloadLength() { + if length != block.GetPayloadLength() || !bytes.Equal(hash, block.GetPayloadHash()) { return blocker.NewBlocker(blocker.ValidationErr, "InvalidBlockPayload") } return nil