diff --git a/blockchain/chain.go b/blockchain/chain.go index 058fa8e2d..d26b822a2 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 uint32) uint32 { +func LockTimeToSequence(isSeconds bool, locktime int64) int64 { // 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 06954128e..346b4b859 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, 0e3e2357e806b6cdb1f70b54c3a3a17b6714ee1f0e68bebb44a74b1efd512098:0 +// Blk 1, c52c57dcdaa5cbfd39ef73afb78b1fbb1e856f557dd5f8b53c49acbf21eb387a:0 // // 03320496b538e853519c726a2c91e61ec11600ae1390813a627c66fb8be7947be63c52 // <><------------------------------------------------------------------> diff --git a/blockchain/chainio_test.go b/blockchain/chainio_test.go index 98bd91ed9..a8ec73fc3 100644 --- a/blockchain/chainio_test.go +++ b/blockchain/chainio_test.go @@ -413,7 +413,7 @@ func TestUtxoSerialization(t *testing.T) { serialized []byte }{ // From tx in main blockchain: - // 0e3e2357e806b6cdb1f70b54c3a3a17b6714ee1f0e68bebb44a74b1efd512098:0 + // c52c57dcdaa5cbfd39ef73afb78b1fbb1e856f557dd5f8b53c49acbf21eb387a:0 { name: "height 1, coinbase", entry: &UtxoEntry{ @@ -425,7 +425,7 @@ func TestUtxoSerialization(t *testing.T) { serialized: hexToBytes("03320496b538e853519c726a2c91e61ec11600ae1390813a627c66fb8be7947be63c52"), }, // From tx in main blockchain: - // 0e3e2357e806b6cdb1f70b54c3a3a17b6714ee1f0e68bebb44a74b1efd512098:0 + // c52c57dcdaa5cbfd39ef73afb78b1fbb1e856f557dd5f8b53c49acbf21eb387a:0 { name: "height 1, coinbase, spent", entry: &UtxoEntry{ @@ -631,7 +631,7 @@ func TestBestChainStateSerialization(t *testing.T) { { name: "block 1", state: bestChainState{ - hash: *newHashFromStr("00000000839a8e6886ab5951d76f411475428afc90947ee320161bbf18eb6048"), + hash: *newHashFromStr("ec85da8297525c2a2a5f3e826510ea1a48ee741e13a18b93ceeb2fb6c9848925,"), height: 1, totalTxns: 2, workSum: func() *big.Int { diff --git a/blockchain/upgrade.go b/blockchain/upgrade.go index 06694cd83..ef6a0eb68 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, 0e3e2357e806b6cdb1f70b54c3a3a17b6714ee1f0e68bebb44a74b1efd512098 +// Blk 1, c52c57dcdaa5cbfd39ef73afb78b1fbb1e856f557dd5f8b53c49acbf21eb387a // // 010103320496b538e853519c726a2c91e61ec11600ae1390813a627c66fb8be7947be63c52 // <><><><------------------------------------------------------------------> diff --git a/blockchain/upgrade_test.go b/blockchain/upgrade_test.go index 97e7f55c3..134453883 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: - // 0e3e2357e806b6cdb1f70b54c3a3a17b6714ee1f0e68bebb44a74b1efd512098 + // c52c57dcdaa5cbfd39ef73afb78b1fbb1e856f557dd5f8b53c49acbf21eb387a { name: "Only output 0, coinbase", entries: map[uint32]*UtxoEntry{ diff --git a/btcjson/chainsvrresults.go b/btcjson/chainsvrresults.go index 3c1947365..973afd8bc 100644 --- a/btcjson/chainsvrresults.go +++ b/btcjson/chainsvrresults.go @@ -444,7 +444,7 @@ type TxRawResult struct { Hash string `json:"hash,omitempty"` Size int32 `json:"size,omitempty"` Version int32 `json:"version"` - LockTime uint32 `json:"locktime"` + LockTime int64 `json:"locktime"` Vin []Vin `json:"vin"` Vout []Vout `json:"vout"` BlockHash string `json:"blockhash,omitempty"` @@ -461,7 +461,7 @@ type SearchRawTransactionsResult struct { Hash string `json:"hash"` Size string `json:"size"` Version int32 `json:"version"` - LockTime uint32 `json:"locktime"` + LockTime int64 `json:"locktime"` Vin []VinPrevOut `json:"vin"` Vout []Vout `json:"vout"` BlockHash string `json:"blockhash,omitempty"` @@ -474,7 +474,7 @@ type SearchRawTransactionsResult struct { type TxRawDecodeResult struct { Txid string `json:"txid"` Version int32 `json:"version"` - Locktime uint32 `json:"locktime"` + Locktime int64 `json:"locktime"` Vin []Vin `json:"vin"` Vout []Vout `json:"vout"` } diff --git a/docs/json_rpc_api.md b/docs/json_rpc_api.md index 3923b4339..5eb3b9a81 100644 --- a/docs/json_rpc_api.md +++ b/docs/json_rpc_api.md @@ -277,7 +277,7 @@ the method name for further details such as parameter and return information. |Returns (verbose=true, verbosetx=false)|`{ (json object)`
  `"hash": "blockhash", (string) the hash of the block (same as provided)`
  `"confirmations": n, (numeric) the number of confirmations`
  `"size", n (numeric) the size of the block`
  `"size": n, (numeric) the size of the block`
  `"height": n, (numeric) the height of the block in the block chain`
  `"version": n, (numeric) the block version`
  `"merkleroot": "hash", (string) root hash of the merkle tree`
  `"tx": [ (json array of string) the transaction hashes`
    `"transactionhash", (string) hash of the parent transaction`
    `...`
  `]`
  `"time": n, (numeric) the block time in seconds since 1 Jan 1970 GMT`
  `"nonce": n, (numeric) the block nonce`
  `"bits", n, (numeric) the bits which represent the block difficulty`
  `difficulty: n.nn, (numeric) the proof-of-work difficulty as a multiple of the minimum difficulty`
  `"previousblockhash": "hash", (string) the hash of the previous block`
  `"nextblockhash": "hash", (string) the hash of the next block (only if there is one)`
`}`| |Returns (verbose=true, verbosetx=true)|`{ (json object)`
  `"hash": "blockhash", (string) the hash of the block (same as provided)`
  `"confirmations": n, (numeric) the number of confirmations`
  `"size", n (numeric) the size of the block`
  `"size": n, (numeric) the size of the block`
  `"height": n, (numeric) the height of the block in the block chain`
  `"version": n, (numeric) the block version`
  `"merkleroot": "hash", (string) root hash of the merkle tree`
  `"rawtx": [ (array of json objects) the transactions as json objects`
    `(see getrawtransaction json object details)`
  `]`
  `"time": n, (numeric) the block time in seconds since 1 Jan 1970 GMT`
  `"nonce": n, (numeric) the block nonce`
  `"bits", n, (numeric) the bits which represent the block difficulty`
  `difficulty: n.nn, (numeric) the proof-of-work difficulty as a multiple of the minimum difficulty`
  `"previousblockhash": "hash", (string) the hash of the previous block`
  `"nextblockhash": "hash", (string) the hash of the next block`
`}`| |Example Return (verbose=false)|`"010000000000000000000000000000000000000000000000000000000000000000000000`
`3ba3edfd7a7b12b27ac72c3e67768f617fc81bc3888a51323a9fb8aa4b1e5e4a29ab5f49`
`ffff001d1dac2b7c01010000000100000000000000000000000000000000000000000000`
`00000000000000000000ffffffff4d04ffff001d0104455468652054696d65732030332f`
`4a616e2f32303039204368616e63656c6c6f72206f6e206272696e6b206f66207365636f`
`6e64206261696c6f757420666f722062616e6b73ffffffff0100f2052a01000000434104`
`678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f`
`4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5fac00000000"`
**Newlines added for display purposes. The actual return does not contain newlines.**| -|Example Return (verbose=true, verbosetx=false)|`{`
  `"hash": "000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f",`
  `"confirmations": 277113,`
  `"size": 285,`
  `"height": 0,`
  `"version": 1,`
  `"merkleroot": "4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b",`
  `"tx": [`
    `"4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b"`
  `],`
  `"time": 1231006505,`
  `"nonce": 2083236893,`
  `"bits": "1d00ffff",`
  `"difficulty": 1,`
  `"previousblockhash": "0000000000000000000000000000000000000000000000000000000000000000",`
  `"nextblockhash": "00000000839a8e6886ab5951d76f411475428afc90947ee320161bbf18eb6048"`
`}`| +|Example Return (verbose=true, verbosetx=false)|`{`
  `"hash": "000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f",`
  `"confirmations": 277113,`
  `"size": 285,`
  `"height": 0,`
  `"version": 1,`
  `"merkleroot": "4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b",`
  `"tx": [`
    `"4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b"`
  `],`
  `"time": 1231006505,`
  `"nonce": 2083236893,`
  `"bits": "1d00ffff",`
  `"difficulty": 1,`
  `"previousblockhash": "0000000000000000000000000000000000000000000000000000000000000000",`
  `"nextblockhash": "ec85da8297525c2a2a5f3e826510ea1a48ee741e13a18b93ceeb2fb6c9848925,"`
`}`| [Return to Overview](#MethodOverview)
*** @@ -1222,7 +1222,7 @@ Which results in: ```bash Hash: 000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f Previous Block: 0000000000000000000000000000000000000000000000000000000000000000 -Next Block: 00000000839a8e6886ab5951d76f411475428afc90947ee320161bbf18eb6048 +Next Block: ec85da8297525c2a2a5f3e826510ea1a48ee741e13a18b93ceeb2fb6c9848925, Merkle root: 4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b Timestamp: 2009-01-03 18:15:05 +0000 UTC Confirmations: 277290 diff --git a/integration/csv_test.go b/integration/csv_test.go index 4dbec18b2..203f374bd 100644 --- a/integration/csv_test.go +++ b/integration/csv_test.go @@ -144,7 +144,7 @@ func TestBIP0113(t *testing.T) { if err != nil { t.Fatalf("unable to query for chain info: %v", err) } - tx.LockTime = uint32(chainInfo.MedianTime) + 1 + tx.LockTime = chainInfo.MedianTime + 1 sigScript, err := txscript.SignatureScript(tx, 0, testPkScript, txscript.SigHashAll, outputKey, true) @@ -199,7 +199,7 @@ func TestBIP0113(t *testing.T) { PkScript: addrScript, Value: outputValue - 1000, }) - tx.LockTime = uint32(medianTimePast + timeLockDelta) + tx.LockTime = medianTimePast + timeLockDelta sigScript, err = txscript.SignatureScript(tx, 0, testPkScript, txscript.SigHashAll, outputKey, true) if err != nil { @@ -237,13 +237,13 @@ func TestBIP0113(t *testing.T) { // createCSVOutput creates an output paying to a trivially redeemable CSV // pkScript with the specified time-lock. func createCSVOutput(r *rpctest.Harness, t *testing.T, - numSatoshis btcutil.Amount, timeLock int32, + numSatoshis btcutil.Amount, timeLock int64, isSeconds bool) ([]byte, *wire.OutPoint, *wire.MsgTx, error) { // Convert the time-lock to the proper sequence lock based according to // if the lock is seconds or time based. sequenceLock := blockchain.LockTimeToSequence(isSeconds, - uint32(timeLock)) + int64(timeLock)) // Our CSV script is simply: OP_CSV OP_DROP b := txscript.NewScriptBuilder(). @@ -397,7 +397,7 @@ func TestBIP0068AndCsv(t *testing.T) { type csvOutput struct { RedeemScript []byte Utxo *wire.OutPoint - Timelock int32 + Timelock int64 } var spendableInputs [numTests]csvOutput @@ -412,7 +412,7 @@ func TestBIP0068AndCsv(t *testing.T) { } redeemScript, utxo, tx, err := createCSVOutput(r, t, outputAmt, - int32(timeLock), isSeconds) + timeLock, isSeconds) if err != nil { t.Fatalf("unable to create CSV output: %v", err) } @@ -424,7 +424,7 @@ func TestBIP0068AndCsv(t *testing.T) { spendableInputs[i] = csvOutput{ RedeemScript: redeemScript, Utxo: utxo, - Timelock: int32(timeLock), + Timelock: int64(timeLock), } } diff --git a/peer/log.go b/peer/log.go index d35f67596..ed3e83d55 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 uint32) string { +func formatLockTime(lockTime int64) 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/rpcserver.go b/rpcserver.go index 68ff49ac5..a27c52203 100644 --- a/rpcserver.go +++ b/rpcserver.go @@ -599,7 +599,7 @@ func handleCreateRawTransaction(s *rpcServer, cmd interface{}, closeChan <-chan // Set the Locktime, if given. if c.LockTime != nil { - mtx.LockTime = uint32(*c.LockTime) + mtx.LockTime = int64(*c.LockTime) } // Return the serialized and hex-encoded transaction. Note that this diff --git a/txscript/opcode.go b/txscript/opcode.go index 29f478305..accba310d 100644 --- a/txscript/opcode.go +++ b/txscript/opcode.go @@ -1090,13 +1090,11 @@ func verifyLockTime(txLockTime, threshold, lockTime int64) error { // LockTime field of the transaction containing the script signature // validating if the transaction outputs are spendable yet. func opcodeCheckLockTimeVerify(op *parsedOpcode, vm *Engine) error { - // The current transaction locktime is a uint32 resulting in a maximum - // locktime of 2^32-1 (the year 2106). However, scriptNums are signed + // The current transaction locktime is a int64 resulting in a maximum + // locktime of 2^63-1 (the year 292278994). However, scriptNums are signed // and therefore a standard 4-byte scriptNum would only support up to a // maximum of 2^31-1 (the year 2038). Thus, a 5-byte scriptNum is used - // here since it will support up to 2^39-1 which allows dates beyond the - // current locktime limit. - // + // here since it will support up to 2^39-1 which allows dates until the year 19400 // PopByteArray is used here instead of PopInt because we do not want // to be limited to a 4-byte integer for reasons specified above. so, err := vm.dstack.PopByteArray() diff --git a/wire/bench_test.go b/wire/bench_test.go index 8ec7776d0..7ab1d012a 100644 --- a/wire/bench_test.go +++ b/wire/bench_test.go @@ -356,7 +356,7 @@ func BenchmarkReadBlockHeader(b *testing.B) { 0x7a, 0xc7, 0x2c, 0x3e, 0x67, 0x76, 0x8f, 0x61, 0x7f, 0xc8, 0x1b, 0xc3, 0x88, 0x8a, 0x51, 0x32, 0x3a, 0x9f, 0xb8, 0xaa, 0x4b, 0x1e, 0x5e, 0x4a, // MerkleRoot - 0x29, 0xab, 0x5f, 0x49, // Timestamp + 0x29, 0xab, 0x5f, 0x49, 0x00, 0x00, 0x00, 0x00, // Timestamp 0xff, 0xff, 0x00, 0x1d, // Bits 0xf3, 0xe0, 0x01, 0x00, // Nonce 0x00, // TxnCount Varint diff --git a/wire/blockheader.go b/wire/blockheader.go index 5a636f36c..9007f560a 100644 --- a/wire/blockheader.go +++ b/wire/blockheader.go @@ -42,7 +42,7 @@ type BlockHeader struct { // blockHeaderLen is a constant that represents the number of bytes for a block // header. -const blockHeaderLen = 80 +const blockHeaderLen = 84 // BlockHash computes the block identifier hash for the given block header. func (h *BlockHeader) BlockHash() chainhash.Hash { @@ -115,14 +115,14 @@ func NewBlockHeader(version int32, prevHash, merkleRootHash *chainhash.Hash, // decoding from the wire. func readBlockHeader(r io.Reader, pver uint32, bh *BlockHeader) error { return readElements(r, &bh.Version, &bh.PrevBlock, &bh.MerkleRoot, - (*uint32Time)(&bh.Timestamp), &bh.Bits, &bh.Nonce) + (*int64Time)(&bh.Timestamp), &bh.Bits, &bh.Nonce) } // writeBlockHeader writes a bitcoin block header to w. See Serialize for // encoding block headers to be stored to disk, such as in a database, as // opposed to encoding for the wire. func writeBlockHeader(w io.Writer, pver uint32, bh *BlockHeader) error { - sec := uint32(bh.Timestamp.Unix()) + sec := int64(bh.Timestamp.Unix()) return writeElements(w, bh.Version, &bh.PrevBlock, &bh.MerkleRoot, sec, bh.Bits, bh.Nonce) } diff --git a/wire/blockheader_test.go b/wire/blockheader_test.go index 2035b1aa7..39570f181 100644 --- a/wire/blockheader_test.go +++ b/wire/blockheader_test.go @@ -73,7 +73,7 @@ func TestBlockHeaderWire(t *testing.T) { 0x7a, 0xc7, 0x2c, 0x3e, 0x67, 0x76, 0x8f, 0x61, 0x7f, 0xc8, 0x1b, 0xc3, 0x88, 0x8a, 0x51, 0x32, 0x3a, 0x9f, 0xb8, 0xaa, 0x4b, 0x1e, 0x5e, 0x4a, // MerkleRoot - 0x29, 0xab, 0x5f, 0x49, // Timestamp + 0x29, 0xab, 0x5f, 0x49, 0x00, 0x00, 0x00, 0x00, // Timestamp 0xff, 0xff, 0x00, 0x1d, // Bits 0xf3, 0xe0, 0x01, 0x00, // Nonce } @@ -206,7 +206,7 @@ func TestBlockHeaderSerialize(t *testing.T) { 0x7a, 0xc7, 0x2c, 0x3e, 0x67, 0x76, 0x8f, 0x61, 0x7f, 0xc8, 0x1b, 0xc3, 0x88, 0x8a, 0x51, 0x32, 0x3a, 0x9f, 0xb8, 0xaa, 0x4b, 0x1e, 0x5e, 0x4a, // MerkleRoot - 0x29, 0xab, 0x5f, 0x49, // Timestamp + 0x29, 0xab, 0x5f, 0x49, 0x00, 0x00, 0x00, 0x00, // Timestamp 0xff, 0xff, 0x00, 0x1d, // Bits 0xf3, 0xe0, 0x01, 0x00, // Nonce } diff --git a/wire/common.go b/wire/common.go index c6bf09b93..2e814c7ad 100644 --- a/wire/common.go +++ b/wire/common.go @@ -176,11 +176,6 @@ var binarySerializer binaryFreeList = make(chan []byte, binaryFreeListMaxItems) var errNonCanonicalVarInt = "non-canonical varint %x - discriminant %x must " + "encode a value greater than %x" -// uint32Time represents a unix timestamp encoded with a uint32. It is used as -// a way to signal the readElement function how to decode a timestamp into a Go -// time.Time since it is otherwise ambiguous. -type uint32Time time.Time - // int64Time represents a unix timestamp encoded with an int64. It is used as // a way to signal the readElement function how to decode a timestamp into a Go // time.Time since it is otherwise ambiguous. @@ -236,15 +231,6 @@ func readElement(r io.Reader, element interface{}) error { } return nil - // Unix timestamp encoded as a uint32. - case *uint32Time: - rv, err := binarySerializer.Uint32(r, binary.LittleEndian) - if err != nil { - return err - } - *e = uint32Time(time.Unix(int64(rv), 0)) - return nil - // Unix timestamp encoded as an int64. case *int64Time: rv, err := binarySerializer.Uint64(r, binary.LittleEndian) diff --git a/wire/message_test.go b/wire/message_test.go index d38fd0e34..37ddb824a 100644 --- a/wire/message_test.go +++ b/wire/message_test.go @@ -89,11 +89,11 @@ func TestMessage(t *testing.T) { {msgGetAddr, msgGetAddr, pver, MainNet, 24}, {msgAddr, msgAddr, pver, MainNet, 25}, {msgGetBlocks, msgGetBlocks, pver, MainNet, 61}, - {msgBlock, msgBlock, pver, MainNet, 239}, + {msgBlock, msgBlock, pver, MainNet, 247}, {msgInv, msgInv, pver, MainNet, 25}, {msgGetData, msgGetData, pver, MainNet, 25}, {msgNotFound, msgNotFound, pver, MainNet, 25}, - {msgTx, msgTx, pver, MainNet, 34}, + {msgTx, msgTx, pver, MainNet, 38}, {msgPing, msgPing, pver, MainNet, 32}, {msgPong, msgPong, pver, MainNet, 32}, {msgGetHeaders, msgGetHeaders, pver, MainNet, 61}, @@ -103,7 +103,7 @@ func TestMessage(t *testing.T) { {msgFilterAdd, msgFilterAdd, pver, MainNet, 26}, {msgFilterClear, msgFilterClear, pver, MainNet, 24}, {msgFilterLoad, msgFilterLoad, pver, MainNet, 35}, - {msgMerkleBlock, msgMerkleBlock, pver, MainNet, 110}, + {msgMerkleBlock, msgMerkleBlock, pver, MainNet, 114}, {msgReject, msgReject, pver, MainNet, 79}, {msgGetCFilters, msgGetCFilters, pver, MainNet, 61}, {msgGetCFHeaders, msgGetCFHeaders, pver, MainNet, 61}, diff --git a/wire/msgaddr_test.go b/wire/msgaddr_test.go index fc466e034..82b6c0b93 100644 --- a/wire/msgaddr_test.go +++ b/wire/msgaddr_test.go @@ -29,7 +29,7 @@ func TestAddr(t *testing.T) { // Ensure max payload is expected value for latest protocol version. // Num addresses (varInt) + max allowed addresses. - wantPayload := uint32(30009) + wantPayload := uint32(34009) maxPayload := msg.MaxPayloadLength(pver) if maxPayload != wantPayload { t.Errorf("MaxPayloadLength: wrong max payload length for "+ @@ -124,13 +124,13 @@ func TestAddrWire(t *testing.T) { multiAddr := NewMsgAddr() multiAddr.AddAddresses(na, na2) multiAddrEncoded := []byte{ - 0x02, // Varint for number of addresses - 0x29, 0xab, 0x5f, 0x49, // Timestamp + 0x02, // Varint for number of addresses + 0x29, 0xab, 0x5f, 0x49, 0x00, 0x00, 0x00, 0x00, // Timestamp 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // SFNodeNetwork 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x7f, 0x00, 0x00, 0x01, // IP 127.0.0.1 0x20, 0x8d, // Port 8333 in big-endian - 0x29, 0xab, 0x5f, 0x49, // Timestamp + 0x29, 0xab, 0x5f, 0x49, 0x00, 0x00, 0x00, 0x00, // Timestamp 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // SFNodeNetwork 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xc0, 0xa8, 0x00, 0x01, // IP 192.168.0.1 @@ -225,13 +225,13 @@ func TestAddrWireErrors(t *testing.T) { baseAddr := NewMsgAddr() baseAddr.AddAddresses(na, na2) baseAddrEncoded := []byte{ - 0x02, // Varint for number of addresses - 0x29, 0xab, 0x5f, 0x49, // Timestamp + 0x02, // Varint for number of addresses + 0x29, 0xab, 0x5f, 0x49, 0x00, 0x00, 0x00, 0x00, // Timestamp 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // SFNodeNetwork 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x7f, 0x00, 0x00, 0x01, // IP 127.0.0.1 0x20, 0x8d, // Port 8333 in big-endian - 0x29, 0xab, 0x5f, 0x49, // Timestamp + 0x29, 0xab, 0x5f, 0x49, 0x00, 0x00, 0x00, 0x00, // Timestamp 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // SFNodeNetwork 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xc0, 0xa8, 0x00, 0x01, // IP 192.168.0.1 diff --git a/wire/msgblock_test.go b/wire/msgblock_test.go index 2ff6351b3..ec75b6185 100644 --- a/wire/msgblock_test.go +++ b/wire/msgblock_test.go @@ -71,7 +71,7 @@ func TestBlock(t *testing.T) { // hashes from a block accurately. func TestBlockTxHashes(t *testing.T) { // Block 1, transaction 1 hash. - hashStr := "0e3e2357e806b6cdb1f70b54c3a3a17b6714ee1f0e68bebb44a74b1efd512098" + hashStr := "c52c57dcdaa5cbfd39ef73afb78b1fbb1e856f557dd5f8b53c49acbf21eb387a" wantHash, err := chainhash.NewHashFromStr(hashStr) if err != nil { t.Errorf("NewHashFromStr: %v", err) @@ -92,7 +92,7 @@ func TestBlockTxHashes(t *testing.T) { // TestBlockHash tests the ability to generate the hash of a block accurately. func TestBlockHash(t *testing.T) { // Block 1 hash. - hashStr := "839a8e6886ab5951d76f411475428afc90947ee320161bbf18eb6048" + hashStr := "ec85da8297525c2a2a5f3e826510ea1a48ee741e13a18b93ceeb2fb6c9848925" wantHash, err := chainhash.NewHashFromStr(hashStr) if err != nil { t.Errorf("NewHashFromStr: %v", err) @@ -201,7 +201,7 @@ func TestBlockWireErrors(t *testing.T) { // version. pver := uint32(60002) - tests := []struct { + tests := []struct { //TODO: need to recheck this part (what are the correct max values) in *MsgBlock // Value to encode buf []byte // Wire encoding pver uint32 // Protocol version for wire encoding @@ -218,13 +218,13 @@ func TestBlockWireErrors(t *testing.T) { // Force error in timestamp. {&blockOne, blockOneBytes, pver, 68, io.ErrShortWrite, io.EOF}, // Force error in difficulty bits. - {&blockOne, blockOneBytes, pver, 72, io.ErrShortWrite, io.EOF}, - // Force error in header nonce. {&blockOne, blockOneBytes, pver, 76, io.ErrShortWrite, io.EOF}, - // Force error in transaction count. + // Force error in header nonce. {&blockOne, blockOneBytes, pver, 80, io.ErrShortWrite, io.EOF}, + // Force error in transaction count. + {&blockOne, blockOneBytes, pver, 84, io.ErrShortWrite, io.EOF}, // Force error in transactions. - {&blockOne, blockOneBytes, pver, 81, io.ErrShortWrite, io.EOF}, + {&blockOne, blockOneBytes, pver, 85, io.ErrShortWrite, io.EOF}, } t.Logf("Running %d tests", len(tests)) @@ -336,13 +336,13 @@ func TestBlockSerializeErrors(t *testing.T) { // Force error in timestamp. {&blockOne, blockOneBytes, 68, io.ErrShortWrite, io.EOF}, // Force error in difficulty bits. - {&blockOne, blockOneBytes, 72, io.ErrShortWrite, io.EOF}, - // Force error in header nonce. {&blockOne, blockOneBytes, 76, io.ErrShortWrite, io.EOF}, - // Force error in transaction count. + // Force error in header nonce. {&blockOne, blockOneBytes, 80, io.ErrShortWrite, io.EOF}, + // Force error in transaction count. + {&blockOne, blockOneBytes, 84, io.ErrShortWrite, io.EOF}, // Force error in transactions. - {&blockOne, blockOneBytes, 81, io.ErrShortWrite, io.EOF}, + {&blockOne, blockOneBytes, 85, io.ErrShortWrite, io.EOF}, } t.Logf("Running %d tests", len(tests)) @@ -404,7 +404,7 @@ func TestBlockOverflowErrors(t *testing.T) { 0xbb, 0xbe, 0x68, 0x0e, 0x1f, 0xee, 0x14, 0x67, 0x7b, 0xa1, 0xa3, 0xc3, 0x54, 0x0b, 0xf7, 0xb1, 0xcd, 0xb6, 0x06, 0xe8, 0x57, 0x23, 0x3e, 0x0e, // MerkleRoot - 0x61, 0xbc, 0x66, 0x49, // Timestamp + 0x61, 0xbc, 0x66, 0x49, 0x00, 0x00, 0x00, 0x00, // Timestamp 0xff, 0xff, 0x00, 0x1d, // Bits 0x01, 0xe3, 0x62, 0x99, // Nonce 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, @@ -456,7 +456,7 @@ func TestBlockSerializeSize(t *testing.T) { size int // Expected serialized size }{ // Block with no transactions. - {noTxBlock, 81}, + {noTxBlock, 85}, // First block in the mainnet block chain. {&blockOne, len(blockOneBytes)}, @@ -543,7 +543,7 @@ var blockOneBytes = []byte{ 0xbb, 0xbe, 0x68, 0x0e, 0x1f, 0xee, 0x14, 0x67, 0x7b, 0xa1, 0xa3, 0xc3, 0x54, 0x0b, 0xf7, 0xb1, 0xcd, 0xb6, 0x06, 0xe8, 0x57, 0x23, 0x3e, 0x0e, // MerkleRoot - 0x61, 0xbc, 0x66, 0x49, // Timestamp + 0x61, 0xbc, 0x66, 0x49, 0x00, 0x00, 0x00, 0x00, // Timestamp 0xff, 0xff, 0x00, 0x1d, // Bits 0x01, 0xe3, 0x62, 0x99, // Nonce 0x01, // TxnCount @@ -569,12 +569,12 @@ var blockOneBytes = []byte{ 0xe0, 0xa6, 0x04, 0xf8, 0x14, 0x17, 0x81, 0xe6, 0x22, 0x94, 0x72, 0x11, 0x66, 0xbf, 0x62, 0x1e, 0x73, 0xa8, 0x2c, 0xbf, 0x23, 0x42, 0xc8, 0x58, - 0xee, // 65-byte uncompressed public key - 0xac, // OP_CHECKSIG - 0x00, 0x00, 0x00, 0x00, // Lock time + 0xee, // 65-byte uncompressed public key + 0xac, // OP_CHECKSIG + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Lock time } // Transaction location information for block one transactions. var blockOneTxLocs = []TxLoc{ - {TxStart: 81, TxLen: 134}, + {TxStart: 85, TxLen: 138}, } diff --git a/wire/msgheaders_test.go b/wire/msgheaders_test.go index 1e44c56d2..fbc6adf4a 100644 --- a/wire/msgheaders_test.go +++ b/wire/msgheaders_test.go @@ -88,7 +88,7 @@ func TestHeadersWire(t *testing.T) { 0xbb, 0xbe, 0x68, 0x0e, 0x1f, 0xee, 0x14, 0x67, 0x7b, 0xa1, 0xa3, 0xc3, 0x54, 0x0b, 0xf7, 0xb1, 0xcd, 0xb6, 0x06, 0xe8, 0x57, 0x23, 0x3e, 0x0e, // MerkleRoot - 0x61, 0xbc, 0x66, 0x49, // Timestamp + 0x61, 0xbc, 0x66, 0x49, 0x00, 0x00, 0x00, 0x00, // Timestamp 0xff, 0xff, 0x00, 0x1d, // Bits 0x01, 0xe3, 0x62, 0x99, // Nonce 0x00, // TxnCount (0 for headers message) @@ -239,7 +239,7 @@ func TestHeadersWireErrors(t *testing.T) { 0xbb, 0xbe, 0x68, 0x0e, 0x1f, 0xee, 0x14, 0x67, 0x7b, 0xa1, 0xa3, 0xc3, 0x54, 0x0b, 0xf7, 0xb1, 0xcd, 0xb6, 0x06, 0xe8, 0x57, 0x23, 0x3e, 0x0e, // MerkleRoot - 0x61, 0xbc, 0x66, 0x49, // Timestamp + 0x61, 0xbc, 0x66, 0x49, 0x00, 0x00, 0x00, 0x00, // Timestamp 0xff, 0xff, 0x00, 0x1d, // Bits 0x01, 0xe3, 0x62, 0x99, // Nonce 0x00, // TxnCount (0 for headers message) @@ -275,7 +275,7 @@ func TestHeadersWireErrors(t *testing.T) { 0xbb, 0xbe, 0x68, 0x0e, 0x1f, 0xee, 0x14, 0x67, 0x7b, 0xa1, 0xa3, 0xc3, 0x54, 0x0b, 0xf7, 0xb1, 0xcd, 0xb6, 0x06, 0xe8, 0x57, 0x23, 0x3e, 0x0e, // MerkleRoot - 0x61, 0xbc, 0x66, 0x49, // Timestamp + 0x61, 0xbc, 0x66, 0x49, 0x00, 0x00, 0x00, 0x00, // Timestamp 0xff, 0xff, 0x00, 0x1d, // Bits 0x01, 0xe3, 0x62, 0x99, // Nonce 0x01, // TxnCount (should be 0 for headers message, but 1 to force error) diff --git a/wire/msgmerkleblock_test.go b/wire/msgmerkleblock_test.go index 1d407f409..fd9de0e41 100644 --- a/wire/msgmerkleblock_test.go +++ b/wire/msgmerkleblock_test.go @@ -410,7 +410,7 @@ var merkleBlockOneBytes = []byte{ 0xbb, 0xbe, 0x68, 0x0e, 0x1f, 0xee, 0x14, 0x67, 0x7b, 0xa1, 0xa3, 0xc3, 0x54, 0x0b, 0xf7, 0xb1, 0xcd, 0xb6, 0x06, 0xe8, 0x57, 0x23, 0x3e, 0x0e, // MerkleRoot - 0x61, 0xbc, 0x66, 0x49, // Timestamp + 0x61, 0xbc, 0x66, 0x49, 0x00, 0x00, 0x00, 0x00, // Timestamp 0xff, 0xff, 0x00, 0x1d, // Bits 0x01, 0xe3, 0x62, 0x99, // Nonce 0x01, 0x00, 0x00, 0x00, // TxnCount diff --git a/wire/msgtx.go b/wire/msgtx.go index 06891a76c..475ef5109 100644 --- a/wire/msgtx.go +++ b/wire/msgtx.go @@ -244,7 +244,7 @@ type MsgTx struct { Version int32 TxIn []*TxIn TxOut []*TxOut - LockTime uint32 + LockTime int64 } // AddTxIn adds a transaction input to the message. @@ -430,7 +430,8 @@ func (msg *MsgTx) BtcDecode(r io.Reader, pver uint32) error { totalScriptSize += uint64(len(to.PkScript)) } - msg.LockTime, err = binarySerializer.Uint32(r, littleEndian) + uint64LockTime, err := binarySerializer.Uint64(r, littleEndian) + msg.LockTime = int64(uint64LockTime) if err != nil { returnScriptBuffers() return err @@ -541,7 +542,7 @@ func (msg *MsgTx) BtcEncode(w io.Writer, pver uint32) error { } } - return binarySerializer.PutUint32(w, littleEndian, msg.LockTime) + return binarySerializer.PutUint64(w, littleEndian, uint64(msg.LockTime)) } // Serialize encodes the transaction to w using a format that suitable for @@ -564,9 +565,9 @@ func (msg *MsgTx) Serialize(w io.Writer) error { // SerializeSize returns the number of bytes it would take to serialize the // the transaction. func (msg *MsgTx) SerializeSize() int { - // Version 4 bytes + LockTime 4 bytes + Serialized varint size for the + // Version 4 bytes + LockTime 8 bytes + Serialized varint size for the // number of transaction inputs and outputs. - n := 8 + VarIntSerializeSize(uint64(len(msg.TxIn))) + + n := 12 + VarIntSerializeSize(uint64(len(msg.TxIn))) + VarIntSerializeSize(uint64(len(msg.TxOut))) for _, txIn := range msg.TxIn { diff --git a/wire/msgtx_test.go b/wire/msgtx_test.go index 06d83bc66..9abe0380d 100644 --- a/wire/msgtx_test.go +++ b/wire/msgtx_test.go @@ -128,7 +128,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 := "f051e59b5e2503ac626d03aaeac8ab7be2d72ba4b7e97119c5852d70d52dcb86" + hashStr := "a16521abfbac8dc484301bb57adc13ac72f71d42459c9c29c96b11972af2475c" wantHash, err := chainhash.NewHashFromStr(hashStr) if err != nil { t.Errorf("NewHashFromStr: %v", err) diff --git a/wire/netaddress.go b/wire/netaddress.go index 5a2610bcc..7e24c2d08 100644 --- a/wire/netaddress.go +++ b/wire/netaddress.go @@ -19,8 +19,8 @@ func maxNetAddressPayload(pver uint32) uint32 { // NetAddressTimeVersion added a timestamp field. if pver >= NetAddressTimeVersion { - // Timestamp 4 bytes. - plen += 4 + // Timestamp 8 bytes. + plen += 8 } return plen @@ -29,10 +29,7 @@ func maxNetAddressPayload(pver uint32) uint32 { // NetAddress defines information about a peer on the network including the time // it was last seen, the services it supports, its IP address, and port. type NetAddress struct { - // Last time the address was seen. This is, unfortunately, encoded as a - // uint32 on the wire and therefore is limited to 2106. This field is - // not present in the bitcoin version message (MsgVersion) nor was it - // added until protocol version >= NetAddressTimeVersion. + // Last time the address was seen. Timestamp time.Time // Bitfield which identifies the services supported by the address. @@ -91,11 +88,8 @@ func NewNetAddress(addr *net.TCPAddr, services ServiceFlag) *NetAddress { func readNetAddress(r io.Reader, pver uint32, na *NetAddress, ts bool) error { var ip [16]byte - // NOTE: The bitcoin protocol uses a uint32 for the timestamp so it will - // stop working somewhere around 2106. Also timestamp wasn't added until - // protocol version >= NetAddressTimeVersion if ts && pver >= NetAddressTimeVersion { - err := readElement(r, (*uint32Time)(&na.Timestamp)) + err := readElement(r, (*int64Time)(&na.Timestamp)) if err != nil { return err } @@ -124,11 +118,9 @@ func readNetAddress(r io.Reader, pver uint32, na *NetAddress, ts bool) error { // version and whether or not the timestamp is included per ts. Some messages // like version do not include the timestamp. func writeNetAddress(w io.Writer, pver uint32, na *NetAddress, ts bool) error { - // NOTE: The bitcoin protocol uses a uint32 for the timestamp so it will - // stop working somewhere around 2106. Also timestamp wasn't added until - // until protocol version >= NetAddressTimeVersion. + // Timestamp wasn't added until protocol version >= NetAddressTimeVersion. if ts && pver >= NetAddressTimeVersion { - err := writeElement(w, uint32(na.Timestamp.Unix())) + err := writeElement(w, int64(na.Timestamp.Unix())) if err != nil { return err } diff --git a/wire/netaddress_test.go b/wire/netaddress_test.go index 128a7fbce..b28c810ea 100644 --- a/wire/netaddress_test.go +++ b/wire/netaddress_test.go @@ -88,7 +88,7 @@ func TestNetAddressWire(t *testing.T) { // baseNetAddrEncoded is the wire encoded bytes of baseNetAddr. baseNetAddrEncoded := []byte{ - 0x29, 0xab, 0x5f, 0x49, // Timestamp + 0x29, 0xab, 0x5f, 0x49, 0x00, 0x00, 0x00, 0x00, // Timestamp 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // SFNodeNetwork 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x7f, 0x00, 0x00, 0x01, // IP 127.0.0.1