From d25931fd359821ac2f38b5b2da691a9d54c83351 Mon Sep 17 00:00:00 2001 From: David Hill Date: Sat, 9 Mar 2019 22:35:39 +0000 Subject: [PATCH] multi: preallocate memory. --- blockchain/chainio.go | 11 ++++++---- blockchain/merkle.go | 2 +- blockchain/stake/internal/ticketdb/chainio.go | 16 +++++++++----- blockmanager.go | 22 ++++++++++--------- dcrec/edwards/curve_test.go | 4 ++-- dcrec/secp256k1/schnorr/ecdsa_test.go | 4 ++-- dcrec/secp256k1/schnorr/threshold_test.go | 4 ++-- dcrjson/parse_test.go | 2 +- dcrutil/address.go | 2 +- rpcwebsocket.go | 2 +- 10 files changed, 40 insertions(+), 29 deletions(-) diff --git a/blockchain/chainio.go b/blockchain/chainio.go index 188bee94..ceb30f37 100644 --- a/blockchain/chainio.go +++ b/blockchain/chainio.go @@ -728,7 +728,7 @@ func serializeSpendJournalEntry(stxos []spentTxOut) ([]byte, error) { // Calculate the size needed to serialize the entire journal entry. var size int - var sizes []int + sizes := make([]int, 0, len(stxos)) for i := range stxos { sz := spentTxOutSerializeSize(&stxos[i]) sizes = append(sizes, sz) @@ -762,9 +762,12 @@ func dbFetchSpendJournalEntry(dbTx database.Tx, block *dcrutil.Block) ([]spentTx // Exclude the coinbase transaction since it can't spend anything. spendBucket := dbTx.Metadata().Bucket(dbnamespace.SpendJournalBucketName) serialized := spendBucket.Get(block.Hash()[:]) - var blockTxns []*wire.MsgTx - blockTxns = append(blockTxns, block.MsgBlock().STransactions...) - blockTxns = append(blockTxns, block.MsgBlock().Transactions[1:]...) + msgBlock := block.MsgBlock() + + blockTxns := make([]*wire.MsgTx, 0, len(msgBlock.STransactions)+ + len(msgBlock.Transactions[1:])) + blockTxns = append(blockTxns, msgBlock.STransactions...) + blockTxns = append(blockTxns, msgBlock.Transactions[1:]...) if len(blockTxns) > 0 && len(serialized) == 0 { panicf("missing spend journal data for %s", block.Hash()) } diff --git a/blockchain/merkle.go b/blockchain/merkle.go index bd5b06f2..47df1d53 100644 --- a/blockchain/merkle.go +++ b/blockchain/merkle.go @@ -1,5 +1,5 @@ // Copyright (c) 2013-2016 The btcsuite developers -// Copyright (c) 2015-2016 The Decred developers +// Copyright (c) 2015-2019 The Decred developers // Use of this source code is governed by an ISC // license that can be found in the LICENSE file. diff --git a/blockchain/stake/internal/ticketdb/chainio.go b/blockchain/stake/internal/ticketdb/chainio.go index 045fa187..18477243 100644 --- a/blockchain/stake/internal/ticketdb/chainio.go +++ b/blockchain/stake/internal/ticketdb/chainio.go @@ -244,13 +244,21 @@ type BestChainState struct { } // serializeBestChainState returns the serialization of the passed block best -// chain state. This is data to be stored in the chain state bucket. This -// function will panic if the number of tickets per block is less than the +// chain state. This is data to be stored in the chain state bucket. +// This function will panic if the number of tickets per block is less than the // size of next winners, which should never happen unless there is memory // corruption. func serializeBestChainState(state BestChainState) []byte { + if int(state.PerBlock) < len(state.NextWinners) { + errStr := fmt.Sprintf("PerBlock:%d < NextWinners:%d", + state.PerBlock, len(state.NextWinners)) + panic(errStr) + } + + serializedDataLen := minimumBestChainStateSize + + (chainhash.HashSize * int(state.PerBlock)) // Serialize the chain state. - serializedData := make([]byte, minimumBestChainStateSize) + serializedData := make([]byte, serializedDataLen) offset := 0 copy(serializedData[offset:offset+chainhash.HashSize], state.Hash[:]) @@ -267,8 +275,6 @@ func serializeBestChainState(state BestChainState) []byte { offset += 2 // Serialize the next winners. - ticketBuffer := make([]byte, chainhash.HashSize*int(state.PerBlock)) - serializedData = append(serializedData, ticketBuffer...) for i := range state.NextWinners { copy(serializedData[offset:offset+chainhash.HashSize], state.NextWinners[i][:]) diff --git a/blockmanager.go b/blockmanager.go index 2440dd5c..d5dccf86 100644 --- a/blockmanager.go +++ b/blockmanager.go @@ -1,5 +1,5 @@ // Copyright (c) 2013-2016 The btcsuite developers -// Copyright (c) 2015-2018 The Decred developers +// Copyright (c) 2015-2019 The Decred developers // Use of this source code is governed by an ISC // license that can be found in the LICENSE file. @@ -688,13 +688,6 @@ func (b *blockManager) current() bool { // access through the block mananger. All template access must also be routed // through the block manager. func (b *blockManager) checkBlockForHiddenVotes(block *dcrutil.Block) { - var votesFromBlock []*dcrutil.Tx - for _, stx := range block.STransactions() { - if stake.IsSSGen(stx.MsgTx()) { - votesFromBlock = append(votesFromBlock, stx) - } - } - // Identify the cached parent template; it's possible that // the parent template hasn't yet been updated, so we may // need to use the current template. @@ -728,6 +721,14 @@ func (b *blockManager) checkBlockForHiddenVotes(block *dcrutil.Block) { return } + votesFromBlock := make([]*dcrutil.Tx, 0, + activeNetParams.TicketsPerBlock) + for _, stx := range block.STransactions() { + if stake.IsSSGen(stx.MsgTx()) { + votesFromBlock = append(votesFromBlock, stx) + } + } + // Now that we have the template, grab the votes and compare // them with those found in the newly added block. If we don't // the votes, they will need to be added to our block template. @@ -791,7 +792,7 @@ func (b *blockManager) checkBlockForHiddenVotes(block *dcrutil.Block) { // calculated. template.Block.ClearSTransactions() updatedTxTreeStake := make([]*dcrutil.Tx, 0, - votesTotal+len(oldTickets)+len(oldRevocations)) + len(newVotes)+len(oldTickets)+len(oldRevocations)) for _, vote := range newVotes { updatedTxTreeStake = append(updatedTxTreeStake, vote) template.Block.AddSTransaction(vote.MsgTx()) @@ -837,7 +838,8 @@ func (b *blockManager) checkBlockForHiddenVotes(block *dcrutil.Block) { // Patch the header. First, reconstruct the merkle trees, then // correct the number of voters, and finally recalculate the size. - var updatedTxTreeRegular []*dcrutil.Tx + updatedTxTreeRegular := make([]*dcrutil.Tx, 0, + len(template.Block.Transactions)) updatedTxTreeRegular = append(updatedTxTreeRegular, coinbase) for i, mtx := range template.Block.Transactions { // Coinbase diff --git a/dcrec/edwards/curve_test.go b/dcrec/edwards/curve_test.go index 2529503d..223a6e48 100644 --- a/dcrec/edwards/curve_test.go +++ b/dcrec/edwards/curve_test.go @@ -1,4 +1,4 @@ -// Copyright (c) 2015-2016 The Decred developers +// Copyright (c) 2015-2019 The Decred developers // Use of this source code is governed by an ISC // license that can be found in the LICENSE file. @@ -196,7 +196,7 @@ type ScalarMultVector struct { func testVectorsScalarMult() []ScalarMultVector { tvsmh := testVectorsScalarMultHex() - var tvsms []ScalarMultVector + tvsms := make([]ScalarMultVector, 0, len(tvsmh)) for _, v := range tvsmh { bIn, _ := hex.DecodeString(v.bIn) s, _ := hex.DecodeString(v.s) diff --git a/dcrec/secp256k1/schnorr/ecdsa_test.go b/dcrec/secp256k1/schnorr/ecdsa_test.go index 03af4039..a7e14996 100644 --- a/dcrec/secp256k1/schnorr/ecdsa_test.go +++ b/dcrec/secp256k1/schnorr/ecdsa_test.go @@ -1,4 +1,4 @@ -// Copyright (c) 2015-2016 The Decred developers +// Copyright (c) 2015-2019 The Decred developers // Use of this source code is governed by an ISC // license that can be found in the LICENSE file. @@ -93,7 +93,7 @@ type SchorrSigningTestVector struct { } func GetSigningTestVectors() []*SchorrSigningTestVector { - var tvs []*SchorrSigningTestVector + tvs := make([]*SchorrSigningTestVector, 0, len(schnorrSigningTestVectors)) for _, v := range schnorrSigningTestVectors { msg, _ := hex.DecodeString(v.msg) nonce, _ := hex.DecodeString(v.nonce) diff --git a/dcrec/secp256k1/schnorr/threshold_test.go b/dcrec/secp256k1/schnorr/threshold_test.go index 6644fc47..bb1bf694 100644 --- a/dcrec/secp256k1/schnorr/threshold_test.go +++ b/dcrec/secp256k1/schnorr/threshold_test.go @@ -1,4 +1,4 @@ -// Copyright (c) 2015-2016 The Decred developers +// Copyright (c) 2015-2019 The Decred developers // Use of this source code is governed by an ISC // license that can be found in the LICENSE file. @@ -177,7 +177,7 @@ type ThresholdTestVector struct { } func GetThresholdTestVectors() []*ThresholdTestVector { - var tvs []*ThresholdTestVector + tvs := make([]*ThresholdTestVector, 0, len(thresholdTestVectorsHex)) for _, v := range thresholdTestVectorsHex { msg, _ := hex.DecodeString(v.msg) combSig, _ := hex.DecodeString(v.combinedSignature) diff --git a/dcrjson/parse_test.go b/dcrjson/parse_test.go index 612ceb53..aafd1dde 100644 --- a/dcrjson/parse_test.go +++ b/dcrjson/parse_test.go @@ -60,7 +60,7 @@ func TestDecodeConcatenatedHashes(t *testing.T) { decodeHash("000000000000437482b6d47f82f374cde539440ddb108b0a76886f0d87d126b9"), decodeHash("000000000000c41019872ff7db8fd2e9bfa05f42d3f8fee8e895e8c1e5b8dcba"), } - var concatenatedHashBytes []byte + concatenatedHashBytes := make([]byte, 0, len(testHashes)) for _, h := range testHashes { concatenatedHashBytes = append(concatenatedHashBytes, h[:]...) } diff --git a/dcrutil/address.go b/dcrutil/address.go index 60d764dd..92209f80 100644 --- a/dcrutil/address.go +++ b/dcrutil/address.go @@ -1,5 +1,5 @@ // Copyright (c) 2013, 2014 The btcsuite developers -// Copyright (c) 2015-2018 The Decred developers +// Copyright (c) 2015-2019 The Decred developers // Use of this source code is governed by an ISC // license that can be found in the LICENSE file. diff --git a/rpcwebsocket.go b/rpcwebsocket.go index ae155b1f..97c825cd 100644 --- a/rpcwebsocket.go +++ b/rpcwebsocket.go @@ -921,7 +921,7 @@ func (m *wsNotificationManager) UnregisterStakeDifficulty(wsc *wsClient) { // maturing ticket updates. func (*wsNotificationManager) notifyNewTickets(clients map[chan struct{}]*wsClient, tnd *blockchain.TicketNotificationsData) { // Create a ticket map to export as JSON. - var tickets []string + tickets := make([]string, 0, len(tnd.TicketsNew)) for _, h := range tnd.TicketsNew { tickets = append(tickets, h.String()) }