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
This commit is contained in:
Evgeny Khirin 2018-10-24 16:29:50 +03:00 committed by Ori Newman
parent ac01babfb1
commit 499adbf046
24 changed files with 71 additions and 123 deletions

View File

@ -555,7 +555,7 @@ func deserializeUTXOEntry(serialized []byte) (*UTXOEntry, error) {
} }
entry := &UTXOEntry{ entry := &UTXOEntry{
amount: int64(amount), amount: amount,
pkScript: pkScript, pkScript: pkScript,
blockHeight: blockHeight, blockHeight: blockHeight,
packedFlags: 0, packedFlags: 0,

View File

@ -383,7 +383,7 @@ func additionalCoinbase(amount util.Amount) func(*wire.MsgBlock) {
return func(b *wire.MsgBlock) { return func(b *wire.MsgBlock) {
// Increase the first proof-of-work coinbase subsidy by the // Increase the first proof-of-work coinbase subsidy by the
// provided amount. // 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) { return func(b *wire.MsgBlock) {
// Increase the fee of the spending transaction by reducing the // Increase the fee of the spending transaction by reducing the
// amount paid. // 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 "+ panic(fmt.Sprintf("additionalSpendFee: fee of %d "+
"exceeds available spend transaction value", "exceeds available spend transaction value",
fee)) 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, Sequence: wire.MaxTxInSequenceNum,
SignatureScript: nil, SignatureScript: nil,
}) })
spendTx.AddTxOut(wire.NewTxOut(int64(spend.amount-fee), spendTx.AddTxOut(wire.NewTxOut(uint64(spend.amount-fee),
opTrueScript)) opTrueScript))
spendTx.AddTxOut(wire.NewTxOut(0, uniqueOpReturnScript())) 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 // Create the transaction with a fee of 1 atom for the
// miner and increase the coinbase subsidy accordingly. // miner and increase the coinbase subsidy accordingly.
fee := util.Amount(1) 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 // Create a transaction that spends from the provided spendable
// output and includes an additional unique OP_RETURN output to // output and includes an additional unique OP_RETURN output to
@ -1695,7 +1695,7 @@ func Generate(includeLargeReorg bool) (tests [][]TestInstance, err error) {
// \-> b59(17) // \-> b59(17)
g.setTip("b57") g.setTip("b57")
g.nextBlock("b59", outs[17], func(b *wire.MsgBlock) { 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) 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 // Add 4 outputs to the spending transaction that are spent
// below. // below.
const numAdditionalOutputs = 4 const numAdditionalOutputs = 4
const zeroCoin = int64(0) const zeroCoin = uint64(0)
spendTx := b.Transactions[1] spendTx := b.Transactions[1]
for i := 0; i < numAdditionalOutputs; i++ { for i := 0; i < numAdditionalOutputs; i++ {
spendTx.AddTxOut(wire.NewTxOut(zeroCoin, opTrueScript)) spendTx.AddTxOut(wire.NewTxOut(zeroCoin, opTrueScript))
@ -2032,7 +2032,7 @@ func Generate(includeLargeReorg bool) (tests [][]TestInstance, err error) {
g.setTip("b79") g.setTip("b79")
g.nextBlock("b81", outs[27], func(b *wire.MsgBlock) { g.nextBlock("b81", outs[27], func(b *wire.MsgBlock) {
const numAdditionalOutputs = 4 const numAdditionalOutputs = 4
const zeroCoin = int64(0) const zeroCoin = uint64(0)
spendTx := b.Transactions[1] spendTx := b.Transactions[1]
for i := 0; i < numAdditionalOutputs; i++ { for i := 0; i < numAdditionalOutputs; i++ {
opRetScript := uniqueOpReturnScript() opRetScript := uniqueOpReturnScript()

View File

@ -20,7 +20,7 @@ type UTXOEntry struct {
// specifically crafted to result in minimal padding. There will be a // 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. // 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. pkScript []byte // The public key script for the output.
blockHeight int32 // Height of block containing tx. blockHeight int32 // Height of block containing tx.
@ -43,7 +43,7 @@ func (entry *UTXOEntry) BlockHeight() int32 {
} }
// Amount returns the amount of the output. // Amount returns the amount of the output.
func (entry *UTXOEntry) Amount() int64 { func (entry *UTXOEntry) Amount() uint64 {
return entry.amount return entry.amount
} }

View File

@ -822,8 +822,8 @@ func createCoinbaseTx(blockHeight int32, numOutputs uint32) (*wire.MsgTx, error)
Sequence: wire.MaxTxInSequenceNum, Sequence: wire.MaxTxInSequenceNum,
}) })
totalInput := CalcBlockSubsidy(blockHeight, &dagconfig.MainNetParams) totalInput := CalcBlockSubsidy(blockHeight, &dagconfig.MainNetParams)
amountPerOutput := totalInput / int64(numOutputs) amountPerOutput := totalInput / uint64(numOutputs)
remainder := totalInput - amountPerOutput*int64(numOutputs) remainder := totalInput - amountPerOutput*uint64(numOutputs)
for i := uint32(0); i < numOutputs; i++ { for i := uint32(0); i < numOutputs; i++ {
// Ensure the final output accounts for any remainder that might // Ensure the final output accounts for any remainder that might
// be left from splitting the input amount. // be left from splitting the input amount.
@ -861,7 +861,7 @@ func TestApplyUTXOChanges(t *testing.T) {
}) })
chainedTx.AddTxOut(&wire.TxOut{ chainedTx.AddTxOut(&wire.TxOut{
PkScript: OpTrueScript, PkScript: OpTrueScript,
Value: int64(1), Value: uint64(1),
}) })
//Fake block header //Fake block header
@ -891,7 +891,7 @@ func TestApplyUTXOChanges(t *testing.T) {
}) })
nonChainedTx.AddTxOut(&wire.TxOut{ nonChainedTx.AddTxOut(&wire.TxOut{
PkScript: OpTrueScript, PkScript: OpTrueScript,
Value: int64(1), Value: uint64(1),
}) })
msgBlock2 := &wire.MsgBlock{ msgBlock2 := &wire.MsgBlock{
@ -930,7 +930,7 @@ func TestDiffFromTx(t *testing.T) {
}) })
tx.AddTxOut(&wire.TxOut{ tx.AddTxOut(&wire.TxOut{
PkScript: OpTrueScript, PkScript: OpTrueScript,
Value: int64(1), Value: uint64(1),
}) })
diff, err := fus.diffFromTx(tx, node) diff, err := fus.diffFromTx(tx, node)
if err != nil { if err != nil {
@ -957,7 +957,7 @@ func TestDiffFromTx(t *testing.T) {
}) })
invalidTx.AddTxOut(&wire.TxOut{ invalidTx.AddTxOut(&wire.TxOut{
PkScript: OpTrueScript, PkScript: OpTrueScript,
Value: int64(1), Value: uint64(1),
}) })
_, err = fus.diffFromTx(invalidTx, node) _, err = fus.diffFromTx(invalidTx, node)
if err == nil { if err == nil {

View File

@ -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 // At the target block generation rate for the main network, this is
// approximately every 4 years. // approximately every 4 years.
func CalcBlockSubsidy(height int32, dagParams *dagconfig.Params) int64 { func CalcBlockSubsidy(height int32, dagParams *dagconfig.Params) uint64 {
if dagParams.SubsidyReductionInterval == 0 { if dagParams.SubsidyReductionInterval == 0 {
return baseSubsidy return baseSubsidy
} }
@ -200,7 +200,7 @@ func CheckTransactionSanity(tx *util.Tx) error {
// restrictions. All amounts in a transaction are in a unit value known // 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 // as a satoshi. One bitcoin is a quantity of satoshi as defined by the
// SatoshiPerBitcoin constant. // SatoshiPerBitcoin constant.
var totalSatoshi int64 var totalSatoshi uint64
for _, txOut := range msgTx.TxOut { for _, txOut := range msgTx.TxOut {
satoshi := txOut.Value satoshi := txOut.Value
if satoshi < 0 { if satoshi < 0 {
@ -215,16 +215,17 @@ func CheckTransactionSanity(tx *util.Tx) error {
return ruleError(ErrBadTxOutValue, str) return ruleError(ErrBadTxOutValue, str)
} }
// Two's complement int64 overflow guarantees that any overflow // Binary arithmetic guarantees that any overflow is detected and reported.
// is detected and reported. This is impossible for Bitcoin, but // This is impossible for Bitcoin, but perhaps possible if an alt increases
// perhaps possible if an alt increases the total money supply. // the total money supply.
totalSatoshi += satoshi newTotalSatoshi := totalSatoshi + satoshi
if totalSatoshi < 0 { if newTotalSatoshi < totalSatoshi {
str := fmt.Sprintf("total value of all transaction "+ str := fmt.Sprintf("total value of all transaction "+
"outputs exceeds max allowed value of %v", "outputs exceeds max allowed value of %v",
util.MaxSatoshi) util.MaxSatoshi)
return ruleError(ErrBadTxOutValue, str) return ruleError(ErrBadTxOutValue, str)
} }
totalSatoshi = newTotalSatoshi
if totalSatoshi > util.MaxSatoshi { if totalSatoshi > util.MaxSatoshi {
str := fmt.Sprintf("total value of all transaction "+ str := fmt.Sprintf("total value of all transaction "+
"outputs is %v which is higher than max "+ "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 // NOTE: The transaction MUST have already been sanity checked with the
// CheckTransactionSanity function prior to calling this function. // 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. // Coinbase transactions have no inputs.
if IsCoinBase(tx) { if IsCoinBase(tx) {
return 0, nil return 0, nil
} }
txHash := tx.Hash() txHash := tx.Hash()
var totalSatoshiIn int64 var totalSatoshiIn uint64
for txInIndex, txIn := range tx.MsgTx().TxIn { for txInIndex, txIn := range tx.MsgTx().TxIn {
// Ensure the referenced input transaction is available. // Ensure the referenced input transaction is available.
entry, ok := utxoSet.Get(txIn.PreviousOutPoint) 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 // bitcoin is a quantity of satoshi as defined by the
// SatoshiPerBitcoin constant. // SatoshiPerBitcoin constant.
originTxSatoshi := entry.Amount() 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 { if originTxSatoshi > util.MaxSatoshi {
str := fmt.Sprintf("transaction output value of %v is "+ str := fmt.Sprintf("transaction output value of %v is "+
"higher than max allowed value of %v", "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 // Calculate the total output amount for this transaction. It is safe
// to ignore overflow and out of range errors here because those error // to ignore overflow and out of range errors here because those error
// conditions would have already been caught by checkTransactionSanity. // conditions would have already been caught by checkTransactionSanity.
var totalSatoshiOut int64 var totalSatoshiOut uint64
for _, txOut := range tx.MsgTx().TxOut { for _, txOut := range tx.MsgTx().TxOut {
totalSatoshiOut += txOut.Value 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 // still relatively cheap as compared to running the scripts) checks
// against all the inputs when the signature operations are out of // against all the inputs when the signature operations are out of
// bounds. // bounds.
var totalFees int64 var totalFees uint64
for _, tx := range transactions { for _, tx := range transactions {
txFee, err := CheckTransactionInputs(tx, node.height, dag.virtual.utxoSet, txFee, err := CheckTransactionInputs(tx, node.height, dag.virtual.utxoSet,
dag.dagParams) 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 // mining the block. It is safe to ignore overflow and out of range
// errors here because those error conditions would have already been // errors here because those error conditions would have already been
// caught by checkTransactionSanity. // caught by checkTransactionSanity.
var totalSatoshiOut int64 var totalSatoshiOut uint64
for _, txOut := range transactions[0].MsgTx().TxOut { for _, txOut := range transactions[0].MsgTx().TxOut {
totalSatoshiOut += txOut.Value totalSatoshiOut += txOut.Value
} }

View File

@ -118,7 +118,7 @@ type GetBlockTemplateResultTx struct {
Data string `json:"data"` Data string `json:"data"`
Hash string `json:"hash"` Hash string `json:"hash"`
Depends []int64 `json:"depends"` Depends []int64 `json:"depends"`
Fee int64 `json:"fee"` Fee uint64 `json:"fee"`
SigOps int64 `json:"sigops"` SigOps int64 `json:"sigops"`
} }
@ -143,7 +143,7 @@ type GetBlockTemplateResult struct {
Version int32 `json:"version"` Version int32 `json:"version"`
CoinbaseAux *GetBlockTemplateResultAux `json:"coinbaseaux,omitempty"` CoinbaseAux *GetBlockTemplateResultAux `json:"coinbaseaux,omitempty"`
CoinbaseTxn *GetBlockTemplateResultTx `json:"coinbasetxn,omitempty"` CoinbaseTxn *GetBlockTemplateResultTx `json:"coinbasetxn,omitempty"`
CoinbaseValue *int64 `json:"coinbasevalue,omitempty"` CoinbaseValue *uint64 `json:"coinbasevalue,omitempty"`
WorkID string `json:"workid,omitempty"` WorkID string `json:"workid,omitempty"`
// Optional long polling from BIP 0022. // Optional long polling from BIP 0022.

View File

@ -16,9 +16,9 @@ import (
"github.com/daglabs/btcd/dagconfig/daghash" "github.com/daglabs/btcd/dagconfig/daghash"
"github.com/daglabs/btcd/rpcclient" "github.com/daglabs/btcd/rpcclient"
"github.com/daglabs/btcd/txscript" "github.com/daglabs/btcd/txscript"
"github.com/daglabs/btcd/wire"
"github.com/daglabs/btcd/util" "github.com/daglabs/btcd/util"
"github.com/daglabs/btcd/util/hdkeychain" "github.com/daglabs/btcd/util/hdkeychain"
"github.com/daglabs/btcd/wire"
) )
var ( var (
@ -428,7 +428,7 @@ func (m *memWallet) fundTx(tx *wire.MsgTx, amt util.Amount, feeRate util.Amount)
return err return err
} }
changeOutput := &wire.TxOut{ changeOutput := &wire.TxOut{
Value: int64(changeVal), Value: uint64(changeVal),
PkScript: pkScript, PkScript: pkScript,
} }
tx.AddTxOut(changeOutput) tx.AddTxOut(changeOutput)

View File

@ -78,7 +78,7 @@ func (rate SatoshiPerByte) ToBtcPerKb() BtcPerKilobyte {
func (rate SatoshiPerByte) Fee(size uint32) util.Amount { func (rate SatoshiPerByte) Fee(size uint32) util.Amount {
// If our rate is the error value, return that. // If our rate is the error value, return that.
if rate == SatoshiPerByte(-1) { if rate == SatoshiPerByte(-1) {
return util.Amount(-1) return math.MaxUint64
} }
return util.Amount(float64(rate) * float64(size)) return util.Amount(float64(rate) * float64(size))

View File

@ -11,8 +11,8 @@ import (
"github.com/daglabs/btcd/dagconfig/daghash" "github.com/daglabs/btcd/dagconfig/daghash"
"github.com/daglabs/btcd/mining" "github.com/daglabs/btcd/mining"
"github.com/daglabs/btcd/wire"
"github.com/daglabs/btcd/util" "github.com/daglabs/btcd/util"
"github.com/daglabs/btcd/wire"
) )
// newTestFeeEstimator creates a feeEstimator with some different parameters // newTestFeeEstimator creates a feeEstimator with some different parameters
@ -54,7 +54,7 @@ func (eft *estimateFeeTester) testTx(fee util.Amount) *TxDesc {
Version: eft.version, Version: eft.version,
}), }),
Height: eft.height, Height: eft.height,
Fee: int64(fee), Fee: uint64(fee),
}, },
StartingPriority: 0, StartingPriority: 0,
} }

View File

@ -540,7 +540,7 @@ func (mp *TxPool) RemoveDoubleSpends(tx *util.Tx) {
// helper for maybeAcceptTransaction. // helper for maybeAcceptTransaction.
// //
// This function MUST be called with the mempool lock held (for writes). // 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() mp.cfg.DAG.UTXORLock()
defer mp.cfg.DAG.UTXORUnlock() defer mp.cfg.DAG.UTXORUnlock()
// Add the transaction to the pool and mark the referenced outpoints // 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(), Added: time.Now(),
Height: height, Height: height,
Fee: fee, Fee: fee,
FeePerKB: fee * 1000 / int64(tx.MsgTx().SerializeSize()), FeePerKB: fee * 1000 / uint64(tx.MsgTx().SerializeSize()),
}, },
StartingPriority: mining.CalcPriority(tx.MsgTx(), mp.mpUTXOSet, height), 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 // transaction does not exceeed 1000 less than the reserved space for
// high-priority transactions, don't require a fee for it. // high-priority transactions, don't require a fee for it.
serializedSize := int64(tx.MsgTx().SerializeSize()) serializedSize := int64(tx.MsgTx().SerializeSize())
minFee := calcMinRequiredTxRelayFee(serializedSize, minFee := uint64(calcMinRequiredTxRelayFee(serializedSize,
mp.cfg.Policy.MinRelayTxFee) mp.cfg.Policy.MinRelayTxFee))
if serializedSize >= (DefaultBlockPrioritySize-1000) && txFee < minFee { if serializedSize >= (DefaultBlockPrioritySize-1000) && txFee < minFee {
str := fmt.Sprintf("transaction %v has %d fees which is under "+ str := fmt.Sprintf("transaction %v has %d fees which is under "+
"the required amount of %d", txHash, txFee, "the required amount of %d", txHash, txFee,

View File

@ -134,8 +134,8 @@ func (p *poolHarness) CreateCoinbaseTx(blockHeight int32, numOutputs uint32) (*u
Sequence: wire.MaxTxInSequenceNum, Sequence: wire.MaxTxInSequenceNum,
}) })
totalInput := blockdag.CalcBlockSubsidy(blockHeight, p.chainParams) totalInput := blockdag.CalcBlockSubsidy(blockHeight, p.chainParams)
amountPerOutput := totalInput / int64(numOutputs) amountPerOutput := totalInput / uint64(numOutputs)
remainder := totalInput - amountPerOutput*int64(numOutputs) remainder := totalInput - amountPerOutput*uint64(numOutputs)
for i := uint32(0); i < numOutputs; i++ { for i := uint32(0); i < numOutputs; i++ {
// Ensure the final output accounts for any remainder that might // Ensure the final output accounts for any remainder that might
// be left from splitting the input amount. // be left from splitting the input amount.
@ -163,8 +163,8 @@ func (p *poolHarness) CreateSignedTx(inputs []spendableOutpoint, numOutputs uint
for _, input := range inputs { for _, input := range inputs {
totalInput += input.amount totalInput += input.amount
} }
amountPerOutput := int64(totalInput) / int64(numOutputs) amountPerOutput := uint64(totalInput) / uint64(numOutputs)
remainder := int64(totalInput) - amountPerOutput*int64(numOutputs) remainder := uint64(totalInput) - amountPerOutput*uint64(numOutputs)
tx := wire.NewMsgTx(wire.TxVersion) tx := wire.NewMsgTx(wire.TxVersion)
for _, input := range inputs { for _, input := range inputs {
@ -220,7 +220,7 @@ func (p *poolHarness) CreateTxChain(firstOutput spendableOutpoint, numTxns uint3
}) })
tx.AddTxOut(&wire.TxOut{ tx.AddTxOut(&wire.TxOut{
PkScript: p.payScript, PkScript: p.payScript,
Value: int64(spendableAmount), Value: uint64(spendableAmount),
}) })
// Sign the new transaction. // 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 := wire.NewMsgTx(wire.TxVersion)
tx.AddTxIn(&wire.TxIn{ tx.AddTxIn(&wire.TxIn{
PreviousOutPoint: outpoint.outPoint, PreviousOutPoint: outpoint.outPoint,
SignatureScript: nil, SignatureScript: nil,
Sequence: wire.MaxTxInSequenceNum, Sequence: wire.MaxTxInSequenceNum,
}) })
amountPerOutput := (int64(outpoint.amount) - fee) / numOutputs amountPerOutput := (uint64(outpoint.amount) - fee) / uint64(numOutputs)
for i := int64(0); i < numOutputs; i++ { for i := int64(0); i < numOutputs; i++ {
tx.AddTxOut(&wire.TxOut{ tx.AddTxOut(&wire.TxOut{
PkScript: p.payScript, PkScript: p.payScript,

View File

@ -235,7 +235,7 @@ func isDust(txOut *wire.TxOut, minRelayTxFee util.Amount) bool {
// //
// The following is equivalent to (value/totalSize) * (1/3) * 1000 // The following is equivalent to (value/totalSize) * (1/3) * 1000
// without needing to do floating point math. // 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 // checkTransactionStandard performs a series of checks on a transaction to

View File

@ -46,10 +46,10 @@ type TxDesc struct {
Height int32 Height int32
// Fee is the total fee the transaction associated with the entry pays. // 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 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 // 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. // which have not been mined into a block yet.
type txPrioItem struct { type txPrioItem struct {
tx *util.Tx tx *util.Tx
fee int64 fee uint64
priority float64 priority float64
feePerKB int64 feePerKB uint64
// dependsOn holds a map of transaction hashes which this one depends // dependsOn holds a map of transaction hashes which this one depends
// on. It will only be set when the transaction references other // 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 // template pays in base units. Since the first transaction is the
// coinbase, the first entry (offset 0) will contain the negative of the // coinbase, the first entry (offset 0) will contain the negative of the
// sum of the fees of all other transactions. // sum of the fees of all other transactions.
Fees []int64 Fees []uint64
// SigOpCounts contains the number of signature operations each // SigOpCounts contains the number of signature operations each
// transaction in the generated template performs. // 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. // 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 // However, since the total fees aren't known yet, use a dummy value for
// the coinbase fee which will be updated later. // 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)) txSigOpCounts := make([]int64, 0, len(sourceTxns))
txFees = append(txFees, -1) // Updated once known txFees = append(txFees, 0) // Updated once known
txSigOpCounts = append(txSigOpCounts, numCoinbaseSigOps) txSigOpCounts = append(txSigOpCounts, numCoinbaseSigOps)
log.Debugf("Considering %d transactions for inclusion to new block", log.Debugf("Considering %d transactions for inclusion to new block",
@ -541,7 +541,7 @@ mempoolLoop:
// transaction. // transaction.
blockSize := blockHeaderOverhead + uint32(coinbaseTx.MsgTx().SerializeSize()) blockSize := blockHeaderOverhead + uint32(coinbaseTx.MsgTx().SerializeSize())
blockSigOps := numCoinbaseSigOps blockSigOps := numCoinbaseSigOps
totalFees := int64(0) totalFees := uint64(0)
// Choose which transactions make it into the block. // Choose which transactions make it into the block.
for priorityQueue.Len() > 0 { for priorityQueue.Len() > 0 {
@ -595,7 +595,7 @@ mempoolLoop:
// Skip free transactions once the block is larger than the // Skip free transactions once the block is larger than the
// minimum block size. // minimum block size.
if sortedByFee && if sortedByFee &&
prioItem.feePerKB < int64(g.policy.TxMinFreeFee) && prioItem.feePerKB < uint64(g.policy.TxMinFreeFee) &&
blockPlusTxSize >= g.policy.BlockMinSize { blockPlusTxSize >= g.policy.BlockMinSize {
log.Tracef("Skipping tx %s with feePerKB %.2f "+ log.Tracef("Skipping tx %s with feePerKB %.2f "+

View File

@ -43,7 +43,7 @@ func TestTxFeePrioHeap(t *testing.T) {
prng := rand.New(rand.NewSource(randSeed)) prng := rand.New(rand.NewSource(randSeed))
for i := 0; i < 1000; i++ { for i := 0; i < 1000; i++ {
testItems = append(testItems, &txPrioItem{ testItems = append(testItems, &txPrioItem{
feePerKB: int64(prng.Float64() * util.SatoshiPerBitcoin), feePerKB: uint64(prng.Float64() * util.SatoshiPerBitcoin),
priority: prng.Float64() * 100, priority: prng.Float64() * 100,
}) })
} }

View File

@ -75,7 +75,7 @@ func calcInputValueAge(tx *wire.MsgTx, utxoSet blockdag.UTXOSet, nextBlockHeight
// Sum the input value times age. // Sum the input value times age.
inputValue := entry.Amount() inputValue := entry.Amount()
totalInputAge += float64(inputValue * int64(inputAge)) totalInputAge += float64(inputValue * uint64(inputAge))
} }
} }

View File

@ -72,7 +72,7 @@ func createTxIn(originTx *wire.MsgTx, outputIndex uint32) *wire.TxIn {
return wire.NewTxIn(prevOut, nil) 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) { lookupKey := func(a util.Address) (*btcec.PrivateKey, bool, error) {
// Ordinarily this function would involve looking up the private // Ordinarily this function would involve looking up the private
// key for the provided address, but since the only thing being // key for the provided address, but since the only thing being

View File

@ -1562,7 +1562,7 @@ func (s *Server) handleRelayInvMsg(state *peerState, msg relayMsg) {
// Don't relay the transaction if the transaction fee-per-kb // Don't relay the transaction if the transaction fee-per-kb
// is less than the peer's feefilter. // is less than the peer's feefilter.
feeFilter := atomic.LoadInt64(&sp.FeeFilterInt) feeFilter := uint64(atomic.LoadInt64(&sp.FeeFilterInt))
if feeFilter > 0 && txD.FeePerKB < feeFilter { if feeFilter > 0 && txD.FeePerKB < feeFilter {
return return
} }

View File

@ -613,7 +613,7 @@ func handleCreateRawTransaction(s *Server, cmd interface{}, closeChan <-chan str
return nil, internalRPCError(err.Error(), context) return nil, internalRPCError(err.Error(), context)
} }
txOut := wire.NewTxOut(int64(satoshi), pkScript) txOut := wire.NewTxOut(uint64(satoshi), pkScript)
mtx.AddTxOut(txOut) 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. // from there, otherwise attempt to fetch from the block database.
var bestBlockHash string var bestBlockHash string
var confirmations int32 var confirmations int32
var value int64 var value uint64
var pkScript []byte var pkScript []byte
var isCoinbase bool var isCoinbase bool
includeMempool := true includeMempool := true
@ -4214,7 +4214,7 @@ func NewRPCServer(
gbtWorkState: newGbtWorkState(cfg.TimeSource), gbtWorkState: newGbtWorkState(cfg.TimeSource),
helpCacher: newHelpCacher(), helpCacher: newHelpCacher(),
requestProcessShutdown: make(chan struct{}), requestProcessShutdown: make(chan struct{}),
quit: make(chan int), quit: make(chan int),
} }
if config.MainConfig().RPCUser != "" && config.MainConfig().RPCPass != "" { if config.MainConfig().RPCUser != "" && config.MainConfig().RPCPass != "" {
login := config.MainConfig().RPCUser + ":" + config.MainConfig().RPCPass login := config.MainConfig().RPCUser + ":" + config.MainConfig().RPCPass

View File

@ -824,7 +824,7 @@ func (m *wsNotificationManager) notifyForNewTx(clients map[chan struct{}]*wsClie
txHashStr := tx.Hash().String() txHashStr := tx.Hash().String()
mtx := tx.MsgTx() mtx := tx.MsgTx()
var amount int64 var amount uint64
for _, txOut := range mtx.TxOut { for _, txOut := range mtx.TxOut {
amount += txOut.Value amount += txOut.Value
} }

View File

@ -329,7 +329,7 @@ func calcSignatureHash(script []parsedOpcode, hashType SigHashType, tx *wire.Msg
// All but current output get zeroed out. // All but current output get zeroed out.
for i := 0; i < idx; i++ { for i := 0; i < idx; i++ {
txCopy.TxOut[i].Value = -1 txCopy.TxOut[i].Value = 0
txCopy.TxOut[i].PkScript = nil txCopy.TxOut[i].PkScript = nil
} }

View File

@ -51,7 +51,7 @@ func (u AmountUnit) String() string {
// Amount represents the base bitcoin monetary unit (colloquially referred // Amount represents the base bitcoin monetary unit (colloquially referred
// to as a `Satoshi'). A single Amount is equal to 1e-8 of a bitcoin. // 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 // 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. // as an integer, to the Amount integer type by rounding to the nearest integer.

View File

@ -31,24 +31,12 @@ func TestAmountCreation(t *testing.T) {
valid: true, valid: true,
expected: MaxSatoshi, expected: MaxSatoshi,
}, },
{
name: "min producible",
amount: -21e6,
valid: true,
expected: -MaxSatoshi,
},
{ {
name: "exceeds max producible", name: "exceeds max producible",
amount: 21e6 + 1e-8, amount: 21e6 + 1e-8,
valid: true, valid: true,
expected: MaxSatoshi + 1, expected: MaxSatoshi + 1,
}, },
{
name: "exceeds min producible",
amount: -21e6 - 1e-8,
valid: true,
expected: -MaxSatoshi - 1,
},
{ {
name: "one hundred", name: "one hundred",
amount: 100, amount: 100,
@ -220,42 +208,6 @@ func TestAmountMulF64(t *testing.T) {
mul: 1.02, mul: 1.02,
res: 204e5, // 0.204 BTC 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", name: "Round down",
amt: 49, // 49 Satoshis amt: 49, // 49 Satoshis

View File

@ -214,7 +214,7 @@ func NewTxIn(prevOut *OutPoint, signatureScript []byte) *TxIn {
// TxOut defines a bitcoin transaction output. // TxOut defines a bitcoin transaction output.
type TxOut struct { type TxOut struct {
Value int64 Value uint64
PkScript []byte PkScript []byte
} }
@ -228,7 +228,7 @@ func (t *TxOut) SerializeSize() int {
// NewTxOut returns a new bitcoin transaction output with the provided // NewTxOut returns a new bitcoin transaction output with the provided
// transaction value and public key script. // transaction value and public key script.
func NewTxOut(value int64, pkScript []byte) *TxOut { func NewTxOut(value uint64, pkScript []byte) *TxOut {
return &TxOut{ return &TxOut{
Value: value, Value: value,
PkScript: pkScript, PkScript: pkScript,

View File

@ -79,7 +79,7 @@ func TestTx(t *testing.T) {
} }
// Ensure we get the same transaction output back out. // Ensure we get the same transaction output back out.
txValue := int64(5000000000) txValue := uint64(5000000000)
pkScript := []byte{ pkScript := []byte{
0x41, // OP_DATA_65 0x41, // OP_DATA_65
0x04, 0xd6, 0x4b, 0xdf, 0xd0, 0x9e, 0xb1, 0xc5, 0x04, 0xd6, 0x4b, 0xdf, 0xd0, 0x9e, 0xb1, 0xc5,