diff --git a/blockchain/chain.go b/blockchain/chain.go index d26b822a2..97a4fcbe8 100644 --- a/blockchain/chain.go +++ b/blockchain/chain.go @@ -447,7 +447,7 @@ func (b *BlockChain) calcSequenceLock(node *blockNode, tx *btcutil.Tx, utxoView // number in accordance to BIP-68. // See: https://github.com/bitcoin/bips/blob/master/bip-0068.mediawiki // * (Compatibility) -func LockTimeToSequence(isSeconds bool, locktime int64) int64 { +func LockTimeToSequence(isSeconds bool, locktime uint64) uint64 { // If we're expressing the relative lock time in blocks, then the // corresponding sequence number is simply the desired input age. if !isSeconds { diff --git a/blockchain/chainio.go b/blockchain/chainio.go index 346b4b859..e56ff0edd 100644 --- a/blockchain/chainio.go +++ b/blockchain/chainio.go @@ -497,7 +497,7 @@ func dbRemoveSpendJournalEntry(dbTx database.Tx, blockHash *chainhash.Hash) erro // // Example 1: // From tx in main blockchain: -// Blk 1, c52c57dcdaa5cbfd39ef73afb78b1fbb1e856f557dd5f8b53c49acbf21eb387a:0 +// Blk 1, b7c3332bc138e2c9429818f5fed500bcc1746544218772389054dc8047d7cd3f:0 // // 03320496b538e853519c726a2c91e61ec11600ae1390813a627c66fb8be7947be63c52 // <><------------------------------------------------------------------> diff --git a/blockchain/chainio_test.go b/blockchain/chainio_test.go index a8ec73fc3..e2572d3a9 100644 --- a/blockchain/chainio_test.go +++ b/blockchain/chainio_test.go @@ -7,6 +7,7 @@ package blockchain import ( "bytes" "errors" + "math" "math/big" "reflect" "testing" @@ -236,7 +237,7 @@ func TestSpendJournalSerialization(t *testing.T) { Index: 0, }, SignatureScript: hexToBytes("47304402204e45e16932b8af514961a1d3a1a25fdf3f4f7732e9d624c6c61548ab5fb8cd410220181522ec8eca07de4860a4acdd12909d831cc56cbbac4622082221a8768d1d0901"), - Sequence: 0xffffffff, + Sequence: math.MaxUint64, }}, TxOut: []*wire.TxOut{{ Value: 1000000000, @@ -271,7 +272,7 @@ func TestSpendJournalSerialization(t *testing.T) { Index: 1, }, SignatureScript: hexToBytes("493046022100c167eead9840da4a033c9a56470d7794a9bb1605b377ebe5688499b39f94be59022100fb6345cab4324f9ea0b9ee9169337534834638d818129778370f7d378ee4a325014104d962cac5390f12ddb7539507065d0def320d68c040f2e73337c3a1aaaab7195cb5c4d02e0959624d534f3c10c3cf3d73ca5065ebd62ae986b04c6d090d32627c"), - Sequence: 0xffffffff, + Sequence: math.MaxUint64, }}, TxOut: []*wire.TxOut{{ Value: 5000000, @@ -289,7 +290,7 @@ func TestSpendJournalSerialization(t *testing.T) { Index: 0, }, SignatureScript: hexToBytes("483045022100e256743154c097465cf13e89955e1c9ff2e55c46051b627751dee0144183157e02201d8d4f02cde8496aae66768f94d35ce54465bd4ae8836004992d3216a93a13f00141049d23ce8686fe9b802a7a938e8952174d35dd2c2089d4112001ed8089023ab4f93a3c9fcd5bfeaa9727858bf640dc1b1c05ec3b434bb59837f8640e8810e87742"), - Sequence: 0xffffffff, + Sequence: math.MaxUint64, }}, TxOut: []*wire.TxOut{{ Value: 5000000, @@ -356,7 +357,7 @@ func TestSpendJournalErrors(t *testing.T) { Index: 0, }, SignatureScript: hexToBytes("47304402204e45e16932b8af514961a1d3a1a25fdf3f4f7732e9d624c6c61548ab5fb8cd410220181522ec8eca07de4860a4acdd12909d831cc56cbbac4622082221a8768d1d0901"), - Sequence: 0xffffffff, + Sequence: math.MaxUint64, }}, LockTime: 0, }}, @@ -373,7 +374,7 @@ func TestSpendJournalErrors(t *testing.T) { Index: 0, }, SignatureScript: hexToBytes("47304402204e45e16932b8af514961a1d3a1a25fdf3f4f7732e9d624c6c61548ab5fb8cd410220181522ec8eca07de4860a4acdd12909d831cc56cbbac4622082221a8768d1d0901"), - Sequence: 0xffffffff, + Sequence: math.MaxUint64, }}, LockTime: 0, }}, @@ -413,7 +414,7 @@ func TestUtxoSerialization(t *testing.T) { serialized []byte }{ // From tx in main blockchain: - // c52c57dcdaa5cbfd39ef73afb78b1fbb1e856f557dd5f8b53c49acbf21eb387a:0 + // b7c3332bc138e2c9429818f5fed500bcc1746544218772389054dc8047d7cd3f:0 { name: "height 1, coinbase", entry: &UtxoEntry{ @@ -425,7 +426,7 @@ func TestUtxoSerialization(t *testing.T) { serialized: hexToBytes("03320496b538e853519c726a2c91e61ec11600ae1390813a627c66fb8be7947be63c52"), }, // From tx in main blockchain: - // c52c57dcdaa5cbfd39ef73afb78b1fbb1e856f557dd5f8b53c49acbf21eb387a:0 + // b7c3332bc138e2c9429818f5fed500bcc1746544218772389054dc8047d7cd3f:0 { name: "height 1, coinbase, spent", entry: &UtxoEntry{ diff --git a/blockchain/fullblocktests/params.go b/blockchain/fullblocktests/params.go index 49c4cfa56..2206f3302 100644 --- a/blockchain/fullblocktests/params.go +++ b/blockchain/fullblocktests/params.go @@ -6,6 +6,7 @@ package fullblocktests import ( "encoding/hex" + "math" "math/big" "time" @@ -70,7 +71,7 @@ var ( "32303039204368616e63656c6c6f72206f" + "6e206272696e6b206f66207365636f6e64" + "206261696c6f757420666f72206261686b73"), - Sequence: 0xffffffff, + Sequence: math.MaxUint64, }}, TxOut: []*wire.TxOut{{ Value: 0, diff --git a/blockchain/upgrade.go b/blockchain/upgrade.go index ef6a0eb68..40a3ca67c 100644 --- a/blockchain/upgrade.go +++ b/blockchain/upgrade.go @@ -267,7 +267,7 @@ func determineMainChainBlocks(blocksMap map[chainhash.Hash]*blockChainContext, t // // Example 1: // From tx in main blockchain: -// Blk 1, c52c57dcdaa5cbfd39ef73afb78b1fbb1e856f557dd5f8b53c49acbf21eb387a +// Blk 1, b7c3332bc138e2c9429818f5fed500bcc1746544218772389054dc8047d7cd3f // // 010103320496b538e853519c726a2c91e61ec11600ae1390813a627c66fb8be7947be63c52 // <><><><------------------------------------------------------------------> diff --git a/blockchain/upgrade_test.go b/blockchain/upgrade_test.go index 134453883..67a10085f 100644 --- a/blockchain/upgrade_test.go +++ b/blockchain/upgrade_test.go @@ -18,7 +18,7 @@ func TestDeserializeUtxoEntryV0(t *testing.T) { serialized []byte }{ // From tx in main blockchain: - // c52c57dcdaa5cbfd39ef73afb78b1fbb1e856f557dd5f8b53c49acbf21eb387a + // b7c3332bc138e2c9429818f5fed500bcc1746544218772389054dc8047d7cd3f { name: "Only output 0, coinbase", entries: map[uint32]*UtxoEntry{ diff --git a/blockchain/validate.go b/blockchain/validate.go index 7604dc4d7..3be4e0d58 100644 --- a/blockchain/validate.go +++ b/blockchain/validate.go @@ -167,7 +167,7 @@ func IsFinalizedTransaction(tx *btcutil.Tx, blockHeight int32, blockTime time.Ti // the transaction might still be finalized if the sequence number // for all transaction inputs is maxed out. for _, txIn := range msgTx.TxIn { - if txIn.Sequence != math.MaxUint32 { + if txIn.Sequence != math.MaxUint64 { return false } } diff --git a/blockchain/validate_test.go b/blockchain/validate_test.go index 6a2dc0219..ddce9e928 100644 --- a/blockchain/validate_test.go +++ b/blockchain/validate_test.go @@ -267,7 +267,7 @@ var Block100000 = wire.MsgBlock{ SignatureScript: []byte{ 0x04, 0x4c, 0x86, 0x04, 0x1b, 0x02, 0x06, 0x02, }, - Sequence: 0xffffffff, + Sequence: math.MaxUint64, }, }, TxOut: []*wire.TxOut{ @@ -326,7 +326,7 @@ var Block100000 = wire.MsgBlock{ 0xc6, 0xf8, 0xa6, 0x30, 0x12, 0x1d, 0xf2, 0xb3, 0xd3, // 65-byte pubkey }, - Sequence: 0xffffffff, + Sequence: math.MaxUint64, }, }, TxOut: []*wire.TxOut{ @@ -394,7 +394,7 @@ var Block100000 = wire.MsgBlock{ 0x60, 0x63, 0x9d, 0xb4, 0x62, 0xe9, 0xcb, 0x85, 0x0f, // 65-byte pubkey }, - Sequence: 0xffffffff, + Sequence: math.MaxUint64, }, }, TxOut: []*wire.TxOut{ @@ -463,7 +463,7 @@ var Block100000 = wire.MsgBlock{ 0x6a, 0xf4, 0xcf, 0xaa, 0xea, 0x4e, 0xa1, 0x4f, 0xbb, // 65-byte pubkey }, - Sequence: 0xffffffff, + Sequence: math.MaxUint64, }, }, TxOut: []*wire.TxOut{ diff --git a/btcjson/chainsvrcmds.go b/btcjson/chainsvrcmds.go index 3a64d135a..cb9c74236 100644 --- a/btcjson/chainsvrcmds.go +++ b/btcjson/chainsvrcmds.go @@ -57,7 +57,7 @@ type TransactionInput struct { type CreateRawTransactionCmd struct { Inputs []TransactionInput Amounts map[string]float64 `jsonrpcusage:"{\"address\":amount,...}"` // In BTC - LockTime *int64 + LockTime *uint64 } // NewCreateRawTransactionCmd returns a new instance which can be used to issue @@ -65,7 +65,7 @@ type CreateRawTransactionCmd struct { // // Amounts are in BTC. func NewCreateRawTransactionCmd(inputs []TransactionInput, amounts map[string]float64, - lockTime *int64) *CreateRawTransactionCmd { + lockTime *uint64) *CreateRawTransactionCmd { return &CreateRawTransactionCmd{ Inputs: inputs, diff --git a/btcjson/chainsvrcmds_test.go b/btcjson/chainsvrcmds_test.go index e45c7cd17..f01877ff5 100644 --- a/btcjson/chainsvrcmds_test.go +++ b/btcjson/chainsvrcmds_test.go @@ -77,7 +77,7 @@ func TestChainSvrCmds(t *testing.T) { unmarshalled: &btcjson.CreateRawTransactionCmd{ Inputs: []btcjson.TransactionInput{{Txid: "123", Vout: 1}}, Amounts: map[string]float64{"456": .0123}, - LockTime: btcjson.Int64(12312333333), + LockTime: btcjson.Uint64(12312333333), }, }, diff --git a/btcjson/chainsvrresults.go b/btcjson/chainsvrresults.go index 973afd8bc..1b4e7e2e8 100644 --- a/btcjson/chainsvrresults.go +++ b/btcjson/chainsvrresults.go @@ -307,7 +307,7 @@ type Vin struct { Txid string `json:"txid"` Vout uint32 `json:"vout"` ScriptSig *ScriptSig `json:"scriptSig"` - Sequence uint32 `json:"sequence"` + Sequence uint64 `json:"sequence"` } // IsCoinBase returns a bool to show if a Vin is a Coinbase one or not. @@ -320,7 +320,7 @@ func (v *Vin) MarshalJSON() ([]byte, error) { if v.IsCoinBase() { coinbaseStruct := struct { Coinbase string `json:"coinbase"` - Sequence uint32 `json:"sequence"` + Sequence uint64 `json:"sequence"` }{ Coinbase: v.Coinbase, Sequence: v.Sequence, @@ -332,7 +332,7 @@ func (v *Vin) MarshalJSON() ([]byte, error) { Txid string `json:"txid"` Vout uint32 `json:"vout"` ScriptSig *ScriptSig `json:"scriptSig"` - Sequence uint32 `json:"sequence"` + Sequence uint64 `json:"sequence"` }{ Txid: v.Txid, Vout: v.Vout, @@ -355,7 +355,7 @@ type VinPrevOut struct { Vout uint32 `json:"vout"` ScriptSig *ScriptSig `json:"scriptSig"` PrevOut *PrevOut `json:"prevOut"` - Sequence uint32 `json:"sequence"` + Sequence uint64 `json:"sequence"` } // IsCoinBase returns a bool to show if a Vin is a Coinbase one or not. @@ -368,7 +368,7 @@ func (v *VinPrevOut) MarshalJSON() ([]byte, error) { if v.IsCoinBase() { coinbaseStruct := struct { Coinbase string `json:"coinbase"` - Sequence uint32 `json:"sequence"` + Sequence uint64 `json:"sequence"` }{ Coinbase: v.Coinbase, Sequence: v.Sequence, @@ -381,7 +381,7 @@ func (v *VinPrevOut) MarshalJSON() ([]byte, error) { Vout uint32 `json:"vout"` ScriptSig *ScriptSig `json:"scriptSig"` PrevOut *PrevOut `json:"prevOut,omitempty"` - Sequence uint32 `json:"sequence"` + Sequence uint64 `json:"sequence"` }{ Txid: v.Txid, Vout: v.Vout, @@ -444,13 +444,13 @@ type TxRawResult struct { Hash string `json:"hash,omitempty"` Size int32 `json:"size,omitempty"` Version int32 `json:"version"` - LockTime int64 `json:"locktime"` + LockTime uint64 `json:"locktime"` Vin []Vin `json:"vin"` Vout []Vout `json:"vout"` BlockHash string `json:"blockhash,omitempty"` Confirmations uint64 `json:"confirmations,omitempty"` Time int64 `json:"time,omitempty"` - Blocktime int64 `json:"blocktime,omitempty"` + Blocktime uint64 `json:"blocktime,omitempty"` } // SearchRawTransactionsResult models the data from the searchrawtransaction @@ -461,20 +461,20 @@ type SearchRawTransactionsResult struct { Hash string `json:"hash"` Size string `json:"size"` Version int32 `json:"version"` - LockTime int64 `json:"locktime"` + LockTime uint64 `json:"locktime"` Vin []VinPrevOut `json:"vin"` Vout []Vout `json:"vout"` BlockHash string `json:"blockhash,omitempty"` Confirmations uint64 `json:"confirmations,omitempty"` - Time int64 `json:"time,omitempty"` - Blocktime int64 `json:"blocktime,omitempty"` + Time uint64 `json:"time,omitempty"` + Blocktime uint64 `json:"blocktime,omitempty"` } // TxRawDecodeResult models the data from the decoderawtransaction command. type TxRawDecodeResult struct { Txid string `json:"txid"` Version int32 `json:"version"` - Locktime int64 `json:"locktime"` + Locktime uint64 `json:"locktime"` Vin []Vin `json:"vin"` Vout []Vout `json:"vout"` } diff --git a/btcjson/walletsvrresults.go b/btcjson/walletsvrresults.go index 9246d131a..a7401dcce 100644 --- a/btcjson/walletsvrresults.go +++ b/btcjson/walletsvrresults.go @@ -26,7 +26,7 @@ type GetTransactionResult struct { Confirmations int64 `json:"confirmations"` BlockHash string `json:"blockhash"` BlockIndex int64 `json:"blockindex"` - BlockTime int64 `json:"blocktime"` + BlockTime uint64 `json:"blocktime"` TxID string `json:"txid"` WalletConflicts []string `json:"walletconflicts"` Time int64 `json:"time"` @@ -65,7 +65,7 @@ type ListTransactionsResult struct { BIP125Replaceable string `json:"bip125-replaceable,omitempty"` BlockHash string `json:"blockhash,omitempty"` BlockIndex *int64 `json:"blockindex,omitempty"` - BlockTime int64 `json:"blocktime,omitempty"` + BlockTime uint64 `json:"blocktime,omitempty"` Category string `json:"category"` Confirmations int64 `json:"confirmations"` Fee *float64 `json:"fee,omitempty"` @@ -125,7 +125,7 @@ type SignRawTransactionError struct { TxID string `json:"txid"` Vout uint32 `json:"vout"` ScriptSig string `json:"scriptSig"` - Sequence uint32 `json:"sequence"` + Sequence uint64 `json:"sequence"` Error string `json:"error"` } diff --git a/chaincfg/genesis.go b/chaincfg/genesis.go index 3d768ad18..3d52b0437 100644 --- a/chaincfg/genesis.go +++ b/chaincfg/genesis.go @@ -5,6 +5,7 @@ package chaincfg import ( + "math" "time" "github.com/daglabs/btcd/chaincfg/chainhash" @@ -33,7 +34,7 @@ var genesisCoinbaseTx = wire.MsgTx{ 0x6f, 0x75, 0x74, 0x20, 0x66, 0x6f, 0x72, 0x20, /* |out for |*/ 0x62, 0x61, 0x6e, 0x6b, 0x73, /* |banks| */ }, - Sequence: 0xffffffff, + Sequence: math.MaxUint64, }, }, TxOut: []*wire.TxOut{ diff --git a/integration/csv_test.go b/integration/csv_test.go index 203f374bd..c50f4a098 100644 --- a/integration/csv_test.go +++ b/integration/csv_test.go @@ -245,7 +245,7 @@ func createCSVOutput(r *rpctest.Harness, t *testing.T, sequenceLock := blockchain.LockTimeToSequence(isSeconds, int64(timeLock)) - // Our CSV script is simply: OP_CSV OP_DROP + // Our CSV script is simply: OP_CSV b := txscript.NewScriptBuilder(). AddInt64(int64(sequenceLock)). AddOp(txscript.OpCheckSequenceVerify) @@ -293,7 +293,7 @@ func createCSVOutput(r *rpctest.Harness, t *testing.T, // function. The sigScript is a trivial push of OP_TRUE followed by the // redeemScript to pass P2SH evaluation. func spendCSVOutput(redeemScript []byte, csvUTXO *wire.OutPoint, - sequence uint32, targetOutput *wire.TxOut, + sequence uint64, targetOutput *wire.TxOut, txVersion int32) (*wire.MsgTx, error) { tx := wire.NewMsgTx(txVersion) @@ -456,7 +456,7 @@ func TestBIP0068AndCsv(t *testing.T) { // A helper function to create fully signed transactions in-line during // the array initialization below. var inputIndex uint32 - makeTxCase := func(sequenceNum uint32, txVersion int32) *wire.MsgTx { + makeTxCase := func(sequenceNum uint64, txVersion int32) *wire.MsgTx { csvInput := spendableInputs[inputIndex] tx, err := spendCSVOutput(csvInput.RedeemScript, csvInput.Utxo, diff --git a/mining/policy_test.go b/mining/policy_test.go index 09da443a4..01eebd6ae 100644 --- a/mining/policy_test.go +++ b/mining/policy_test.go @@ -6,6 +6,7 @@ package mining import ( "encoding/hex" + "math" "testing" "github.com/daglabs/btcd/blockchain" @@ -69,7 +70,7 @@ func TestCalcPriority(t *testing.T) { Index: wire.MaxPrevOutIndex, }, SignatureScript: hexToBytes("04ffff001d0134"), - Sequence: 0xffffffff, + Sequence: math.MaxUint64, }}, TxOut: []*wire.TxOut{{ Value: 5000000000, @@ -98,7 +99,7 @@ func TestCalcPriority(t *testing.T) { "514961a1d3a1a25fdf3f4f7732e9d624c6c61548ab5f" + "b8cd410220181522ec8eca07de4860a4acdd12909d83" + "1cc56cbbac4622082221a8768d1d0901"), - Sequence: 0xffffffff, + Sequence: math.MaxUint64, }}, TxOut: []*wire.TxOut{{ Value: 1000000000, diff --git a/peer/log.go b/peer/log.go index ed3e83d55..5b1244f1e 100644 --- a/peer/log.go +++ b/peer/log.go @@ -65,7 +65,7 @@ func directionString(inbound bool) string { } // formatLockTime returns a transaction lock time as a human-readable string. -func formatLockTime(lockTime int64) string { +func formatLockTime(lockTime uint64) string { // The lock time field of a transaction is either a block height at // which the transaction is finalized or a timestamp depending on if the // value is before the lockTimeThreshold. When it is under the diff --git a/rpcclient/rawtransactions.go b/rpcclient/rawtransactions.go index d7264a3c3..759b81f7d 100644 --- a/rpcclient/rawtransactions.go +++ b/rpcclient/rawtransactions.go @@ -239,7 +239,7 @@ func (r FutureCreateRawTransactionResult) Receive() (*wire.MsgTx, error) { // // See CreateRawTransaction for the blocking version and more details. func (c *Client) CreateRawTransactionAsync(inputs []btcjson.TransactionInput, - amounts map[btcutil.Address]btcutil.Amount, lockTime *int64) FutureCreateRawTransactionResult { + amounts map[btcutil.Address]btcutil.Amount, lockTime *uint64) FutureCreateRawTransactionResult { convertedAmts := make(map[string]float64, len(amounts)) for addr, amount := range amounts { @@ -252,7 +252,7 @@ func (c *Client) CreateRawTransactionAsync(inputs []btcjson.TransactionInput, // CreateRawTransaction returns a new transaction spending the provided inputs // and sending to the provided addresses. func (c *Client) CreateRawTransaction(inputs []btcjson.TransactionInput, - amounts map[btcutil.Address]btcutil.Amount, lockTime *int64) (*wire.MsgTx, error) { + amounts map[btcutil.Address]btcutil.Amount, lockTime *uint64) (*wire.MsgTx, error) { return c.CreateRawTransactionAsync(inputs, amounts, lockTime).Receive() } diff --git a/rpcserver.go b/rpcserver.go index a27c52203..afe94d07a 100644 --- a/rpcserver.go +++ b/rpcserver.go @@ -514,7 +514,7 @@ func handleCreateRawTransaction(s *rpcServer, cmd interface{}, closeChan <-chan // Validate the locktime, if given. if c.LockTime != nil && - (*c.LockTime < 0 || *c.LockTime > int64(wire.MaxTxInSequenceNum)) { + (*c.LockTime < 0 || *c.LockTime > wire.MaxTxInSequenceNum) { return nil, &btcjson.RPCError{ Code: btcjson.ErrRPCInvalidParameter, Message: "Locktime out of range", @@ -599,7 +599,7 @@ func handleCreateRawTransaction(s *rpcServer, cmd interface{}, closeChan <-chan // Set the Locktime, if given. if c.LockTime != nil { - mtx.LockTime = int64(*c.LockTime) + mtx.LockTime = *c.LockTime } // Return the serialized and hex-encoded transaction. Note that this diff --git a/txscript/opcode.go b/txscript/opcode.go index accba310d..359036cea 100644 --- a/txscript/opcode.go +++ b/txscript/opcode.go @@ -1066,7 +1066,7 @@ func opcodeReturn(op *parsedOpcode, vm *Engine) error { } // verifyLockTime is a helper function used to validate locktimes. -func verifyLockTime(txLockTime, threshold, lockTime int64) error { +func verifyLockTime(txLockTime, threshold, lockTime uint64) error { // The lockTimes in both the script and transaction must be of the same // type. if !((txLockTime < threshold && lockTime < threshold) || @@ -1118,8 +1118,8 @@ func opcodeCheckLockTimeVerify(op *parsedOpcode, vm *Engine) error { // which the transaction is finalized or a timestamp depending on if the // value is before the txscript.LockTimeThreshold. When it is under the // threshold it is a block height. - err = verifyLockTime(int64(vm.tx.LockTime), LockTimeThreshold, - int64(lockTime)) + err = verifyLockTime(vm.tx.LockTime, LockTimeThreshold, + uint64(lockTime)) if err != nil { return err } @@ -1151,12 +1151,12 @@ func opcodeCheckLockTimeVerify(op *parsedOpcode, vm *Engine) error { // validating if the transaction outputs are spendable yet. func opcodeCheckSequenceVerify(op *parsedOpcode, vm *Engine) error { - // The current transaction sequence is a uint32 resulting in a maximum + // The current transaction sequence is a uint64 resulting in a maximum // sequence of 2^32-1. However, scriptNums are signed and therefore a // standard 4-byte scriptNum would only support up to a maximum of // 2^31-1. Thus, a 5-byte scriptNum is used here since it will support // up to 2^39-1 which allows sequences beyond the current sequence - // limit. + // limit. TODO: Understand this // // PopByteArray is used here instead of PopInt because we do not want // to be limited to a 4-byte integer for reasons specified above. @@ -1177,12 +1177,12 @@ func opcodeCheckSequenceVerify(op *parsedOpcode, vm *Engine) error { return scriptError(ErrNegativeLockTime, str) } - sequence := int64(stackSequence) + sequence := uint64(stackSequence) // To provide for future soft-fork extensibility, if the // operand has the disabled lock-time flag set, // CHECKSEQUENCEVERIFY behaves as a NOP. - if sequence&int64(wire.SequenceLockTimeDisabled) != 0 { + if sequence&uint64(wire.SequenceLockTimeDisabled) != 0 { return nil } @@ -1190,15 +1190,15 @@ func opcodeCheckSequenceVerify(op *parsedOpcode, vm *Engine) error { // consensus constrained. Testing that the transaction's sequence // number does not have this bit set prevents using this property // to get around a CHECKSEQUENCEVERIFY check. - txSequence := int64(vm.tx.TxIn[vm.txIdx].Sequence) - if txSequence&int64(wire.SequenceLockTimeDisabled) != 0 { + txSequence := vm.tx.TxIn[vm.txIdx].Sequence + if txSequence&wire.SequenceLockTimeDisabled != 0 { str := fmt.Sprintf("transaction sequence has sequence "+ "locktime disabled bit set: 0x%x", txSequence) return scriptError(ErrUnsatisfiedLockTime, str) } // Mask off non-consensus bits before doing comparisons. - lockTimeMask := int64(wire.SequenceLockTimeIsSeconds | + lockTimeMask := uint64(wire.SequenceLockTimeIsSeconds | wire.SequenceLockTimeMask) return verifyLockTime(txSequence&lockTimeMask, wire.SequenceLockTimeIsSeconds, sequence&lockTimeMask) diff --git a/txscript/standard.go b/txscript/standard.go index 1a4a4a5dc..818a40b8c 100644 --- a/txscript/standard.go +++ b/txscript/standard.go @@ -501,7 +501,7 @@ type AtomicSwapDataPushes struct { RefundHash160 [20]byte SecretHash [32]byte SecretSize int64 - LockTime int64 + LockTime uint64 } // ExtractAtomicSwapDataPushes returns the data pushes from an atomic swap @@ -568,9 +568,9 @@ func ExtractAtomicSwapDataPushes(version uint16, pkScript []byte) (*AtomicSwapDa if err != nil { return nil, nil } - pushes.LockTime = int64(locktime) + pushes.LockTime = uint64(locktime) } else if op := pops[11].opcode; isSmallInt(op) { - pushes.LockTime = int64(asSmallInt(op)) + pushes.LockTime = uint64(asSmallInt(op)) } else { return nil, nil } diff --git a/wire/bench_test.go b/wire/bench_test.go index f04840160..4b2f76838 100644 --- a/wire/bench_test.go +++ b/wire/bench_test.go @@ -9,6 +9,7 @@ import ( "compress/bzip2" "fmt" "io/ioutil" + "math" "net" "os" "testing" @@ -38,7 +39,7 @@ var genesisCoinbaseTx = MsgTx{ 0x6f, 0x75, 0x74, 0x20, 0x66, 0x6f, 0x72, 0x20, /* |out for |*/ 0x62, 0x61, 0x6e, 0x6b, 0x73, /* |banks| */ }, - Sequence: 0xffffffff, + Sequence: math.MaxUint64, }, }, TxOut: []*TxOut{ @@ -251,7 +252,7 @@ func BenchmarkReadTxIn(b *testing.B) { 0xff, 0xff, 0xff, 0xff, // Previous output index 0x07, // Varint for length of signature script 0x04, 0xff, 0xff, 0x00, 0x1d, 0x01, 0x04, // Signature script - 0xff, 0xff, 0xff, 0xff, // Sequence + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, // Sequence } r := bytes.NewReader(buf) var txIn TxIn @@ -284,7 +285,7 @@ func BenchmarkDeserializeTxSmall(b *testing.B) { 0xff, 0xff, 0xff, 0xff, // Prevous output index 0x07, // Varint for length of signature script 0x04, 0xff, 0xff, 0x00, 0x1d, 0x01, 0x04, // Signature script - 0xff, 0xff, 0xff, 0xff, // Sequence + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, // Sequence 0x01, // Varint for number of output transactions 0x00, 0xf2, 0x05, 0x2a, 0x01, 0x00, 0x00, 0x00, // Transaction amount 0x43, // Varint for length of pk script diff --git a/wire/message_test.go b/wire/message_test.go index 37ddb824a..2d0d6c293 100644 --- a/wire/message_test.go +++ b/wire/message_test.go @@ -89,7 +89,7 @@ func TestMessage(t *testing.T) { {msgGetAddr, msgGetAddr, pver, MainNet, 24}, {msgAddr, msgAddr, pver, MainNet, 25}, {msgGetBlocks, msgGetBlocks, pver, MainNet, 61}, - {msgBlock, msgBlock, pver, MainNet, 247}, + {msgBlock, msgBlock, pver, MainNet, 251}, {msgInv, msgInv, pver, MainNet, 25}, {msgGetData, msgGetData, pver, MainNet, 25}, {msgNotFound, msgNotFound, pver, MainNet, 25}, diff --git a/wire/msgblock_test.go b/wire/msgblock_test.go index ec75b6185..fa5aa08db 100644 --- a/wire/msgblock_test.go +++ b/wire/msgblock_test.go @@ -7,6 +7,7 @@ package wire import ( "bytes" "io" + "math" "reflect" "testing" "time" @@ -71,7 +72,7 @@ func TestBlock(t *testing.T) { // hashes from a block accurately. func TestBlockTxHashes(t *testing.T) { // Block 1, transaction 1 hash. - hashStr := "c52c57dcdaa5cbfd39ef73afb78b1fbb1e856f557dd5f8b53c49acbf21eb387a" + hashStr := "b7c3332bc138e2c9429818f5fed500bcc1746544218772389054dc8047d7cd3f" wantHash, err := chainhash.NewHashFromStr(hashStr) if err != nil { t.Errorf("NewHashFromStr: %v", err) @@ -506,7 +507,7 @@ var blockOne = MsgBlock{ SignatureScript: []byte{ 0x04, 0xff, 0xff, 0x00, 0x1d, 0x01, 0x04, }, - Sequence: 0xffffffff, + Sequence: math.MaxUint64, }, }, TxOut: []*TxOut{ @@ -556,7 +557,7 @@ var blockOneBytes = []byte{ 0xff, 0xff, 0xff, 0xff, // Prevous output index 0x07, // Varint for length of signature script 0x04, 0xff, 0xff, 0x00, 0x1d, 0x01, 0x04, // Signature script (coinbase) - 0xff, 0xff, 0xff, 0xff, // Sequence + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, // Sequence 0x01, // Varint for number of transaction outputs 0x00, 0xf2, 0x05, 0x2a, 0x01, 0x00, 0x00, 0x00, // Transaction amount 0x43, // Varint for length of pk script @@ -576,5 +577,5 @@ var blockOneBytes = []byte{ // Transaction location information for block one transactions. var blockOneTxLocs = []TxLoc{ - {TxStart: 85, TxLen: 138}, + {TxStart: 85, TxLen: 142}, } diff --git a/wire/msgtx.go b/wire/msgtx.go index 475ef5109..98fa072dc 100644 --- a/wire/msgtx.go +++ b/wire/msgtx.go @@ -8,6 +8,7 @@ import ( "bytes" "fmt" "io" + "math" "strconv" "github.com/daglabs/btcd/chaincfg/chainhash" @@ -19,7 +20,7 @@ const ( // MaxTxInSequenceNum is the maximum sequence number the sequence field // of a transaction input can be. - MaxTxInSequenceNum uint32 = 0xffffffff + MaxTxInSequenceNum uint64 = math.MaxUint64 // MaxPrevOutIndex is the maximum index the index field of a previous // outpoint can be. @@ -187,16 +188,16 @@ func (o OutPoint) String() string { type TxIn struct { PreviousOutPoint OutPoint SignatureScript []byte - Sequence uint32 + Sequence uint64 } // SerializeSize returns the number of bytes it would take to serialize the // the transaction input. func (t *TxIn) SerializeSize() int { - // Outpoint Hash 32 bytes + Outpoint Index 4 bytes + Sequence 4 bytes + + // Outpoint Hash 32 bytes + Outpoint Index 4 bytes + Sequence 8 bytes + // serialized varint size for the length of SignatureScript + // SignatureScript bytes. - return 40 + VarIntSerializeSize(uint64(len(t.SignatureScript))) + + return 44 + VarIntSerializeSize(uint64(len(t.SignatureScript))) + len(t.SignatureScript) } @@ -244,7 +245,7 @@ type MsgTx struct { Version int32 TxIn []*TxIn TxOut []*TxOut - LockTime int64 + LockTime uint64 } // AddTxIn adds a transaction input to the message. @@ -431,7 +432,7 @@ func (msg *MsgTx) BtcDecode(r io.Reader, pver uint32) error { } uint64LockTime, err := binarySerializer.Uint64(r, littleEndian) - msg.LockTime = int64(uint64LockTime) + msg.LockTime = uint64LockTime if err != nil { returnScriptBuffers() return err @@ -727,7 +728,7 @@ func writeTxIn(w io.Writer, pver uint32, version int32, ti *TxIn) error { return err } - return binarySerializer.PutUint32(w, littleEndian, ti.Sequence) + return binarySerializer.PutUint64(w, littleEndian, ti.Sequence) } // readTxOut reads the next sequence of bytes from r as a transaction output diff --git a/wire/msgtx_test.go b/wire/msgtx_test.go index ec906fe4d..e3018c812 100644 --- a/wire/msgtx_test.go +++ b/wire/msgtx_test.go @@ -8,6 +8,7 @@ import ( "bytes" "fmt" "io" + "math" "reflect" "testing" @@ -128,7 +129,7 @@ func TestTx(t *testing.T) { // TestTxHash tests the ability to generate the hash of a transaction accurately. func TestTxHash(t *testing.T) { // Hash of first transaction from block 113875. - hashStr := "a16521abfbac8dc484301bb57adc13ac72f71d42459c9c29c96b11972af2475c" + hashStr := "768f7e5de1e0a209c9f4e89a5b610d15e888dfe8f32be7f92462edc5815fc025" wantHash, err := chainhash.NewHashFromStr(hashStr) if err != nil { t.Errorf("NewHashFromStr: %v", err) @@ -143,7 +144,7 @@ func TestTxHash(t *testing.T) { Index: 0xffffffff, }, SignatureScript: []byte{0x04, 0x31, 0xdc, 0x00, 0x1b, 0x01, 0x62}, - Sequence: 0xffffffff, + Sequence: math.MaxUint64, } txOut := TxOut{ Value: 5000000000, @@ -334,15 +335,15 @@ func TestTxWireErrors(t *testing.T) { // Force error in transaction input sequence. {multiTx, multiTxEncoded, pver, 49, io.ErrShortWrite, io.EOF}, // Force error in number of transaction outputs. - {multiTx, multiTxEncoded, pver, 53, io.ErrShortWrite, io.EOF}, + {multiTx, multiTxEncoded, pver, 57, io.ErrShortWrite, io.EOF}, // Force error in transaction output value. - {multiTx, multiTxEncoded, pver, 54, io.ErrShortWrite, io.EOF}, + {multiTx, multiTxEncoded, pver, 58, io.ErrShortWrite, io.EOF}, // Force error in transaction output pk script length. - {multiTx, multiTxEncoded, pver, 62, io.ErrShortWrite, io.EOF}, + {multiTx, multiTxEncoded, pver, 66, io.ErrShortWrite, io.EOF}, // Force error in transaction output pk script. - {multiTx, multiTxEncoded, pver, 63, io.ErrShortWrite, io.EOF}, + {multiTx, multiTxEncoded, pver, 67, io.ErrShortWrite, io.EOF}, // Force error in transaction output lock time. - {multiTx, multiTxEncoded, pver, 206, io.ErrShortWrite, io.EOF}, + {multiTx, multiTxEncoded, pver, 210, io.ErrShortWrite, io.EOF}, } t.Logf("Running %d tests", len(tests)) @@ -477,15 +478,15 @@ func TestTxSerializeErrors(t *testing.T) { // Force error in transaction input sequence. {multiTx, multiTxEncoded, 49, io.ErrShortWrite, io.EOF}, // Force error in number of transaction outputs. - {multiTx, multiTxEncoded, 53, io.ErrShortWrite, io.EOF}, + {multiTx, multiTxEncoded, 57, io.ErrShortWrite, io.EOF}, // Force error in transaction output value. - {multiTx, multiTxEncoded, 54, io.ErrShortWrite, io.EOF}, + {multiTx, multiTxEncoded, 58, io.ErrShortWrite, io.EOF}, // Force error in transaction output pk script length. - {multiTx, multiTxEncoded, 62, io.ErrShortWrite, io.EOF}, + {multiTx, multiTxEncoded, 66, io.ErrShortWrite, io.EOF}, // Force error in transaction output pk script. - {multiTx, multiTxEncoded, 63, io.ErrShortWrite, io.EOF}, + {multiTx, multiTxEncoded, 67, io.ErrShortWrite, io.EOF}, // Force error in transaction output lock time. - {multiTx, multiTxEncoded, 206, io.ErrShortWrite, io.EOF}, + {multiTx, multiTxEncoded, 210, io.ErrShortWrite, io.EOF}, } t.Logf("Running %d tests", len(tests)) @@ -574,8 +575,8 @@ func TestTxOverflowErrors(t *testing.T) { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Previous output hash 0xff, 0xff, 0xff, 0xff, // Prevous output index - 0x00, // Varint for length of signature script - 0xff, 0xff, 0xff, 0xff, // Sequence + 0x00, // Varint for length of signature script + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, // Sequence 0x01, // Varint for number of output transactions 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Transaction amount 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, @@ -622,7 +623,7 @@ func TestTxSerializeSize(t *testing.T) { {noTx, 14}, // Transcaction with an input and an output. - {multiTx, 214}, + {multiTx, 218}, } t.Logf("Running %d tests", len(tests)) @@ -648,7 +649,7 @@ var multiTx = &MsgTx{ SignatureScript: []byte{ 0x04, 0x31, 0xdc, 0x00, 0x1b, 0x01, 0x62, }, - Sequence: 0xffffffff, + Sequence: math.MaxUint64, }, }, TxOut: []*TxOut{ @@ -700,7 +701,7 @@ var multiTxEncoded = []byte{ 0xff, 0xff, 0xff, 0xff, // Prevous output index 0x07, // Varint for length of signature script 0x04, 0x31, 0xdc, 0x00, 0x1b, 0x01, 0x62, // Signature script - 0xff, 0xff, 0xff, 0xff, // Sequence + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, // Sequence 0x02, // Varint for number of output transactions 0x00, 0xf2, 0x05, 0x2a, 0x01, 0x00, 0x00, 0x00, // Transaction amount 0x43, // Varint for length of pk script @@ -733,4 +734,4 @@ var multiTxEncoded = []byte{ // multiTxPkScriptLocs is the location information for the public key scripts // located in multiTx. -var multiTxPkScriptLocs = []int{63, 139} +var multiTxPkScriptLocs = []int{67, 143}