[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.
// 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 {

View File

@ -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
// <><------------------------------------------------------------------>

View File

@ -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 {

View File

@ -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
// <><><><------------------------------------------------------------------>

View File

@ -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{

View File

@ -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"`
}

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=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=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 />
***
@ -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

View File

@ -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: <sequenceLock> 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),
}
}

View File

@ -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

View File

@ -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

View File

@ -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()

View File

@ -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

View File

@ -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)
}

View File

@ -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
}

View File

@ -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)

View File

@ -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},

View File

@ -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

View File

@ -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},
}

View File

@ -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)

View File

@ -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

View File

@ -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 {

View File

@ -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)

View File

@ -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
}

View File

@ -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