From 499adbf0461e8839106dd67facce872c4120f6e6 Mon Sep 17 00:00:00 2001 From: Evgeny Khirin <32414982+evgeny-khirin@users.noreply.github.com> Date: Wed, 24 Oct 2018 16:29:50 +0300 Subject: [PATCH] DEV-222: Changed type of TxOut.Value and util.Amount to uin64 (#108) * [DEV-222] Changed type of TxOut.Value and util.Amount to uin64 * [DEV-222] Replaced math.MaxUint64 with 0 * [DEV-222] Fixed comment to reflect uint64 instead of int64 * [DEV-222] Fixed overflow comment --- blockdag/dagio.go | 2 +- blockdag/fullblocktests/generate.go | 16 +++++----- blockdag/utxoset.go | 4 +-- blockdag/utxoset_test.go | 12 ++++---- blockdag/validate.go | 30 ++++++++---------- btcjson/dagsvrresults.go | 4 +-- integration/rpctest/memwallet.go | 4 +-- mempool/estimatefee.go | 2 +- mempool/estimatefee_test.go | 4 +-- mempool/mempool.go | 8 ++--- mempool/mempool_test.go | 14 ++++----- mempool/policy.go | 2 +- mining/mining.go | 18 +++++------ mining/mining_test.go | 2 +- mining/policy.go | 2 +- mining/policy_test.go | 2 +- server/p2p/p2p.go | 2 +- server/rpc/rpcserver.go | 6 ++-- server/rpc/rpcwebsocket.go | 2 +- txscript/script.go | 2 +- util/amount.go | 2 +- util/amount_test.go | 48 ----------------------------- wire/msgtx.go | 4 +-- wire/msgtx_test.go | 2 +- 24 files changed, 71 insertions(+), 123 deletions(-) diff --git a/blockdag/dagio.go b/blockdag/dagio.go index 552471bce..b59b680d0 100644 --- a/blockdag/dagio.go +++ b/blockdag/dagio.go @@ -555,7 +555,7 @@ func deserializeUTXOEntry(serialized []byte) (*UTXOEntry, error) { } entry := &UTXOEntry{ - amount: int64(amount), + amount: amount, pkScript: pkScript, blockHeight: blockHeight, packedFlags: 0, diff --git a/blockdag/fullblocktests/generate.go b/blockdag/fullblocktests/generate.go index 476e021af..df5c64996 100644 --- a/blockdag/fullblocktests/generate.go +++ b/blockdag/fullblocktests/generate.go @@ -383,7 +383,7 @@ func additionalCoinbase(amount util.Amount) func(*wire.MsgBlock) { return func(b *wire.MsgBlock) { // Increase the first proof-of-work coinbase subsidy by the // provided amount. - b.Transactions[0].TxOut[0].Value += int64(amount) + b.Transactions[0].TxOut[0].Value += uint64(amount) } } @@ -396,12 +396,12 @@ func additionalSpendFee(fee util.Amount) func(*wire.MsgBlock) { return func(b *wire.MsgBlock) { // Increase the fee of the spending transaction by reducing the // amount paid. - if int64(fee) > b.Transactions[1].TxOut[0].Value { + if uint64(fee) > b.Transactions[1].TxOut[0].Value { panic(fmt.Sprintf("additionalSpendFee: fee of %d "+ "exceeds available spend transaction value", fee)) } - b.Transactions[1].TxOut[0].Value -= int64(fee) + b.Transactions[1].TxOut[0].Value -= uint64(fee) } } @@ -441,7 +441,7 @@ func createSpendTx(spend *spendableOut, fee util.Amount) *wire.MsgTx { Sequence: wire.MaxTxInSequenceNum, SignatureScript: nil, }) - spendTx.AddTxOut(wire.NewTxOut(int64(spend.amount-fee), + spendTx.AddTxOut(wire.NewTxOut(uint64(spend.amount-fee), opTrueScript)) spendTx.AddTxOut(wire.NewTxOut(0, uniqueOpReturnScript())) @@ -487,7 +487,7 @@ func (g *testGenerator) nextBlock(blockName string, spend *spendableOut, mungers // Create the transaction with a fee of 1 atom for the // miner and increase the coinbase subsidy accordingly. fee := util.Amount(1) - coinbaseTx.TxOut[0].Value += int64(fee) + coinbaseTx.TxOut[0].Value += uint64(fee) // Create a transaction that spends from the provided spendable // output and includes an additional unique OP_RETURN output to @@ -1695,7 +1695,7 @@ func Generate(includeLargeReorg bool) (tests [][]TestInstance, err error) { // \-> b59(17) g.setTip("b57") g.nextBlock("b59", outs[17], func(b *wire.MsgBlock) { - b.Transactions[1].TxOut[0].Value = int64(outs[17].amount) + 1 + b.Transactions[1].TxOut[0].Value = uint64(outs[17].amount) + 1 }) rejected(blockdag.ErrSpendTooHigh) @@ -1967,7 +1967,7 @@ func Generate(includeLargeReorg bool) (tests [][]TestInstance, err error) { // Add 4 outputs to the spending transaction that are spent // below. const numAdditionalOutputs = 4 - const zeroCoin = int64(0) + const zeroCoin = uint64(0) spendTx := b.Transactions[1] for i := 0; i < numAdditionalOutputs; i++ { spendTx.AddTxOut(wire.NewTxOut(zeroCoin, opTrueScript)) @@ -2032,7 +2032,7 @@ func Generate(includeLargeReorg bool) (tests [][]TestInstance, err error) { g.setTip("b79") g.nextBlock("b81", outs[27], func(b *wire.MsgBlock) { const numAdditionalOutputs = 4 - const zeroCoin = int64(0) + const zeroCoin = uint64(0) spendTx := b.Transactions[1] for i := 0; i < numAdditionalOutputs; i++ { opRetScript := uniqueOpReturnScript() diff --git a/blockdag/utxoset.go b/blockdag/utxoset.go index 2d3d2d7bb..6087173b6 100644 --- a/blockdag/utxoset.go +++ b/blockdag/utxoset.go @@ -20,7 +20,7 @@ type UTXOEntry struct { // specifically crafted to result in minimal padding. There will be a // lot of these in memory, so a few extra bytes of padding adds up. - amount int64 + amount uint64 pkScript []byte // The public key script for the output. blockHeight int32 // Height of block containing tx. @@ -43,7 +43,7 @@ func (entry *UTXOEntry) BlockHeight() int32 { } // Amount returns the amount of the output. -func (entry *UTXOEntry) Amount() int64 { +func (entry *UTXOEntry) Amount() uint64 { return entry.amount } diff --git a/blockdag/utxoset_test.go b/blockdag/utxoset_test.go index 1894b4775..ccc97db2d 100644 --- a/blockdag/utxoset_test.go +++ b/blockdag/utxoset_test.go @@ -822,8 +822,8 @@ func createCoinbaseTx(blockHeight int32, numOutputs uint32) (*wire.MsgTx, error) Sequence: wire.MaxTxInSequenceNum, }) totalInput := CalcBlockSubsidy(blockHeight, &dagconfig.MainNetParams) - amountPerOutput := totalInput / int64(numOutputs) - remainder := totalInput - amountPerOutput*int64(numOutputs) + amountPerOutput := totalInput / uint64(numOutputs) + remainder := totalInput - amountPerOutput*uint64(numOutputs) for i := uint32(0); i < numOutputs; i++ { // Ensure the final output accounts for any remainder that might // be left from splitting the input amount. @@ -861,7 +861,7 @@ func TestApplyUTXOChanges(t *testing.T) { }) chainedTx.AddTxOut(&wire.TxOut{ PkScript: OpTrueScript, - Value: int64(1), + Value: uint64(1), }) //Fake block header @@ -891,7 +891,7 @@ func TestApplyUTXOChanges(t *testing.T) { }) nonChainedTx.AddTxOut(&wire.TxOut{ PkScript: OpTrueScript, - Value: int64(1), + Value: uint64(1), }) msgBlock2 := &wire.MsgBlock{ @@ -930,7 +930,7 @@ func TestDiffFromTx(t *testing.T) { }) tx.AddTxOut(&wire.TxOut{ PkScript: OpTrueScript, - Value: int64(1), + Value: uint64(1), }) diff, err := fus.diffFromTx(tx, node) if err != nil { @@ -957,7 +957,7 @@ func TestDiffFromTx(t *testing.T) { }) invalidTx.AddTxOut(&wire.TxOut{ PkScript: OpTrueScript, - Value: int64(1), + Value: uint64(1), }) _, err = fus.diffFromTx(invalidTx, node) if err == nil { diff --git a/blockdag/validate.go b/blockdag/validate.go index 6af659d43..828dadf9f 100644 --- a/blockdag/validate.go +++ b/blockdag/validate.go @@ -162,7 +162,7 @@ func IsFinalizedTransaction(tx *util.Tx, blockHeight int32, blockTime time.Time) // // At the target block generation rate for the main network, this is // approximately every 4 years. -func CalcBlockSubsidy(height int32, dagParams *dagconfig.Params) int64 { +func CalcBlockSubsidy(height int32, dagParams *dagconfig.Params) uint64 { if dagParams.SubsidyReductionInterval == 0 { return baseSubsidy } @@ -200,7 +200,7 @@ func CheckTransactionSanity(tx *util.Tx) error { // restrictions. All amounts in a transaction are in a unit value known // as a satoshi. One bitcoin is a quantity of satoshi as defined by the // SatoshiPerBitcoin constant. - var totalSatoshi int64 + var totalSatoshi uint64 for _, txOut := range msgTx.TxOut { satoshi := txOut.Value if satoshi < 0 { @@ -215,16 +215,17 @@ func CheckTransactionSanity(tx *util.Tx) error { return ruleError(ErrBadTxOutValue, str) } - // Two's complement int64 overflow guarantees that any overflow - // is detected and reported. This is impossible for Bitcoin, but - // perhaps possible if an alt increases the total money supply. - totalSatoshi += satoshi - if totalSatoshi < 0 { + // Binary arithmetic guarantees that any overflow is detected and reported. + // This is impossible for Bitcoin, but perhaps possible if an alt increases + // the total money supply. + newTotalSatoshi := totalSatoshi + satoshi + if newTotalSatoshi < totalSatoshi { str := fmt.Sprintf("total value of all transaction "+ "outputs exceeds max allowed value of %v", util.MaxSatoshi) return ruleError(ErrBadTxOutValue, str) } + totalSatoshi = newTotalSatoshi if totalSatoshi > util.MaxSatoshi { str := fmt.Sprintf("total value of all transaction "+ "outputs is %v which is higher than max "+ @@ -815,14 +816,14 @@ func (dag *BlockDAG) ensureNoDuplicateTx(node *blockNode, block *util.Block) err // // NOTE: The transaction MUST have already been sanity checked with the // CheckTransactionSanity function prior to calling this function. -func CheckTransactionInputs(tx *util.Tx, txHeight int32, utxoSet UTXOSet, dagParams *dagconfig.Params) (int64, error) { +func CheckTransactionInputs(tx *util.Tx, txHeight int32, utxoSet UTXOSet, dagParams *dagconfig.Params) (uint64, error) { // Coinbase transactions have no inputs. if IsCoinBase(tx) { return 0, nil } txHash := tx.Hash() - var totalSatoshiIn int64 + var totalSatoshiIn uint64 for txInIndex, txIn := range tx.MsgTx().TxIn { // Ensure the referenced input transaction is available. entry, ok := utxoSet.Get(txIn.PreviousOutPoint) @@ -858,11 +859,6 @@ func CheckTransactionInputs(tx *util.Tx, txHeight int32, utxoSet UTXOSet, dagPar // bitcoin is a quantity of satoshi as defined by the // SatoshiPerBitcoin constant. originTxSatoshi := entry.Amount() - if originTxSatoshi < 0 { - str := fmt.Sprintf("transaction output has negative "+ - "value of %v", util.Amount(originTxSatoshi)) - return 0, ruleError(ErrBadTxOutValue, str) - } if originTxSatoshi > util.MaxSatoshi { str := fmt.Sprintf("transaction output value of %v is "+ "higher than max allowed value of %v", @@ -889,7 +885,7 @@ func CheckTransactionInputs(tx *util.Tx, txHeight int32, utxoSet UTXOSet, dagPar // Calculate the total output amount for this transaction. It is safe // to ignore overflow and out of range errors here because those error // conditions would have already been caught by checkTransactionSanity. - var totalSatoshiOut int64 + var totalSatoshiOut uint64 for _, txOut := range tx.MsgTx().TxOut { totalSatoshiOut += txOut.Value } @@ -990,7 +986,7 @@ func (dag *BlockDAG) checkConnectBlock(node *blockNode, block *util.Block) error // still relatively cheap as compared to running the scripts) checks // against all the inputs when the signature operations are out of // bounds. - var totalFees int64 + var totalFees uint64 for _, tx := range transactions { txFee, err := CheckTransactionInputs(tx, node.height, dag.virtual.utxoSet, dag.dagParams) @@ -1013,7 +1009,7 @@ func (dag *BlockDAG) checkConnectBlock(node *blockNode, block *util.Block) error // mining the block. It is safe to ignore overflow and out of range // errors here because those error conditions would have already been // caught by checkTransactionSanity. - var totalSatoshiOut int64 + var totalSatoshiOut uint64 for _, txOut := range transactions[0].MsgTx().TxOut { totalSatoshiOut += txOut.Value } diff --git a/btcjson/dagsvrresults.go b/btcjson/dagsvrresults.go index a4e03170b..4fcb93d06 100644 --- a/btcjson/dagsvrresults.go +++ b/btcjson/dagsvrresults.go @@ -118,7 +118,7 @@ type GetBlockTemplateResultTx struct { Data string `json:"data"` Hash string `json:"hash"` Depends []int64 `json:"depends"` - Fee int64 `json:"fee"` + Fee uint64 `json:"fee"` SigOps int64 `json:"sigops"` } @@ -143,7 +143,7 @@ type GetBlockTemplateResult struct { Version int32 `json:"version"` CoinbaseAux *GetBlockTemplateResultAux `json:"coinbaseaux,omitempty"` CoinbaseTxn *GetBlockTemplateResultTx `json:"coinbasetxn,omitempty"` - CoinbaseValue *int64 `json:"coinbasevalue,omitempty"` + CoinbaseValue *uint64 `json:"coinbasevalue,omitempty"` WorkID string `json:"workid,omitempty"` // Optional long polling from BIP 0022. diff --git a/integration/rpctest/memwallet.go b/integration/rpctest/memwallet.go index ccd3e740d..1eb1d18d8 100644 --- a/integration/rpctest/memwallet.go +++ b/integration/rpctest/memwallet.go @@ -16,9 +16,9 @@ import ( "github.com/daglabs/btcd/dagconfig/daghash" "github.com/daglabs/btcd/rpcclient" "github.com/daglabs/btcd/txscript" - "github.com/daglabs/btcd/wire" "github.com/daglabs/btcd/util" "github.com/daglabs/btcd/util/hdkeychain" + "github.com/daglabs/btcd/wire" ) var ( @@ -428,7 +428,7 @@ func (m *memWallet) fundTx(tx *wire.MsgTx, amt util.Amount, feeRate util.Amount) return err } changeOutput := &wire.TxOut{ - Value: int64(changeVal), + Value: uint64(changeVal), PkScript: pkScript, } tx.AddTxOut(changeOutput) diff --git a/mempool/estimatefee.go b/mempool/estimatefee.go index d9e7116c2..d1575d275 100644 --- a/mempool/estimatefee.go +++ b/mempool/estimatefee.go @@ -78,7 +78,7 @@ func (rate SatoshiPerByte) ToBtcPerKb() BtcPerKilobyte { func (rate SatoshiPerByte) Fee(size uint32) util.Amount { // If our rate is the error value, return that. if rate == SatoshiPerByte(-1) { - return util.Amount(-1) + return math.MaxUint64 } return util.Amount(float64(rate) * float64(size)) diff --git a/mempool/estimatefee_test.go b/mempool/estimatefee_test.go index 0916308ac..01996d38a 100644 --- a/mempool/estimatefee_test.go +++ b/mempool/estimatefee_test.go @@ -11,8 +11,8 @@ import ( "github.com/daglabs/btcd/dagconfig/daghash" "github.com/daglabs/btcd/mining" - "github.com/daglabs/btcd/wire" "github.com/daglabs/btcd/util" + "github.com/daglabs/btcd/wire" ) // newTestFeeEstimator creates a feeEstimator with some different parameters @@ -54,7 +54,7 @@ func (eft *estimateFeeTester) testTx(fee util.Amount) *TxDesc { Version: eft.version, }), Height: eft.height, - Fee: int64(fee), + Fee: uint64(fee), }, StartingPriority: 0, } diff --git a/mempool/mempool.go b/mempool/mempool.go index 76fd7d2e0..85a8e5bff 100644 --- a/mempool/mempool.go +++ b/mempool/mempool.go @@ -540,7 +540,7 @@ func (mp *TxPool) RemoveDoubleSpends(tx *util.Tx) { // helper for maybeAcceptTransaction. // // This function MUST be called with the mempool lock held (for writes). -func (mp *TxPool) addTransaction(tx *util.Tx, height int32, fee int64) *TxDesc { +func (mp *TxPool) addTransaction(tx *util.Tx, height int32, fee uint64) *TxDesc { mp.cfg.DAG.UTXORLock() defer mp.cfg.DAG.UTXORUnlock() // Add the transaction to the pool and mark the referenced outpoints @@ -551,7 +551,7 @@ func (mp *TxPool) addTransaction(tx *util.Tx, height int32, fee int64) *TxDesc { Added: time.Now(), Height: height, Fee: fee, - FeePerKB: fee * 1000 / int64(tx.MsgTx().SerializeSize()), + FeePerKB: fee * 1000 / uint64(tx.MsgTx().SerializeSize()), }, StartingPriority: mining.CalcPriority(tx.MsgTx(), mp.mpUTXOSet, height), } @@ -816,8 +816,8 @@ func (mp *TxPool) maybeAcceptTransaction(tx *util.Tx, isNew, rateLimit, rejectDu // transaction does not exceeed 1000 less than the reserved space for // high-priority transactions, don't require a fee for it. serializedSize := int64(tx.MsgTx().SerializeSize()) - minFee := calcMinRequiredTxRelayFee(serializedSize, - mp.cfg.Policy.MinRelayTxFee) + minFee := uint64(calcMinRequiredTxRelayFee(serializedSize, + mp.cfg.Policy.MinRelayTxFee)) if serializedSize >= (DefaultBlockPrioritySize-1000) && txFee < minFee { str := fmt.Sprintf("transaction %v has %d fees which is under "+ "the required amount of %d", txHash, txFee, diff --git a/mempool/mempool_test.go b/mempool/mempool_test.go index 3c2ab1a07..354c0a912 100644 --- a/mempool/mempool_test.go +++ b/mempool/mempool_test.go @@ -134,8 +134,8 @@ func (p *poolHarness) CreateCoinbaseTx(blockHeight int32, numOutputs uint32) (*u Sequence: wire.MaxTxInSequenceNum, }) totalInput := blockdag.CalcBlockSubsidy(blockHeight, p.chainParams) - amountPerOutput := totalInput / int64(numOutputs) - remainder := totalInput - amountPerOutput*int64(numOutputs) + amountPerOutput := totalInput / uint64(numOutputs) + remainder := totalInput - amountPerOutput*uint64(numOutputs) for i := uint32(0); i < numOutputs; i++ { // Ensure the final output accounts for any remainder that might // be left from splitting the input amount. @@ -163,8 +163,8 @@ func (p *poolHarness) CreateSignedTx(inputs []spendableOutpoint, numOutputs uint for _, input := range inputs { totalInput += input.amount } - amountPerOutput := int64(totalInput) / int64(numOutputs) - remainder := int64(totalInput) - amountPerOutput*int64(numOutputs) + amountPerOutput := uint64(totalInput) / uint64(numOutputs) + remainder := uint64(totalInput) - amountPerOutput*uint64(numOutputs) tx := wire.NewMsgTx(wire.TxVersion) for _, input := range inputs { @@ -220,7 +220,7 @@ func (p *poolHarness) CreateTxChain(firstOutput spendableOutpoint, numTxns uint3 }) tx.AddTxOut(&wire.TxOut{ PkScript: p.payScript, - Value: int64(spendableAmount), + Value: uint64(spendableAmount), }) // Sign the new transaction. @@ -362,14 +362,14 @@ func testPoolMembership(tc *testContext, tx *util.Tx, inOrphanPool, inTxPool boo } } -func (p *poolHarness) createTx(outpoint spendableOutpoint, fee int64, numOutputs int64) (*util.Tx, error) { +func (p *poolHarness) createTx(outpoint spendableOutpoint, fee uint64, numOutputs int64) (*util.Tx, error) { tx := wire.NewMsgTx(wire.TxVersion) tx.AddTxIn(&wire.TxIn{ PreviousOutPoint: outpoint.outPoint, SignatureScript: nil, Sequence: wire.MaxTxInSequenceNum, }) - amountPerOutput := (int64(outpoint.amount) - fee) / numOutputs + amountPerOutput := (uint64(outpoint.amount) - fee) / uint64(numOutputs) for i := int64(0); i < numOutputs; i++ { tx.AddTxOut(&wire.TxOut{ PkScript: p.payScript, diff --git a/mempool/policy.go b/mempool/policy.go index 67498636c..1dcb5ef66 100644 --- a/mempool/policy.go +++ b/mempool/policy.go @@ -235,7 +235,7 @@ func isDust(txOut *wire.TxOut, minRelayTxFee util.Amount) bool { // // The following is equivalent to (value/totalSize) * (1/3) * 1000 // without needing to do floating point math. - return txOut.Value*1000/(3*int64(totalSize)) < int64(minRelayTxFee) + return txOut.Value*1000/(3*uint64(totalSize)) < uint64(minRelayTxFee) } // checkTransactionStandard performs a series of checks on a transaction to diff --git a/mining/mining.go b/mining/mining.go index d319c6dec..b11050065 100644 --- a/mining/mining.go +++ b/mining/mining.go @@ -46,10 +46,10 @@ type TxDesc struct { Height int32 // Fee is the total fee the transaction associated with the entry pays. - Fee int64 + Fee uint64 // FeePerKB is the fee the transaction pays in Satoshi per 1000 bytes. - FeePerKB int64 + FeePerKB uint64 } // TxSource represents a source of transactions to consider for inclusion in @@ -76,9 +76,9 @@ type TxSource interface { // which have not been mined into a block yet. type txPrioItem struct { tx *util.Tx - fee int64 + fee uint64 priority float64 - feePerKB int64 + feePerKB uint64 // dependsOn holds a map of transaction hashes which this one depends // on. It will only be set when the transaction references other @@ -195,7 +195,7 @@ type BlockTemplate struct { // template pays in base units. Since the first transaction is the // coinbase, the first entry (offset 0) will contain the negative of the // sum of the fees of all other transactions. - Fees []int64 + Fees []uint64 // SigOpCounts contains the number of signature operations each // transaction in the generated template performs. @@ -455,9 +455,9 @@ func (g *BlkTmplGenerator) NewBlockTemplate(payToAddress util.Address) (*BlockTe // a transaction as it is selected for inclusion in the final block. // However, since the total fees aren't known yet, use a dummy value for // the coinbase fee which will be updated later. - txFees := make([]int64, 0, len(sourceTxns)) + txFees := make([]uint64, 0, len(sourceTxns)) txSigOpCounts := make([]int64, 0, len(sourceTxns)) - txFees = append(txFees, -1) // Updated once known + txFees = append(txFees, 0) // Updated once known txSigOpCounts = append(txSigOpCounts, numCoinbaseSigOps) log.Debugf("Considering %d transactions for inclusion to new block", @@ -541,7 +541,7 @@ mempoolLoop: // transaction. blockSize := blockHeaderOverhead + uint32(coinbaseTx.MsgTx().SerializeSize()) blockSigOps := numCoinbaseSigOps - totalFees := int64(0) + totalFees := uint64(0) // Choose which transactions make it into the block. for priorityQueue.Len() > 0 { @@ -595,7 +595,7 @@ mempoolLoop: // Skip free transactions once the block is larger than the // minimum block size. if sortedByFee && - prioItem.feePerKB < int64(g.policy.TxMinFreeFee) && + prioItem.feePerKB < uint64(g.policy.TxMinFreeFee) && blockPlusTxSize >= g.policy.BlockMinSize { log.Tracef("Skipping tx %s with feePerKB %.2f "+ diff --git a/mining/mining_test.go b/mining/mining_test.go index 25cc61c5a..4c0ea71d4 100644 --- a/mining/mining_test.go +++ b/mining/mining_test.go @@ -43,7 +43,7 @@ func TestTxFeePrioHeap(t *testing.T) { prng := rand.New(rand.NewSource(randSeed)) for i := 0; i < 1000; i++ { testItems = append(testItems, &txPrioItem{ - feePerKB: int64(prng.Float64() * util.SatoshiPerBitcoin), + feePerKB: uint64(prng.Float64() * util.SatoshiPerBitcoin), priority: prng.Float64() * 100, }) } diff --git a/mining/policy.go b/mining/policy.go index 32503709a..d0b8944e7 100644 --- a/mining/policy.go +++ b/mining/policy.go @@ -75,7 +75,7 @@ func calcInputValueAge(tx *wire.MsgTx, utxoSet blockdag.UTXOSet, nextBlockHeight // Sum the input value times age. inputValue := entry.Amount() - totalInputAge += float64(inputValue * int64(inputAge)) + totalInputAge += float64(inputValue * uint64(inputAge)) } } diff --git a/mining/policy_test.go b/mining/policy_test.go index aff0389c8..93bb17121 100644 --- a/mining/policy_test.go +++ b/mining/policy_test.go @@ -72,7 +72,7 @@ func createTxIn(originTx *wire.MsgTx, outputIndex uint32) *wire.TxIn { return wire.NewTxIn(prevOut, nil) } -func createTransaction(value int64, originTx *wire.MsgTx, originTxoutputIndex uint32, sigScript []byte) (*wire.MsgTx, error) { +func createTransaction(value uint64, originTx *wire.MsgTx, originTxoutputIndex uint32, sigScript []byte) (*wire.MsgTx, error) { lookupKey := func(a util.Address) (*btcec.PrivateKey, bool, error) { // Ordinarily this function would involve looking up the private // key for the provided address, but since the only thing being diff --git a/server/p2p/p2p.go b/server/p2p/p2p.go index 0353651b0..870e800a3 100644 --- a/server/p2p/p2p.go +++ b/server/p2p/p2p.go @@ -1562,7 +1562,7 @@ func (s *Server) handleRelayInvMsg(state *peerState, msg relayMsg) { // Don't relay the transaction if the transaction fee-per-kb // is less than the peer's feefilter. - feeFilter := atomic.LoadInt64(&sp.FeeFilterInt) + feeFilter := uint64(atomic.LoadInt64(&sp.FeeFilterInt)) if feeFilter > 0 && txD.FeePerKB < feeFilter { return } diff --git a/server/rpc/rpcserver.go b/server/rpc/rpcserver.go index 0816ef6a1..080665fa5 100644 --- a/server/rpc/rpcserver.go +++ b/server/rpc/rpcserver.go @@ -613,7 +613,7 @@ func handleCreateRawTransaction(s *Server, cmd interface{}, closeChan <-chan str return nil, internalRPCError(err.Error(), context) } - txOut := wire.NewTxOut(int64(satoshi), pkScript) + txOut := wire.NewTxOut(uint64(satoshi), pkScript) mtx.AddTxOut(txOut) } @@ -2544,7 +2544,7 @@ func handleGetTxOut(s *Server, cmd interface{}, closeChan <-chan struct{}) (inte // from there, otherwise attempt to fetch from the block database. var bestBlockHash string var confirmations int32 - var value int64 + var value uint64 var pkScript []byte var isCoinbase bool includeMempool := true @@ -4214,7 +4214,7 @@ func NewRPCServer( gbtWorkState: newGbtWorkState(cfg.TimeSource), helpCacher: newHelpCacher(), requestProcessShutdown: make(chan struct{}), - quit: make(chan int), + quit: make(chan int), } if config.MainConfig().RPCUser != "" && config.MainConfig().RPCPass != "" { login := config.MainConfig().RPCUser + ":" + config.MainConfig().RPCPass diff --git a/server/rpc/rpcwebsocket.go b/server/rpc/rpcwebsocket.go index 0c117b4f8..8cc2a1c7b 100644 --- a/server/rpc/rpcwebsocket.go +++ b/server/rpc/rpcwebsocket.go @@ -824,7 +824,7 @@ func (m *wsNotificationManager) notifyForNewTx(clients map[chan struct{}]*wsClie txHashStr := tx.Hash().String() mtx := tx.MsgTx() - var amount int64 + var amount uint64 for _, txOut := range mtx.TxOut { amount += txOut.Value } diff --git a/txscript/script.go b/txscript/script.go index 45791d636..69b3ab2df 100644 --- a/txscript/script.go +++ b/txscript/script.go @@ -329,7 +329,7 @@ func calcSignatureHash(script []parsedOpcode, hashType SigHashType, tx *wire.Msg // All but current output get zeroed out. for i := 0; i < idx; i++ { - txCopy.TxOut[i].Value = -1 + txCopy.TxOut[i].Value = 0 txCopy.TxOut[i].PkScript = nil } diff --git a/util/amount.go b/util/amount.go index 2a25ff780..534db9d48 100644 --- a/util/amount.go +++ b/util/amount.go @@ -51,7 +51,7 @@ func (u AmountUnit) String() string { // Amount represents the base bitcoin monetary unit (colloquially referred // to as a `Satoshi'). A single Amount is equal to 1e-8 of a bitcoin. -type Amount int64 +type Amount uint64 // round converts a floating point number, which may or may not be representable // as an integer, to the Amount integer type by rounding to the nearest integer. diff --git a/util/amount_test.go b/util/amount_test.go index d1baf0d56..f135ff9b7 100644 --- a/util/amount_test.go +++ b/util/amount_test.go @@ -31,24 +31,12 @@ func TestAmountCreation(t *testing.T) { valid: true, expected: MaxSatoshi, }, - { - name: "min producible", - amount: -21e6, - valid: true, - expected: -MaxSatoshi, - }, { name: "exceeds max producible", amount: 21e6 + 1e-8, valid: true, expected: MaxSatoshi + 1, }, - { - name: "exceeds min producible", - amount: -21e6 - 1e-8, - valid: true, - expected: -MaxSatoshi - 1, - }, { name: "one hundred", amount: 100, @@ -220,42 +208,6 @@ func TestAmountMulF64(t *testing.T) { mul: 1.02, res: 204e5, // 0.204 BTC }, - { - name: "Multiply 0.1 BTC by -2", - amt: 100e5, // 0.1 BTC - mul: -2, - res: -200e5, // -0.2 BTC - }, - { - name: "Multiply 0.2 BTC by -0.02", - amt: 200e5, // 0.2 BTC - mul: -1.02, - res: -204e5, // -0.204 BTC - }, - { - name: "Multiply -0.1 BTC by 2", - amt: -100e5, // -0.1 BTC - mul: 2, - res: -200e5, // -0.2 BTC - }, - { - name: "Multiply -0.2 BTC by 0.02", - amt: -200e5, // -0.2 BTC - mul: 1.02, - res: -204e5, // -0.204 BTC - }, - { - name: "Multiply -0.1 BTC by -2", - amt: -100e5, // -0.1 BTC - mul: -2, - res: 200e5, // 0.2 BTC - }, - { - name: "Multiply -0.2 BTC by -0.02", - amt: -200e5, // -0.2 BTC - mul: -1.02, - res: 204e5, // 0.204 BTC - }, { name: "Round down", amt: 49, // 49 Satoshis diff --git a/wire/msgtx.go b/wire/msgtx.go index 03883c088..2db4f6221 100644 --- a/wire/msgtx.go +++ b/wire/msgtx.go @@ -214,7 +214,7 @@ func NewTxIn(prevOut *OutPoint, signatureScript []byte) *TxIn { // TxOut defines a bitcoin transaction output. type TxOut struct { - Value int64 + Value uint64 PkScript []byte } @@ -228,7 +228,7 @@ func (t *TxOut) SerializeSize() int { // NewTxOut returns a new bitcoin transaction output with the provided // transaction value and public key script. -func NewTxOut(value int64, pkScript []byte) *TxOut { +func NewTxOut(value uint64, pkScript []byte) *TxOut { return &TxOut{ Value: value, PkScript: pkScript, diff --git a/wire/msgtx_test.go b/wire/msgtx_test.go index d9c4abd81..339b3f69a 100644 --- a/wire/msgtx_test.go +++ b/wire/msgtx_test.go @@ -79,7 +79,7 @@ func TestTx(t *testing.T) { } // Ensure we get the same transaction output back out. - txValue := int64(5000000000) + txValue := uint64(5000000000) pkScript := []byte{ 0x41, // OP_DATA_65 0x04, 0xd6, 0x4b, 0xdf, 0xd0, 0x9e, 0xb1, 0xc5,