[DEV-31] Convert all timestamp to int64

This commit is contained in:
Ori Newman 2018-07-15 18:00:21 +03:00
parent d472600155
commit d488aebe0d
24 changed files with 76 additions and 99 deletions

View File

@ -447,7 +447,7 @@ func (b *BlockChain) calcSequenceLock(node *blockNode, tx *btcutil.Tx, utxoView
// number in accordance to BIP-68. // number in accordance to BIP-68.
// See: https://github.com/bitcoin/bips/blob/master/bip-0068.mediawiki // See: https://github.com/bitcoin/bips/blob/master/bip-0068.mediawiki
// * (Compatibility) // * (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 // If we're expressing the relative lock time in blocks, then the
// corresponding sequence number is simply the desired input age. // corresponding sequence number is simply the desired input age.
if !isSeconds { if !isSeconds {

View File

@ -497,7 +497,7 @@ func dbRemoveSpendJournalEntry(dbTx database.Tx, blockHash *chainhash.Hash) erro
// //
// Example 1: // Example 1:
// From tx in main blockchain: // From tx in main blockchain:
// Blk 1, 0e3e2357e806b6cdb1f70b54c3a3a17b6714ee1f0e68bebb44a74b1efd512098:0 // Blk 1, c52c57dcdaa5cbfd39ef73afb78b1fbb1e856f557dd5f8b53c49acbf21eb387a:0
// //
// 03320496b538e853519c726a2c91e61ec11600ae1390813a627c66fb8be7947be63c52 // 03320496b538e853519c726a2c91e61ec11600ae1390813a627c66fb8be7947be63c52
// <><------------------------------------------------------------------> // <><------------------------------------------------------------------>

View File

@ -413,7 +413,7 @@ func TestUtxoSerialization(t *testing.T) {
serialized []byte serialized []byte
}{ }{
// From tx in main blockchain: // From tx in main blockchain:
// 0e3e2357e806b6cdb1f70b54c3a3a17b6714ee1f0e68bebb44a74b1efd512098:0 // c52c57dcdaa5cbfd39ef73afb78b1fbb1e856f557dd5f8b53c49acbf21eb387a:0
{ {
name: "height 1, coinbase", name: "height 1, coinbase",
entry: &UtxoEntry{ entry: &UtxoEntry{
@ -425,7 +425,7 @@ func TestUtxoSerialization(t *testing.T) {
serialized: hexToBytes("03320496b538e853519c726a2c91e61ec11600ae1390813a627c66fb8be7947be63c52"), serialized: hexToBytes("03320496b538e853519c726a2c91e61ec11600ae1390813a627c66fb8be7947be63c52"),
}, },
// From tx in main blockchain: // From tx in main blockchain:
// 0e3e2357e806b6cdb1f70b54c3a3a17b6714ee1f0e68bebb44a74b1efd512098:0 // c52c57dcdaa5cbfd39ef73afb78b1fbb1e856f557dd5f8b53c49acbf21eb387a:0
{ {
name: "height 1, coinbase, spent", name: "height 1, coinbase, spent",
entry: &UtxoEntry{ entry: &UtxoEntry{
@ -631,7 +631,7 @@ func TestBestChainStateSerialization(t *testing.T) {
{ {
name: "block 1", name: "block 1",
state: bestChainState{ state: bestChainState{
hash: *newHashFromStr("00000000839a8e6886ab5951d76f411475428afc90947ee320161bbf18eb6048"), hash: *newHashFromStr("ec85da8297525c2a2a5f3e826510ea1a48ee741e13a18b93ceeb2fb6c9848925,"),
height: 1, height: 1,
totalTxns: 2, totalTxns: 2,
workSum: func() *big.Int { workSum: func() *big.Int {

View File

@ -267,7 +267,7 @@ func determineMainChainBlocks(blocksMap map[chainhash.Hash]*blockChainContext, t
// //
// Example 1: // Example 1:
// From tx in main blockchain: // From tx in main blockchain:
// Blk 1, 0e3e2357e806b6cdb1f70b54c3a3a17b6714ee1f0e68bebb44a74b1efd512098 // Blk 1, c52c57dcdaa5cbfd39ef73afb78b1fbb1e856f557dd5f8b53c49acbf21eb387a
// //
// 010103320496b538e853519c726a2c91e61ec11600ae1390813a627c66fb8be7947be63c52 // 010103320496b538e853519c726a2c91e61ec11600ae1390813a627c66fb8be7947be63c52
// <><><><------------------------------------------------------------------> // <><><><------------------------------------------------------------------>

View File

@ -18,7 +18,7 @@ func TestDeserializeUtxoEntryV0(t *testing.T) {
serialized []byte serialized []byte
}{ }{
// From tx in main blockchain: // From tx in main blockchain:
// 0e3e2357e806b6cdb1f70b54c3a3a17b6714ee1f0e68bebb44a74b1efd512098 // c52c57dcdaa5cbfd39ef73afb78b1fbb1e856f557dd5f8b53c49acbf21eb387a
{ {
name: "Only output 0, coinbase", name: "Only output 0, coinbase",
entries: map[uint32]*UtxoEntry{ entries: map[uint32]*UtxoEntry{

View File

@ -444,7 +444,7 @@ type TxRawResult struct {
Hash string `json:"hash,omitempty"` Hash string `json:"hash,omitempty"`
Size int32 `json:"size,omitempty"` Size int32 `json:"size,omitempty"`
Version int32 `json:"version"` Version int32 `json:"version"`
LockTime uint32 `json:"locktime"` LockTime int64 `json:"locktime"`
Vin []Vin `json:"vin"` Vin []Vin `json:"vin"`
Vout []Vout `json:"vout"` Vout []Vout `json:"vout"`
BlockHash string `json:"blockhash,omitempty"` BlockHash string `json:"blockhash,omitempty"`
@ -461,7 +461,7 @@ type SearchRawTransactionsResult struct {
Hash string `json:"hash"` Hash string `json:"hash"`
Size string `json:"size"` Size string `json:"size"`
Version int32 `json:"version"` Version int32 `json:"version"`
LockTime uint32 `json:"locktime"` LockTime int64 `json:"locktime"`
Vin []VinPrevOut `json:"vin"` Vin []VinPrevOut `json:"vin"`
Vout []Vout `json:"vout"` Vout []Vout `json:"vout"`
BlockHash string `json:"blockhash,omitempty"` BlockHash string `json:"blockhash,omitempty"`
@ -474,7 +474,7 @@ type SearchRawTransactionsResult struct {
type TxRawDecodeResult struct { type TxRawDecodeResult struct {
Txid string `json:"txid"` Txid string `json:"txid"`
Version int32 `json:"version"` Version int32 `json:"version"`
Locktime uint32 `json:"locktime"` Locktime int64 `json:"locktime"`
Vin []Vin `json:"vin"` Vin []Vin `json:"vin"`
Vout []Vout `json:"vout"` Vout []Vout `json:"vout"`
} }

View File

@ -277,7 +277,7 @@ the method name for further details such as parameter and return information.
|Returns (verbose=true, verbosetx=false)|`{ (json object)`<br />&nbsp;&nbsp;`"hash": "blockhash", (string) the hash of the block (same as provided)`<br />&nbsp;&nbsp;`"confirmations": n, (numeric) the number of confirmations`<br />&nbsp;&nbsp;`"size", n (numeric) the size of the block`<br />&nbsp;&nbsp;`"size": n, (numeric) the size of the block`<br />&nbsp;&nbsp;`"height": n, (numeric) the height of the block in the block chain`<br />&nbsp;&nbsp;`"version": n, (numeric) the block version`<br />&nbsp;&nbsp;`"merkleroot": "hash", (string) root hash of the merkle tree`<br />&nbsp;&nbsp;`"tx": [ (json array of string) the transaction hashes`<br />&nbsp;&nbsp;&nbsp;&nbsp;`"transactionhash", (string) hash of the parent transaction`<br />&nbsp;&nbsp;&nbsp;&nbsp;`...`<br />&nbsp;&nbsp;`]`<br />&nbsp;&nbsp;`"time": n, (numeric) the block time in seconds since 1 Jan 1970 GMT`<br />&nbsp;&nbsp;`"nonce": n, (numeric) the block nonce`<br />&nbsp;&nbsp;`"bits", n, (numeric) the bits which represent the block difficulty`<br />&nbsp;&nbsp;`difficulty: n.nn, (numeric) the proof-of-work difficulty as a multiple of the minimum difficulty`<br />&nbsp;&nbsp;`"previousblockhash": "hash", (string) the hash of the previous block`<br />&nbsp;&nbsp;`"nextblockhash": "hash", (string) the hash of the next block (only if there is one)`<br />`}`| |Returns (verbose=true, verbosetx=false)|`{ (json object)`<br />&nbsp;&nbsp;`"hash": "blockhash", (string) the hash of the block (same as provided)`<br />&nbsp;&nbsp;`"confirmations": n, (numeric) the number of confirmations`<br />&nbsp;&nbsp;`"size", n (numeric) the size of the block`<br />&nbsp;&nbsp;`"size": n, (numeric) the size of the block`<br />&nbsp;&nbsp;`"height": n, (numeric) the height of the block in the block chain`<br />&nbsp;&nbsp;`"version": n, (numeric) the block version`<br />&nbsp;&nbsp;`"merkleroot": "hash", (string) root hash of the merkle tree`<br />&nbsp;&nbsp;`"tx": [ (json array of string) the transaction hashes`<br />&nbsp;&nbsp;&nbsp;&nbsp;`"transactionhash", (string) hash of the parent transaction`<br />&nbsp;&nbsp;&nbsp;&nbsp;`...`<br />&nbsp;&nbsp;`]`<br />&nbsp;&nbsp;`"time": n, (numeric) the block time in seconds since 1 Jan 1970 GMT`<br />&nbsp;&nbsp;`"nonce": n, (numeric) the block nonce`<br />&nbsp;&nbsp;`"bits", n, (numeric) the bits which represent the block difficulty`<br />&nbsp;&nbsp;`difficulty: n.nn, (numeric) the proof-of-work difficulty as a multiple of the minimum difficulty`<br />&nbsp;&nbsp;`"previousblockhash": "hash", (string) the hash of the previous block`<br />&nbsp;&nbsp;`"nextblockhash": "hash", (string) the hash of the next block (only if there is one)`<br />`}`|
|Returns (verbose=true, verbosetx=true)|`{ (json object)`<br />&nbsp;&nbsp;`"hash": "blockhash", (string) the hash of the block (same as provided)`<br />&nbsp;&nbsp;`"confirmations": n, (numeric) the number of confirmations`<br />&nbsp;&nbsp;`"size", n (numeric) the size of the block`<br />&nbsp;&nbsp;`"size": n, (numeric) the size of the block`<br />&nbsp;&nbsp;`"height": n, (numeric) the height of the block in the block chain`<br />&nbsp;&nbsp;`"version": n, (numeric) the block version`<br />&nbsp;&nbsp;`"merkleroot": "hash", (string) root hash of the merkle tree`<br />&nbsp;&nbsp;`"rawtx": [ (array of json objects) the transactions as json objects`<br />&nbsp;&nbsp;&nbsp;&nbsp;`(see getrawtransaction json object details)`<br />&nbsp;&nbsp;`]`<br />&nbsp;&nbsp;`"time": n, (numeric) the block time in seconds since 1 Jan 1970 GMT`<br />&nbsp;&nbsp;`"nonce": n, (numeric) the block nonce`<br />&nbsp;&nbsp;`"bits", n, (numeric) the bits which represent the block difficulty`<br />&nbsp;&nbsp;`difficulty: n.nn, (numeric) the proof-of-work difficulty as a multiple of the minimum difficulty`<br />&nbsp;&nbsp;`"previousblockhash": "hash", (string) the hash of the previous block`<br />&nbsp;&nbsp;`"nextblockhash": "hash", (string) the hash of the next block`<br />`}`| |Returns (verbose=true, verbosetx=true)|`{ (json object)`<br />&nbsp;&nbsp;`"hash": "blockhash", (string) the hash of the block (same as provided)`<br />&nbsp;&nbsp;`"confirmations": n, (numeric) the number of confirmations`<br />&nbsp;&nbsp;`"size", n (numeric) the size of the block`<br />&nbsp;&nbsp;`"size": n, (numeric) the size of the block`<br />&nbsp;&nbsp;`"height": n, (numeric) the height of the block in the block chain`<br />&nbsp;&nbsp;`"version": n, (numeric) the block version`<br />&nbsp;&nbsp;`"merkleroot": "hash", (string) root hash of the merkle tree`<br />&nbsp;&nbsp;`"rawtx": [ (array of json objects) the transactions as json objects`<br />&nbsp;&nbsp;&nbsp;&nbsp;`(see getrawtransaction json object details)`<br />&nbsp;&nbsp;`]`<br />&nbsp;&nbsp;`"time": n, (numeric) the block time in seconds since 1 Jan 1970 GMT`<br />&nbsp;&nbsp;`"nonce": n, (numeric) the block nonce`<br />&nbsp;&nbsp;`"bits", n, (numeric) the bits which represent the block difficulty`<br />&nbsp;&nbsp;`difficulty: n.nn, (numeric) the proof-of-work difficulty as a multiple of the minimum difficulty`<br />&nbsp;&nbsp;`"previousblockhash": "hash", (string) the hash of the previous block`<br />&nbsp;&nbsp;`"nextblockhash": "hash", (string) the hash of the next block`<br />`}`|
|Example Return (verbose=false)|`"010000000000000000000000000000000000000000000000000000000000000000000000`<br />`3ba3edfd7a7b12b27ac72c3e67768f617fc81bc3888a51323a9fb8aa4b1e5e4a29ab5f49`<br />`ffff001d1dac2b7c01010000000100000000000000000000000000000000000000000000`<br />`00000000000000000000ffffffff4d04ffff001d0104455468652054696d65732030332f`<br />`4a616e2f32303039204368616e63656c6c6f72206f6e206272696e6b206f66207365636f`<br />`6e64206261696c6f757420666f722062616e6b73ffffffff0100f2052a01000000434104`<br />`678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f`<br />`4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5fac00000000"`<br /><font color="orange">**Newlines added for display purposes. The actual return does not contain newlines.**</font>| |Example Return (verbose=false)|`"010000000000000000000000000000000000000000000000000000000000000000000000`<br />`3ba3edfd7a7b12b27ac72c3e67768f617fc81bc3888a51323a9fb8aa4b1e5e4a29ab5f49`<br />`ffff001d1dac2b7c01010000000100000000000000000000000000000000000000000000`<br />`00000000000000000000ffffffff4d04ffff001d0104455468652054696d65732030332f`<br />`4a616e2f32303039204368616e63656c6c6f72206f6e206272696e6b206f66207365636f`<br />`6e64206261696c6f757420666f722062616e6b73ffffffff0100f2052a01000000434104`<br />`678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f`<br />`4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5fac00000000"`<br /><font color="orange">**Newlines added for display purposes. The actual return does not contain newlines.**</font>|
|Example Return (verbose=true, verbosetx=false)|`{`<br />&nbsp;&nbsp;`"hash": "000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f",`<br />&nbsp;&nbsp;`"confirmations": 277113,`<br />&nbsp;&nbsp;`"size": 285,`<br />&nbsp;&nbsp;`"height": 0,`<br />&nbsp;&nbsp;`"version": 1,`<br />&nbsp;&nbsp;`"merkleroot": "4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b",`<br />&nbsp;&nbsp;`"tx": [`<br />&nbsp;&nbsp;&nbsp;&nbsp;`"4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b"`<br />&nbsp;&nbsp;`],`<br />&nbsp;&nbsp;`"time": 1231006505,`<br />&nbsp;&nbsp;`"nonce": 2083236893,`<br />&nbsp;&nbsp;`"bits": "1d00ffff",`<br />&nbsp;&nbsp;`"difficulty": 1,`<br />&nbsp;&nbsp;`"previousblockhash": "0000000000000000000000000000000000000000000000000000000000000000",`<br />&nbsp;&nbsp;`"nextblockhash": "00000000839a8e6886ab5951d76f411475428afc90947ee320161bbf18eb6048"`<br />`}`| |Example Return (verbose=true, verbosetx=false)|`{`<br />&nbsp;&nbsp;`"hash": "000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f",`<br />&nbsp;&nbsp;`"confirmations": 277113,`<br />&nbsp;&nbsp;`"size": 285,`<br />&nbsp;&nbsp;`"height": 0,`<br />&nbsp;&nbsp;`"version": 1,`<br />&nbsp;&nbsp;`"merkleroot": "4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b",`<br />&nbsp;&nbsp;`"tx": [`<br />&nbsp;&nbsp;&nbsp;&nbsp;`"4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b"`<br />&nbsp;&nbsp;`],`<br />&nbsp;&nbsp;`"time": 1231006505,`<br />&nbsp;&nbsp;`"nonce": 2083236893,`<br />&nbsp;&nbsp;`"bits": "1d00ffff",`<br />&nbsp;&nbsp;`"difficulty": 1,`<br />&nbsp;&nbsp;`"previousblockhash": "0000000000000000000000000000000000000000000000000000000000000000",`<br />&nbsp;&nbsp;`"nextblockhash": "ec85da8297525c2a2a5f3e826510ea1a48ee741e13a18b93ceeb2fb6c9848925,"`<br />`}`|
[Return to Overview](#MethodOverview)<br /> [Return to Overview](#MethodOverview)<br />
*** ***
@ -1222,7 +1222,7 @@ Which results in:
```bash ```bash
Hash: 000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f Hash: 000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f
Previous Block: 0000000000000000000000000000000000000000000000000000000000000000 Previous Block: 0000000000000000000000000000000000000000000000000000000000000000
Next Block: 00000000839a8e6886ab5951d76f411475428afc90947ee320161bbf18eb6048 Next Block: ec85da8297525c2a2a5f3e826510ea1a48ee741e13a18b93ceeb2fb6c9848925,
Merkle root: 4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b Merkle root: 4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b
Timestamp: 2009-01-03 18:15:05 +0000 UTC Timestamp: 2009-01-03 18:15:05 +0000 UTC
Confirmations: 277290 Confirmations: 277290

View File

@ -144,7 +144,7 @@ func TestBIP0113(t *testing.T) {
if err != nil { if err != nil {
t.Fatalf("unable to query for chain info: %v", err) 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, sigScript, err := txscript.SignatureScript(tx, 0, testPkScript,
txscript.SigHashAll, outputKey, true) txscript.SigHashAll, outputKey, true)
@ -199,7 +199,7 @@ func TestBIP0113(t *testing.T) {
PkScript: addrScript, PkScript: addrScript,
Value: outputValue - 1000, Value: outputValue - 1000,
}) })
tx.LockTime = uint32(medianTimePast + timeLockDelta) tx.LockTime = medianTimePast + timeLockDelta
sigScript, err = txscript.SignatureScript(tx, 0, testPkScript, sigScript, err = txscript.SignatureScript(tx, 0, testPkScript,
txscript.SigHashAll, outputKey, true) txscript.SigHashAll, outputKey, true)
if err != nil { if err != nil {
@ -237,13 +237,13 @@ func TestBIP0113(t *testing.T) {
// createCSVOutput creates an output paying to a trivially redeemable CSV // createCSVOutput creates an output paying to a trivially redeemable CSV
// pkScript with the specified time-lock. // pkScript with the specified time-lock.
func createCSVOutput(r *rpctest.Harness, t *testing.T, 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) { isSeconds bool) ([]byte, *wire.OutPoint, *wire.MsgTx, error) {
// Convert the time-lock to the proper sequence lock based according to // Convert the time-lock to the proper sequence lock based according to
// if the lock is seconds or time based. // if the lock is seconds or time based.
sequenceLock := blockchain.LockTimeToSequence(isSeconds, sequenceLock := blockchain.LockTimeToSequence(isSeconds,
uint32(timeLock)) int64(timeLock))
// Our CSV script is simply: <sequenceLock> OP_CSV OP_DROP // Our CSV script is simply: <sequenceLock> OP_CSV OP_DROP
b := txscript.NewScriptBuilder(). b := txscript.NewScriptBuilder().
@ -397,7 +397,7 @@ func TestBIP0068AndCsv(t *testing.T) {
type csvOutput struct { type csvOutput struct {
RedeemScript []byte RedeemScript []byte
Utxo *wire.OutPoint Utxo *wire.OutPoint
Timelock int32 Timelock int64
} }
var spendableInputs [numTests]csvOutput var spendableInputs [numTests]csvOutput
@ -412,7 +412,7 @@ func TestBIP0068AndCsv(t *testing.T) {
} }
redeemScript, utxo, tx, err := createCSVOutput(r, t, outputAmt, redeemScript, utxo, tx, err := createCSVOutput(r, t, outputAmt,
int32(timeLock), isSeconds) timeLock, isSeconds)
if err != nil { if err != nil {
t.Fatalf("unable to create CSV output: %v", err) t.Fatalf("unable to create CSV output: %v", err)
} }
@ -424,7 +424,7 @@ func TestBIP0068AndCsv(t *testing.T) {
spendableInputs[i] = csvOutput{ spendableInputs[i] = csvOutput{
RedeemScript: redeemScript, RedeemScript: redeemScript,
Utxo: utxo, Utxo: utxo,
Timelock: int32(timeLock), Timelock: int64(timeLock),
} }
} }

View File

@ -65,7 +65,7 @@ func directionString(inbound bool) string {
} }
// formatLockTime returns a transaction lock time as a human-readable 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 // 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 // which the transaction is finalized or a timestamp depending on if the
// value is before the lockTimeThreshold. When it is under the // value is before the lockTimeThreshold. When it is under the

View File

@ -599,7 +599,7 @@ func handleCreateRawTransaction(s *rpcServer, cmd interface{}, closeChan <-chan
// Set the Locktime, if given. // Set the Locktime, if given.
if c.LockTime != nil { if c.LockTime != nil {
mtx.LockTime = uint32(*c.LockTime) mtx.LockTime = int64(*c.LockTime)
} }
// Return the serialized and hex-encoded transaction. Note that this // Return the serialized and hex-encoded transaction. Note that this

View File

@ -1090,13 +1090,11 @@ func verifyLockTime(txLockTime, threshold, lockTime int64) error {
// LockTime field of the transaction containing the script signature // LockTime field of the transaction containing the script signature
// validating if the transaction outputs are spendable yet. // validating if the transaction outputs are spendable yet.
func opcodeCheckLockTimeVerify(op *parsedOpcode, vm *Engine) error { func opcodeCheckLockTimeVerify(op *parsedOpcode, vm *Engine) error {
// The current transaction locktime is a uint32 resulting in a maximum // The current transaction locktime is a int64 resulting in a maximum
// locktime of 2^32-1 (the year 2106). However, scriptNums are signed // 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 // 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 // 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 // here since it will support up to 2^39-1 which allows dates until the year 19400
// current locktime limit.
//
// PopByteArray is used here instead of PopInt because we do not want // PopByteArray is used here instead of PopInt because we do not want
// to be limited to a 4-byte integer for reasons specified above. // to be limited to a 4-byte integer for reasons specified above.
so, err := vm.dstack.PopByteArray() so, err := vm.dstack.PopByteArray()

View File

@ -356,7 +356,7 @@ func BenchmarkReadBlockHeader(b *testing.B) {
0x7a, 0xc7, 0x2c, 0x3e, 0x67, 0x76, 0x8f, 0x61, 0x7a, 0xc7, 0x2c, 0x3e, 0x67, 0x76, 0x8f, 0x61,
0x7f, 0xc8, 0x1b, 0xc3, 0x88, 0x8a, 0x51, 0x32, 0x7f, 0xc8, 0x1b, 0xc3, 0x88, 0x8a, 0x51, 0x32,
0x3a, 0x9f, 0xb8, 0xaa, 0x4b, 0x1e, 0x5e, 0x4a, // MerkleRoot 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 0xff, 0xff, 0x00, 0x1d, // Bits
0xf3, 0xe0, 0x01, 0x00, // Nonce 0xf3, 0xe0, 0x01, 0x00, // Nonce
0x00, // TxnCount Varint 0x00, // TxnCount Varint

View File

@ -42,7 +42,7 @@ type BlockHeader struct {
// blockHeaderLen is a constant that represents the number of bytes for a block // blockHeaderLen is a constant that represents the number of bytes for a block
// header. // header.
const blockHeaderLen = 80 const blockHeaderLen = 84
// BlockHash computes the block identifier hash for the given block header. // BlockHash computes the block identifier hash for the given block header.
func (h *BlockHeader) BlockHash() chainhash.Hash { func (h *BlockHeader) BlockHash() chainhash.Hash {
@ -115,14 +115,14 @@ func NewBlockHeader(version int32, prevHash, merkleRootHash *chainhash.Hash,
// decoding from the wire. // decoding from the wire.
func readBlockHeader(r io.Reader, pver uint32, bh *BlockHeader) error { func readBlockHeader(r io.Reader, pver uint32, bh *BlockHeader) error {
return readElements(r, &bh.Version, &bh.PrevBlock, &bh.MerkleRoot, 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 // 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 // encoding block headers to be stored to disk, such as in a database, as
// opposed to encoding for the wire. // opposed to encoding for the wire.
func writeBlockHeader(w io.Writer, pver uint32, bh *BlockHeader) error { 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, return writeElements(w, bh.Version, &bh.PrevBlock, &bh.MerkleRoot,
sec, bh.Bits, bh.Nonce) sec, bh.Bits, bh.Nonce)
} }

View File

@ -73,7 +73,7 @@ func TestBlockHeaderWire(t *testing.T) {
0x7a, 0xc7, 0x2c, 0x3e, 0x67, 0x76, 0x8f, 0x61, 0x7a, 0xc7, 0x2c, 0x3e, 0x67, 0x76, 0x8f, 0x61,
0x7f, 0xc8, 0x1b, 0xc3, 0x88, 0x8a, 0x51, 0x32, 0x7f, 0xc8, 0x1b, 0xc3, 0x88, 0x8a, 0x51, 0x32,
0x3a, 0x9f, 0xb8, 0xaa, 0x4b, 0x1e, 0x5e, 0x4a, // MerkleRoot 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 0xff, 0xff, 0x00, 0x1d, // Bits
0xf3, 0xe0, 0x01, 0x00, // Nonce 0xf3, 0xe0, 0x01, 0x00, // Nonce
} }
@ -206,7 +206,7 @@ func TestBlockHeaderSerialize(t *testing.T) {
0x7a, 0xc7, 0x2c, 0x3e, 0x67, 0x76, 0x8f, 0x61, 0x7a, 0xc7, 0x2c, 0x3e, 0x67, 0x76, 0x8f, 0x61,
0x7f, 0xc8, 0x1b, 0xc3, 0x88, 0x8a, 0x51, 0x32, 0x7f, 0xc8, 0x1b, 0xc3, 0x88, 0x8a, 0x51, 0x32,
0x3a, 0x9f, 0xb8, 0xaa, 0x4b, 0x1e, 0x5e, 0x4a, // MerkleRoot 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 0xff, 0xff, 0x00, 0x1d, // Bits
0xf3, 0xe0, 0x01, 0x00, // Nonce 0xf3, 0xe0, 0x01, 0x00, // Nonce
} }

View File

@ -176,11 +176,6 @@ var binarySerializer binaryFreeList = make(chan []byte, binaryFreeListMaxItems)
var errNonCanonicalVarInt = "non-canonical varint %x - discriminant %x must " + var errNonCanonicalVarInt = "non-canonical varint %x - discriminant %x must " +
"encode a value greater than %x" "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 // 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 // a way to signal the readElement function how to decode a timestamp into a Go
// time.Time since it is otherwise ambiguous. // time.Time since it is otherwise ambiguous.
@ -236,15 +231,6 @@ func readElement(r io.Reader, element interface{}) error {
} }
return nil 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. // Unix timestamp encoded as an int64.
case *int64Time: case *int64Time:
rv, err := binarySerializer.Uint64(r, binary.LittleEndian) rv, err := binarySerializer.Uint64(r, binary.LittleEndian)

View File

@ -89,11 +89,11 @@ func TestMessage(t *testing.T) {
{msgGetAddr, msgGetAddr, pver, MainNet, 24}, {msgGetAddr, msgGetAddr, pver, MainNet, 24},
{msgAddr, msgAddr, pver, MainNet, 25}, {msgAddr, msgAddr, pver, MainNet, 25},
{msgGetBlocks, msgGetBlocks, pver, MainNet, 61}, {msgGetBlocks, msgGetBlocks, pver, MainNet, 61},
{msgBlock, msgBlock, pver, MainNet, 239}, {msgBlock, msgBlock, pver, MainNet, 247},
{msgInv, msgInv, pver, MainNet, 25}, {msgInv, msgInv, pver, MainNet, 25},
{msgGetData, msgGetData, pver, MainNet, 25}, {msgGetData, msgGetData, pver, MainNet, 25},
{msgNotFound, msgNotFound, pver, MainNet, 25}, {msgNotFound, msgNotFound, pver, MainNet, 25},
{msgTx, msgTx, pver, MainNet, 34}, {msgTx, msgTx, pver, MainNet, 38},
{msgPing, msgPing, pver, MainNet, 32}, {msgPing, msgPing, pver, MainNet, 32},
{msgPong, msgPong, pver, MainNet, 32}, {msgPong, msgPong, pver, MainNet, 32},
{msgGetHeaders, msgGetHeaders, pver, MainNet, 61}, {msgGetHeaders, msgGetHeaders, pver, MainNet, 61},
@ -103,7 +103,7 @@ func TestMessage(t *testing.T) {
{msgFilterAdd, msgFilterAdd, pver, MainNet, 26}, {msgFilterAdd, msgFilterAdd, pver, MainNet, 26},
{msgFilterClear, msgFilterClear, pver, MainNet, 24}, {msgFilterClear, msgFilterClear, pver, MainNet, 24},
{msgFilterLoad, msgFilterLoad, pver, MainNet, 35}, {msgFilterLoad, msgFilterLoad, pver, MainNet, 35},
{msgMerkleBlock, msgMerkleBlock, pver, MainNet, 110}, {msgMerkleBlock, msgMerkleBlock, pver, MainNet, 114},
{msgReject, msgReject, pver, MainNet, 79}, {msgReject, msgReject, pver, MainNet, 79},
{msgGetCFilters, msgGetCFilters, pver, MainNet, 61}, {msgGetCFilters, msgGetCFilters, pver, MainNet, 61},
{msgGetCFHeaders, msgGetCFHeaders, pver, MainNet, 61}, {msgGetCFHeaders, msgGetCFHeaders, pver, MainNet, 61},

View File

@ -29,7 +29,7 @@ func TestAddr(t *testing.T) {
// Ensure max payload is expected value for latest protocol version. // Ensure max payload is expected value for latest protocol version.
// Num addresses (varInt) + max allowed addresses. // Num addresses (varInt) + max allowed addresses.
wantPayload := uint32(30009) wantPayload := uint32(34009)
maxPayload := msg.MaxPayloadLength(pver) maxPayload := msg.MaxPayloadLength(pver)
if maxPayload != wantPayload { if maxPayload != wantPayload {
t.Errorf("MaxPayloadLength: wrong max payload length for "+ t.Errorf("MaxPayloadLength: wrong max payload length for "+
@ -125,12 +125,12 @@ func TestAddrWire(t *testing.T) {
multiAddr.AddAddresses(na, na2) multiAddr.AddAddresses(na, na2)
multiAddrEncoded := []byte{ multiAddrEncoded := []byte{
0x02, // Varint for number of addresses 0x02, // Varint for number of addresses
0x29, 0xab, 0x5f, 0x49, // Timestamp 0x29, 0xab, 0x5f, 0x49, 0x00, 0x00, 0x00, 0x00, // Timestamp
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // SFNodeNetwork 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // SFNodeNetwork
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0xff, 0xff, 0x7f, 0x00, 0x00, 0x01, // IP 127.0.0.1 0x00, 0x00, 0xff, 0xff, 0x7f, 0x00, 0x00, 0x01, // IP 127.0.0.1
0x20, 0x8d, // Port 8333 in big-endian 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 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // SFNodeNetwork
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0xff, 0xff, 0xc0, 0xa8, 0x00, 0x01, // IP 192.168.0.1 0x00, 0x00, 0xff, 0xff, 0xc0, 0xa8, 0x00, 0x01, // IP 192.168.0.1
@ -226,12 +226,12 @@ func TestAddrWireErrors(t *testing.T) {
baseAddr.AddAddresses(na, na2) baseAddr.AddAddresses(na, na2)
baseAddrEncoded := []byte{ baseAddrEncoded := []byte{
0x02, // Varint for number of addresses 0x02, // Varint for number of addresses
0x29, 0xab, 0x5f, 0x49, // Timestamp 0x29, 0xab, 0x5f, 0x49, 0x00, 0x00, 0x00, 0x00, // Timestamp
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // SFNodeNetwork 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // SFNodeNetwork
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0xff, 0xff, 0x7f, 0x00, 0x00, 0x01, // IP 127.0.0.1 0x00, 0x00, 0xff, 0xff, 0x7f, 0x00, 0x00, 0x01, // IP 127.0.0.1
0x20, 0x8d, // Port 8333 in big-endian 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 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // SFNodeNetwork
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0xff, 0xff, 0xc0, 0xa8, 0x00, 0x01, // IP 192.168.0.1 0x00, 0x00, 0xff, 0xff, 0xc0, 0xa8, 0x00, 0x01, // IP 192.168.0.1

View File

@ -71,7 +71,7 @@ func TestBlock(t *testing.T) {
// hashes from a block accurately. // hashes from a block accurately.
func TestBlockTxHashes(t *testing.T) { func TestBlockTxHashes(t *testing.T) {
// Block 1, transaction 1 hash. // Block 1, transaction 1 hash.
hashStr := "0e3e2357e806b6cdb1f70b54c3a3a17b6714ee1f0e68bebb44a74b1efd512098" hashStr := "c52c57dcdaa5cbfd39ef73afb78b1fbb1e856f557dd5f8b53c49acbf21eb387a"
wantHash, err := chainhash.NewHashFromStr(hashStr) wantHash, err := chainhash.NewHashFromStr(hashStr)
if err != nil { if err != nil {
t.Errorf("NewHashFromStr: %v", err) 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. // TestBlockHash tests the ability to generate the hash of a block accurately.
func TestBlockHash(t *testing.T) { func TestBlockHash(t *testing.T) {
// Block 1 hash. // Block 1 hash.
hashStr := "839a8e6886ab5951d76f411475428afc90947ee320161bbf18eb6048" hashStr := "ec85da8297525c2a2a5f3e826510ea1a48ee741e13a18b93ceeb2fb6c9848925"
wantHash, err := chainhash.NewHashFromStr(hashStr) wantHash, err := chainhash.NewHashFromStr(hashStr)
if err != nil { if err != nil {
t.Errorf("NewHashFromStr: %v", err) t.Errorf("NewHashFromStr: %v", err)
@ -201,7 +201,7 @@ func TestBlockWireErrors(t *testing.T) {
// version. // version.
pver := uint32(60002) pver := uint32(60002)
tests := []struct { tests := []struct { //TODO: need to recheck this part (what are the correct max values)
in *MsgBlock // Value to encode in *MsgBlock // Value to encode
buf []byte // Wire encoding buf []byte // Wire encoding
pver uint32 // Protocol version for wire encoding pver uint32 // Protocol version for wire encoding
@ -218,13 +218,13 @@ func TestBlockWireErrors(t *testing.T) {
// Force error in timestamp. // Force error in timestamp.
{&blockOne, blockOneBytes, pver, 68, io.ErrShortWrite, io.EOF}, {&blockOne, blockOneBytes, pver, 68, io.ErrShortWrite, io.EOF},
// Force error in difficulty bits. // 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}, {&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}, {&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. // 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)) t.Logf("Running %d tests", len(tests))
@ -336,13 +336,13 @@ func TestBlockSerializeErrors(t *testing.T) {
// Force error in timestamp. // Force error in timestamp.
{&blockOne, blockOneBytes, 68, io.ErrShortWrite, io.EOF}, {&blockOne, blockOneBytes, 68, io.ErrShortWrite, io.EOF},
// Force error in difficulty bits. // Force error in difficulty bits.
{&blockOne, blockOneBytes, 72, io.ErrShortWrite, io.EOF},
// Force error in header nonce.
{&blockOne, blockOneBytes, 76, io.ErrShortWrite, io.EOF}, {&blockOne, blockOneBytes, 76, io.ErrShortWrite, io.EOF},
// Force error in transaction count. // Force error in header nonce.
{&blockOne, blockOneBytes, 80, io.ErrShortWrite, io.EOF}, {&blockOne, blockOneBytes, 80, io.ErrShortWrite, io.EOF},
// Force error in transaction count.
{&blockOne, blockOneBytes, 84, io.ErrShortWrite, io.EOF},
// Force error in transactions. // 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)) t.Logf("Running %d tests", len(tests))
@ -404,7 +404,7 @@ func TestBlockOverflowErrors(t *testing.T) {
0xbb, 0xbe, 0x68, 0x0e, 0x1f, 0xee, 0x14, 0x67, 0xbb, 0xbe, 0x68, 0x0e, 0x1f, 0xee, 0x14, 0x67,
0x7b, 0xa1, 0xa3, 0xc3, 0x54, 0x0b, 0xf7, 0xb1, 0x7b, 0xa1, 0xa3, 0xc3, 0x54, 0x0b, 0xf7, 0xb1,
0xcd, 0xb6, 0x06, 0xe8, 0x57, 0x23, 0x3e, 0x0e, // MerkleRoot 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 0xff, 0xff, 0x00, 0x1d, // Bits
0x01, 0xe3, 0x62, 0x99, // Nonce 0x01, 0xe3, 0x62, 0x99, // Nonce
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
@ -456,7 +456,7 @@ func TestBlockSerializeSize(t *testing.T) {
size int // Expected serialized size size int // Expected serialized size
}{ }{
// Block with no transactions. // Block with no transactions.
{noTxBlock, 81}, {noTxBlock, 85},
// First block in the mainnet block chain. // First block in the mainnet block chain.
{&blockOne, len(blockOneBytes)}, {&blockOne, len(blockOneBytes)},
@ -543,7 +543,7 @@ var blockOneBytes = []byte{
0xbb, 0xbe, 0x68, 0x0e, 0x1f, 0xee, 0x14, 0x67, 0xbb, 0xbe, 0x68, 0x0e, 0x1f, 0xee, 0x14, 0x67,
0x7b, 0xa1, 0xa3, 0xc3, 0x54, 0x0b, 0xf7, 0xb1, 0x7b, 0xa1, 0xa3, 0xc3, 0x54, 0x0b, 0xf7, 0xb1,
0xcd, 0xb6, 0x06, 0xe8, 0x57, 0x23, 0x3e, 0x0e, // MerkleRoot 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 0xff, 0xff, 0x00, 0x1d, // Bits
0x01, 0xe3, 0x62, 0x99, // Nonce 0x01, 0xe3, 0x62, 0x99, // Nonce
0x01, // TxnCount 0x01, // TxnCount
@ -571,10 +571,10 @@ var blockOneBytes = []byte{
0x73, 0xa8, 0x2c, 0xbf, 0x23, 0x42, 0xc8, 0x58, 0x73, 0xa8, 0x2c, 0xbf, 0x23, 0x42, 0xc8, 0x58,
0xee, // 65-byte uncompressed public key 0xee, // 65-byte uncompressed public key
0xac, // OP_CHECKSIG 0xac, // OP_CHECKSIG
0x00, 0x00, 0x00, 0x00, // Lock time 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Lock time
} }
// Transaction location information for block one transactions. // Transaction location information for block one transactions.
var blockOneTxLocs = []TxLoc{ var blockOneTxLocs = []TxLoc{
{TxStart: 81, TxLen: 134}, {TxStart: 85, TxLen: 138},
} }

View File

@ -88,7 +88,7 @@ func TestHeadersWire(t *testing.T) {
0xbb, 0xbe, 0x68, 0x0e, 0x1f, 0xee, 0x14, 0x67, 0xbb, 0xbe, 0x68, 0x0e, 0x1f, 0xee, 0x14, 0x67,
0x7b, 0xa1, 0xa3, 0xc3, 0x54, 0x0b, 0xf7, 0xb1, 0x7b, 0xa1, 0xa3, 0xc3, 0x54, 0x0b, 0xf7, 0xb1,
0xcd, 0xb6, 0x06, 0xe8, 0x57, 0x23, 0x3e, 0x0e, // MerkleRoot 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 0xff, 0xff, 0x00, 0x1d, // Bits
0x01, 0xe3, 0x62, 0x99, // Nonce 0x01, 0xe3, 0x62, 0x99, // Nonce
0x00, // TxnCount (0 for headers message) 0x00, // TxnCount (0 for headers message)
@ -239,7 +239,7 @@ func TestHeadersWireErrors(t *testing.T) {
0xbb, 0xbe, 0x68, 0x0e, 0x1f, 0xee, 0x14, 0x67, 0xbb, 0xbe, 0x68, 0x0e, 0x1f, 0xee, 0x14, 0x67,
0x7b, 0xa1, 0xa3, 0xc3, 0x54, 0x0b, 0xf7, 0xb1, 0x7b, 0xa1, 0xa3, 0xc3, 0x54, 0x0b, 0xf7, 0xb1,
0xcd, 0xb6, 0x06, 0xe8, 0x57, 0x23, 0x3e, 0x0e, // MerkleRoot 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 0xff, 0xff, 0x00, 0x1d, // Bits
0x01, 0xe3, 0x62, 0x99, // Nonce 0x01, 0xe3, 0x62, 0x99, // Nonce
0x00, // TxnCount (0 for headers message) 0x00, // TxnCount (0 for headers message)
@ -275,7 +275,7 @@ func TestHeadersWireErrors(t *testing.T) {
0xbb, 0xbe, 0x68, 0x0e, 0x1f, 0xee, 0x14, 0x67, 0xbb, 0xbe, 0x68, 0x0e, 0x1f, 0xee, 0x14, 0x67,
0x7b, 0xa1, 0xa3, 0xc3, 0x54, 0x0b, 0xf7, 0xb1, 0x7b, 0xa1, 0xa3, 0xc3, 0x54, 0x0b, 0xf7, 0xb1,
0xcd, 0xb6, 0x06, 0xe8, 0x57, 0x23, 0x3e, 0x0e, // MerkleRoot 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 0xff, 0xff, 0x00, 0x1d, // Bits
0x01, 0xe3, 0x62, 0x99, // Nonce 0x01, 0xe3, 0x62, 0x99, // Nonce
0x01, // TxnCount (should be 0 for headers message, but 1 to force error) 0x01, // TxnCount (should be 0 for headers message, but 1 to force error)

View File

@ -410,7 +410,7 @@ var merkleBlockOneBytes = []byte{
0xbb, 0xbe, 0x68, 0x0e, 0x1f, 0xee, 0x14, 0x67, 0xbb, 0xbe, 0x68, 0x0e, 0x1f, 0xee, 0x14, 0x67,
0x7b, 0xa1, 0xa3, 0xc3, 0x54, 0x0b, 0xf7, 0xb1, 0x7b, 0xa1, 0xa3, 0xc3, 0x54, 0x0b, 0xf7, 0xb1,
0xcd, 0xb6, 0x06, 0xe8, 0x57, 0x23, 0x3e, 0x0e, // MerkleRoot 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 0xff, 0xff, 0x00, 0x1d, // Bits
0x01, 0xe3, 0x62, 0x99, // Nonce 0x01, 0xe3, 0x62, 0x99, // Nonce
0x01, 0x00, 0x00, 0x00, // TxnCount 0x01, 0x00, 0x00, 0x00, // TxnCount

View File

@ -244,7 +244,7 @@ type MsgTx struct {
Version int32 Version int32
TxIn []*TxIn TxIn []*TxIn
TxOut []*TxOut TxOut []*TxOut
LockTime uint32 LockTime int64
} }
// AddTxIn adds a transaction input to the message. // 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)) 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 { if err != nil {
returnScriptBuffers() returnScriptBuffers()
return err 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 // 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 // SerializeSize returns the number of bytes it would take to serialize the
// the transaction. // the transaction.
func (msg *MsgTx) SerializeSize() int { 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. // 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))) VarIntSerializeSize(uint64(len(msg.TxOut)))
for _, txIn := range msg.TxIn { for _, txIn := range msg.TxIn {

View File

@ -128,7 +128,7 @@ func TestTx(t *testing.T) {
// TestTxHash tests the ability to generate the hash of a transaction accurately. // TestTxHash tests the ability to generate the hash of a transaction accurately.
func TestTxHash(t *testing.T) { func TestTxHash(t *testing.T) {
// Hash of first transaction from block 113875. // Hash of first transaction from block 113875.
hashStr := "f051e59b5e2503ac626d03aaeac8ab7be2d72ba4b7e97119c5852d70d52dcb86" hashStr := "a16521abfbac8dc484301bb57adc13ac72f71d42459c9c29c96b11972af2475c"
wantHash, err := chainhash.NewHashFromStr(hashStr) wantHash, err := chainhash.NewHashFromStr(hashStr)
if err != nil { if err != nil {
t.Errorf("NewHashFromStr: %v", err) t.Errorf("NewHashFromStr: %v", err)

View File

@ -19,8 +19,8 @@ func maxNetAddressPayload(pver uint32) uint32 {
// NetAddressTimeVersion added a timestamp field. // NetAddressTimeVersion added a timestamp field.
if pver >= NetAddressTimeVersion { if pver >= NetAddressTimeVersion {
// Timestamp 4 bytes. // Timestamp 8 bytes.
plen += 4 plen += 8
} }
return plen return plen
@ -29,10 +29,7 @@ func maxNetAddressPayload(pver uint32) uint32 {
// NetAddress defines information about a peer on the network including the time // 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. // it was last seen, the services it supports, its IP address, and port.
type NetAddress struct { type NetAddress struct {
// Last time the address was seen. This is, unfortunately, encoded as a // Last time the address was seen.
// 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.
Timestamp time.Time Timestamp time.Time
// Bitfield which identifies the services supported by the address. // 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 { func readNetAddress(r io.Reader, pver uint32, na *NetAddress, ts bool) error {
var ip [16]byte 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 { if ts && pver >= NetAddressTimeVersion {
err := readElement(r, (*uint32Time)(&na.Timestamp)) err := readElement(r, (*int64Time)(&na.Timestamp))
if err != nil { if err != nil {
return err 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 // version and whether or not the timestamp is included per ts. Some messages
// like version do not include the timestamp. // like version do not include the timestamp.
func writeNetAddress(w io.Writer, pver uint32, na *NetAddress, ts bool) error { 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 // Timestamp wasn't added until protocol version >= NetAddressTimeVersion.
// stop working somewhere around 2106. Also timestamp wasn't added until
// until protocol version >= NetAddressTimeVersion.
if ts && pver >= NetAddressTimeVersion { if ts && pver >= NetAddressTimeVersion {
err := writeElement(w, uint32(na.Timestamp.Unix())) err := writeElement(w, int64(na.Timestamp.Unix()))
if err != nil { if err != nil {
return err return err
} }

View File

@ -88,7 +88,7 @@ func TestNetAddressWire(t *testing.T) {
// baseNetAddrEncoded is the wire encoded bytes of baseNetAddr. // baseNetAddrEncoded is the wire encoded bytes of baseNetAddr.
baseNetAddrEncoded := []byte{ 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 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // SFNodeNetwork
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0xff, 0xff, 0x7f, 0x00, 0x00, 0x01, // IP 127.0.0.1 0x00, 0x00, 0xff, 0xff, 0x7f, 0x00, 0x00, 0x01, // IP 127.0.0.1