// TestBlockHeader tests the BlockHeader API. func TestBlockHeader(t *testing.T) { nonce64, err := wire.RandomUint64() if err != nil { t.Errorf("RandomUint64: Error generating nonce: %v", err) } nonce := uint32(nonce64) hash := mainNetGenesisHash merkleHash := mainNetGenesisMerkleRoot bits := uint32(0x1d00ffff) bh := wire.NewBlockHeader(&hash, &merkleHash, bits, nonce) // Ensure we get the same data back out. if !bh.PrevBlock.IsEqual(&hash) { t.Errorf("NewBlockHeader: wrong prev hash - got %v, want %v", spew.Sprint(bh.PrevBlock), spew.Sprint(hash)) } if !bh.MerkleRoot.IsEqual(&merkleHash) { t.Errorf("NewBlockHeader: wrong merkle root - got %v, want %v", spew.Sprint(bh.MerkleRoot), spew.Sprint(merkleHash)) } if bh.Bits != bits { t.Errorf("NewBlockHeader: wrong bits - got %v, want %v", bh.Bits, bits) } if bh.Nonce != nonce { t.Errorf("NewBlockHeader: wrong nonce - got %v, want %v", bh.Nonce, nonce) } }
// TestGetData tests the MsgGetData API. func TestGetData(t *testing.T) { pver := ProtocolVersion // Ensure the command is expected value. wantCmd := "getdata" msg := NewMsgGetData() if cmd := msg.Command(); cmd != wantCmd { t.Errorf("NewMsgGetData: wrong command - got %v want %v", cmd, wantCmd) } // Ensure max payload is expected value for latest protocol version. // Num inventory vectors (varInt) + max allowed inventory vectors. wantPayload := uint32(1800009) maxPayload := msg.MaxPayloadLength(pver) if maxPayload != wantPayload { t.Errorf("MaxPayloadLength: wrong max payload length for "+ "protocol version %d - got %v, want %v", pver, maxPayload, wantPayload) } // Ensure inventory vectors are added properly. hash := chainhash.Hash{} iv := NewInvVect(InvTypeBlock, &hash) err := msg.AddInvVect(iv) if err != nil { t.Errorf("AddInvVect: %v", err) } if msg.InvList[0] != iv { t.Errorf("AddInvVect: wrong invvect added - got %v, want %v", spew.Sprint(msg.InvList[0]), spew.Sprint(iv)) } // Ensure adding more than the max allowed inventory vectors per // message returns an error. for i := 0; i < MaxInvPerMsg; i++ { err = msg.AddInvVect(iv) } if err == nil { t.Errorf("AddInvVect: expected error on too many inventory " + "vectors not received") } // Ensure creating the message with a size hint larger than the max // works as expected. msg = NewMsgGetDataSizeHint(MaxInvPerMsg + 1) wantCap := MaxInvPerMsg if cap(msg.InvList) != wantCap { t.Errorf("NewMsgGetDataSizeHint: wrong cap for size hint - "+ "got %v, want %v", cap(msg.InvList), wantCap) } return }
// TestGetHeaders tests the MsgGetHeader API. func TestGetHeaders(t *testing.T) { pver := wire.ProtocolVersion // Block 99500 hash. hashStr := "000000000002e7ad7b9eef9479e4aabc65cb831269cc20d2632c13684406dee0" locatorHash, err := chainhash.NewHashFromStr(hashStr) if err != nil { t.Errorf("NewShaHashFromStr: %v", err) } // Ensure the command is expected value. wantCmd := "getheaders" msg := wire.NewMsgGetHeaders() if cmd := msg.Command(); cmd != wantCmd { t.Errorf("NewMsgGetHeaders: wrong command - got %v want %v", cmd, wantCmd) } // Ensure max payload is expected value for latest protocol version. // Protocol version 4 bytes + num hashes (varInt) + max block locator // hashes + hash stop. wantPayload := uint32(16045) maxPayload := msg.MaxPayloadLength(pver) if maxPayload != wantPayload { t.Errorf("MaxPayloadLength: wrong max payload length for "+ "protocol version %d - got %v, want %v", pver, maxPayload, wantPayload) } // Ensure block locator hashes are added properly. err = msg.AddBlockLocatorHash(locatorHash) if err != nil { t.Errorf("AddBlockLocatorHash: %v", err) } if msg.BlockLocatorHashes[0] != locatorHash { t.Errorf("AddBlockLocatorHash: wrong block locator added - "+ "got %v, want %v", spew.Sprint(msg.BlockLocatorHashes[0]), spew.Sprint(locatorHash)) } // Ensure adding more than the max allowed block locator hashes per // message returns an error. for i := 0; i < wire.MaxBlockLocatorsPerMsg; i++ { err = msg.AddBlockLocatorHash(locatorHash) } if err == nil { t.Errorf("AddBlockLocatorHash: expected error on too many " + "block locator hashes not received") } return }
// TestTxSha tests the ability to generate the hash of a transaction accurately. func TestTxSha(t *testing.T) { // Hash of first transaction from block 113875. hashStr := "4538fc1618badd058ee88fd020984451024858796be0a1ed111877f887e1bd53" wantHash, err := chainhash.NewHashFromStr(hashStr) if err != nil { t.Errorf("NewShaHashFromStr: %v", err) return } msgTx := wire.NewMsgTx() txIn := wire.TxIn{ PreviousOutPoint: wire.OutPoint{ Hash: chainhash.Hash{}, Index: 0xffffffff, Tree: dcrutil.TxTreeRegular, }, Sequence: 0xffffffff, ValueIn: 5000000000, BlockHeight: 0x3F3F3F3F, BlockIndex: 0x2E2E2E2E, SignatureScript: []byte{0x04, 0x31, 0xdc, 0x00, 0x1b, 0x01, 0x62}, } txOut := wire.TxOut{ Value: 5000000000, Version: 0xF0F0, PkScript: []byte{ 0x41, // OP_DATA_65 0x04, 0xd6, 0x4b, 0xdf, 0xd0, 0x9e, 0xb1, 0xc5, 0xfe, 0x29, 0x5a, 0xbd, 0xeb, 0x1d, 0xca, 0x42, 0x81, 0xbe, 0x98, 0x8e, 0x2d, 0xa0, 0xb6, 0xc1, 0xc6, 0xa5, 0x9d, 0xc2, 0x26, 0xc2, 0x86, 0x24, 0xe1, 0x81, 0x75, 0xe8, 0x51, 0xc9, 0x6b, 0x97, 0x3d, 0x81, 0xb0, 0x1c, 0xc3, 0x1f, 0x04, 0x78, 0x34, 0xbc, 0x06, 0xd6, 0xd6, 0xed, 0xf6, 0x20, 0xd1, 0x84, 0x24, 0x1a, 0x6a, 0xed, 0x8b, 0x63, 0xa6, // 65-byte signature 0xac, // OP_CHECKSIG }, } msgTx.AddTxIn(&txIn) msgTx.AddTxOut(&txOut) msgTx.LockTime = 0 msgTx.Expiry = 0 // Ensure the hash produced is expected. txHash := msgTx.TxSha() if !txHash.IsEqual(wantHash) { t.Errorf("TxSha: wrong hash - got %v, want %v", spew.Sprint(txHash), spew.Sprint(wantHash)) } }
func TestTxSha(t *testing.T) { pver := btcwire.ProtocolVersion // Hash of first transaction from block 113875. hashStr := "f051e59b5e2503ac626d03aaeac8ab7be2d72ba4b7e97119c5852d70d52dcb86" wantHash, err := btcwire.NewShaHashFromStr(hashStr) if err != nil { t.Errorf("NewShaHashFromStr: %v", err) return } // First transaction from block 113875. msgTx := btcwire.NewMsgTx() txIn := btcwire.TxIn{ PreviousOutpoint: btcwire.OutPoint{ Hash: btcwire.ShaHash{0x00}, Index: 0xffffffff, }, SignatureScript: []byte{0x04, 0x31, 0xdc, 0x00, 0x1b, 0x01, 0x62}, Sequence: 0xffffffff, } txOut := btcwire.TxOut{ Value: 5000000000, PkScript: []byte{ 0x41, // OP_DATA_65 0x04, 0xd6, 0x4b, 0xdf, 0xd0, 0x9e, 0xb1, 0xc5, 0xfe, 0x29, 0x5a, 0xbd, 0xeb, 0x1d, 0xca, 0x42, 0x81, 0xbe, 0x98, 0x8e, 0x2d, 0xa0, 0xb6, 0xc1, 0xc6, 0xa5, 0x9d, 0xc2, 0x26, 0xc2, 0x86, 0x24, 0xe1, 0x81, 0x75, 0xe8, 0x51, 0xc9, 0x6b, 0x97, 0x3d, 0x81, 0xb0, 0x1c, 0xc3, 0x1f, 0x04, 0x78, 0x34, 0xbc, 0x06, 0xd6, 0xd6, 0xed, 0xf6, 0x20, 0xd1, 0x84, 0x24, 0x1a, 0x6a, 0xed, 0x8b, 0x63, 0xa6, // 65-byte signature 0xac, // OP_CHECKSIG }, } msgTx.AddTxIn(&txIn) msgTx.AddTxOut(&txOut) msgTx.LockTime = 0 // Ensure the hash produced is expected. txHash, err := msgTx.TxSha(pver) if err != nil { t.Errorf("TxSha: %v", err) } if !txHash.IsEqual(wantHash) { t.Errorf("TxSha: wrong hash - got %v, want %v", spew.Sprint(txHash), spew.Sprint(wantHash)) } }
// TestBlockSha tests the ability to generate the hash of a block accurately. func TestBlockSha(t *testing.T) { // Block 1 hash. hashStr := "152437dada95368c42b19febc1702939fa9c1ccdb6fd7284e5b7a19d8fe6df7a" wantHash, err := chainhash.NewHashFromStr(hashStr) if err != nil { t.Errorf("NewShaHashFromStr: %v", err) } // Ensure the hash produced is expected. blockHash := testBlock.BlockSha() if !blockHash.IsEqual(wantHash) { t.Errorf("BlockSha: wrong hash - got %v, want %v", spew.Sprint(blockHash), spew.Sprint(wantHash)) } }
// TestBlockSha tests the ability to generate the hash of a block accurately. func TestBlockSha(t *testing.T) { // Block 1 hash. hashStr := "839a8e6886ab5951d76f411475428afc90947ee320161bbf18eb6048" wantHash, err := wire.NewShaHashFromStr(hashStr) if err != nil { t.Errorf("NewShaHashFromStr: %v", err) } // Ensure the hash produced is expected. blockHash := blockOne.BlockSha() if !blockHash.IsEqual(wantHash) { t.Errorf("BlockSha: wrong hash - got %v, want %v", spew.Sprint(blockHash), spew.Sprint(wantHash)) } }
// TestBlockSha tests the ability to generate the hash of a block accurately. func TestBlockSha(t *testing.T) { // Block 1 hash. hashStr := "6b73b6f6faebbfd6a541f38820593e43c50ce1abf64602ab8ac7d5502991c37f" wantHash, err := chainhash.NewHashFromStr(hashStr) if err != nil { t.Errorf("NewShaHashFromStr: %v", err) } // Ensure the hash produced is expected. blockHash := testBlock.BlockSha() if !blockHash.IsEqual(wantHash) { t.Errorf("BlockSha: wrong hash - got %v, want %v", spew.Sprint(blockHash), spew.Sprint(wantHash)) } }
func dumper() { c := time.Tick(5 * time.Second) for _ = range c { Linfo.Printf("DUMP:\n%s", spew.Sprint(gmap.MyStore)) dumpStats() } }
// TestNotFound tests the MsgNotFound API. func TestNotFound(t *testing.T) { pver := btcwire.ProtocolVersion // Ensure the command is expected value. wantCmd := "notfound" msg := btcwire.NewMsgNotFound() if cmd := msg.Command(); cmd != wantCmd { t.Errorf("NewMsgNotFound: wrong command - got %v want %v", cmd, wantCmd) } // Ensure max payload is expected value for latest protocol version. // Num inventory vectors (varInt) + max allowed inventory vectors. wantPayload := uint32(1800009) maxPayload := msg.MaxPayloadLength(pver) if maxPayload != wantPayload { t.Errorf("MaxPayloadLength: wrong max payload length for "+ "protocol version %d - got %v, want %v", pver, maxPayload, wantPayload) } // Ensure inventory vectors are added properly. hash := btcwire.ShaHash{} iv := btcwire.NewInvVect(btcwire.InvVect_Block, &hash) err := msg.AddInvVect(iv) if err != nil { t.Errorf("AddInvVect: %v", err) } if msg.InvList[0] != iv { t.Errorf("AddInvVect: wrong invvect added - got %v, want %v", spew.Sprint(msg.InvList[0]), spew.Sprint(iv)) } // Ensure adding more than the max allowed inventory vectors per // message returns an error. for i := 0; i < btcwire.MaxInvPerMsg; i++ { err = msg.AddInvVect(iv) } if err == nil { t.Errorf("AddInvVect: expected error on too many inventory " + "vectors not received") } return }
// TestBlockSha tests the ability to generate the hash of a block accurately. func TestBlockSha(t *testing.T) { // Use protocol version 60002 specifically here instead of the latest // because the test data is using bytes encoded with that protocol // version. pver := uint32(60002) // Block 1 hash. hashStr := "839a8e6886ab5951d76f411475428afc90947ee320161bbf18eb6048" wantHash, err := btcwire.NewShaHashFromStr(hashStr) if err != nil { t.Errorf("NewShaHashFromStr: %v", err) } // Ensure the hash produced is expected. blockHash, err := blockOne.BlockSha(pver) if err != nil { t.Errorf("BlockSha: %v", err) } if !blockHash.IsEqual(wantHash) { t.Errorf("BlockSha: wrong hash - got %v, want %v", spew.Sprint(blockHash), spew.Sprint(wantHash)) } }
func TestCompileModelSpec(t *testing.T) { type Primative struct { Int int String string Bool bool } type Unexported struct { privateInt int privateString string privateBool bool } type Pointer struct { Int *int String *string Bool *bool } type Indexed struct { Int int `zoom:"index"` String string `zoom:"index"` Bool bool `zoom:"index"` } type Ignored struct { Int int `redis:"-"` String string `redis:"-"` Bool bool `redis:"-"` } type CustomName struct { Int int `redis:"myInt"` String string `redis:"myString"` Bool bool `redis:"myBool"` } testCases := []struct { model interface{} expectedSpec *modelSpec }{ { model: &Primative{}, expectedSpec: &modelSpec{ typ: reflect.TypeOf(&Primative{}), name: "Primative", fieldsByName: map[string]*fieldSpec{ "Int": &fieldSpec{ kind: primativeField, name: "Int", redisName: "Int", typ: reflect.TypeOf(Primative{}.Int), indexKind: noIndex, }, "String": &fieldSpec{ kind: primativeField, name: "String", redisName: "String", typ: reflect.TypeOf(Primative{}.String), indexKind: noIndex, }, "Bool": &fieldSpec{ kind: primativeField, name: "Bool", redisName: "Bool", typ: reflect.TypeOf(Primative{}.Bool), indexKind: noIndex, }, }, fields: []*fieldSpec{ { kind: primativeField, name: "Int", redisName: "Int", typ: reflect.TypeOf(Primative{}.Int), indexKind: noIndex, }, { kind: primativeField, name: "String", redisName: "String", typ: reflect.TypeOf(Primative{}.String), indexKind: noIndex, }, { kind: primativeField, name: "Bool", redisName: "Bool", typ: reflect.TypeOf(Primative{}.Bool), indexKind: noIndex, }, }, }, }, { model: &Unexported{}, expectedSpec: &modelSpec{ typ: reflect.TypeOf(&Unexported{}), name: "Unexported", fieldsByName: map[string]*fieldSpec{}, }, }, { model: &Pointer{}, expectedSpec: &modelSpec{ typ: reflect.TypeOf(&Pointer{}), name: "Pointer", fieldsByName: map[string]*fieldSpec{ "Int": &fieldSpec{ kind: pointerField, name: "Int", redisName: "Int", typ: reflect.TypeOf(Pointer{}.Int), indexKind: noIndex, }, "String": &fieldSpec{ kind: pointerField, name: "String", redisName: "String", typ: reflect.TypeOf(Pointer{}.String), indexKind: noIndex, }, "Bool": &fieldSpec{ kind: pointerField, name: "Bool", redisName: "Bool", typ: reflect.TypeOf(Pointer{}.Bool), indexKind: noIndex, }, }, fields: []*fieldSpec{ { kind: pointerField, name: "Int", redisName: "Int", typ: reflect.TypeOf(Pointer{}.Int), indexKind: noIndex, }, { kind: pointerField, name: "String", redisName: "String", typ: reflect.TypeOf(Pointer{}.String), indexKind: noIndex, }, { kind: pointerField, name: "Bool", redisName: "Bool", typ: reflect.TypeOf(Pointer{}.Bool), indexKind: noIndex, }, }, }, }, { model: &Indexed{}, expectedSpec: &modelSpec{ typ: reflect.TypeOf(&Indexed{}), name: "Indexed", fieldsByName: map[string]*fieldSpec{ "Int": &fieldSpec{ kind: primativeField, name: "Int", redisName: "Int", typ: reflect.TypeOf(Indexed{}.Int), indexKind: numericIndex, }, "String": &fieldSpec{ kind: primativeField, name: "String", redisName: "String", typ: reflect.TypeOf(Indexed{}.String), indexKind: stringIndex, }, "Bool": &fieldSpec{ kind: primativeField, name: "Bool", redisName: "Bool", typ: reflect.TypeOf(Indexed{}.Bool), indexKind: booleanIndex, }, }, fields: []*fieldSpec{ { kind: primativeField, name: "Int", redisName: "Int", typ: reflect.TypeOf(Indexed{}.Int), indexKind: numericIndex, }, { kind: primativeField, name: "String", redisName: "String", typ: reflect.TypeOf(Indexed{}.String), indexKind: stringIndex, }, { kind: primativeField, name: "Bool", redisName: "Bool", typ: reflect.TypeOf(Indexed{}.Bool), indexKind: booleanIndex, }, }, }, }, { model: &Ignored{}, expectedSpec: &modelSpec{ typ: reflect.TypeOf(&Ignored{}), name: "Ignored", fieldsByName: map[string]*fieldSpec{}, }, }, { model: &CustomName{}, expectedSpec: &modelSpec{ typ: reflect.TypeOf(&CustomName{}), name: "CustomName", fieldsByName: map[string]*fieldSpec{ "Int": &fieldSpec{ kind: primativeField, name: "Int", redisName: "myInt", typ: reflect.TypeOf(CustomName{}.Int), indexKind: noIndex, }, "String": &fieldSpec{ kind: primativeField, name: "String", redisName: "myString", typ: reflect.TypeOf(CustomName{}.String), indexKind: noIndex, }, "Bool": &fieldSpec{ kind: primativeField, name: "Bool", redisName: "myBool", typ: reflect.TypeOf(CustomName{}.Bool), indexKind: noIndex, }, }, fields: []*fieldSpec{ { kind: primativeField, name: "Int", redisName: "myInt", typ: reflect.TypeOf(CustomName{}.Int), indexKind: noIndex, }, { kind: primativeField, name: "String", redisName: "myString", typ: reflect.TypeOf(CustomName{}.String), indexKind: noIndex, }, { kind: primativeField, name: "Bool", redisName: "myBool", typ: reflect.TypeOf(CustomName{}.Bool), indexKind: noIndex, }, }, }, }, } for _, tc := range testCases { gotSpec, err := compileModelSpec(reflect.TypeOf(tc.model)) if err != nil { t.Error("Error compiling model spec: ", err.Error()) continue } if !reflect.DeepEqual(tc.expectedSpec, gotSpec) { t.Errorf( "Incorrect model spec.\nExpected: %s\nBut got: %s\n", spew.Sprint(tc.expectedSpec), spew.Sprint(gotSpec), ) } } }
// TestGetBlocks tests the MsgGetBlocks API. func TestGetBlocks(t *testing.T) { pver := btcwire.ProtocolVersion // Block 99500 hash. hashStr := "000000000002e7ad7b9eef9479e4aabc65cb831269cc20d2632c13684406dee0" locatorHash, err := btcwire.NewShaHashFromStr(hashStr) if err != nil { t.Errorf("NewShaHashFromStr: %v", err) } // Block 100000 hash. hashStr = "3ba27aa200b1cecaad478d2b00432346c3f1f3986da1afd33e506" hashStop, err := btcwire.NewShaHashFromStr(hashStr) if err != nil { t.Errorf("NewShaHashFromStr: %v", err) } // Ensure we get the same data back out. msg := btcwire.NewMsgGetBlocks(hashStop) if !msg.HashStop.IsEqual(hashStop) { t.Errorf("NewMsgGetBlocks: wrong stop hash - got %v, want %v", msg.HashStop, hashStop) } // Ensure the command is expected value. wantCmd := "getblocks" if cmd := msg.Command(); cmd != wantCmd { t.Errorf("NewMsgGetBlocks: wrong command - got %v want %v", cmd, wantCmd) } // Ensure max payload is expected value for latest protocol version. // Protocol version 4 bytes + num hashes (varInt) + max block locator // hashes + hash stop. wantPayload := uint32(16045) maxPayload := msg.MaxPayloadLength(pver) if maxPayload != wantPayload { t.Errorf("MaxPayloadLength: wrong max payload length for "+ "protocol version %d - got %v, want %v", pver, maxPayload, wantPayload) } // Ensure block locator hashes are added properly. err = msg.AddBlockLocatorHash(locatorHash) if err != nil { t.Errorf("AddBlockLocatorHash: %v", err) } if msg.BlockLocatorHashes[0] != locatorHash { t.Errorf("AddBlockLocatorHash: wrong block locator added - "+ "got %v, want %v", spew.Sprint(msg.BlockLocatorHashes[0]), spew.Sprint(locatorHash)) } // Ensure adding more than the max allowed block locator hashes per // message returns an error. for i := 0; i < btcwire.MaxBlockLocatorsPerMsg; i++ { err = msg.AddBlockLocatorHash(locatorHash) } if err == nil { t.Errorf("AddBlockLocatorHash: expected error on too many " + "block locator hashes not received") } return }
// TestTx tests the MsgTx API. func TestTx(t *testing.T) { pver := btcwire.ProtocolVersion // Block 100000 hash. hashStr := "3ba27aa200b1cecaad478d2b00432346c3f1f3986da1afd33e506" hash, err := btcwire.NewShaHashFromStr(hashStr) if err != nil { t.Errorf("NewShaHashFromStr: %v", err) } // Ensure the command is expected value. wantCmd := "tx" msg := btcwire.NewMsgTx() if cmd := msg.Command(); cmd != wantCmd { t.Errorf("NewMsgAddr: wrong command - got %v want %v", cmd, wantCmd) } // Ensure max payload is expected value for latest protocol version. // Num addresses (varInt) + max allowed addresses. wantPayload := uint32(1000 * 1000) maxPayload := msg.MaxPayloadLength(pver) if maxPayload != wantPayload { t.Errorf("MaxPayloadLength: wrong max payload length for "+ "protocol version %d - got %v, want %v", pver, maxPayload, wantPayload) } // Ensure we get the same transaction output point data back out. prevOutIndex := uint32(1) prevOut := btcwire.NewOutPoint(hash, prevOutIndex) if !prevOut.Hash.IsEqual(hash) { t.Errorf("NewOutPoint: wrong hash - got %v, want %v", spew.Sprint(&prevOut.Hash), spew.Sprint(hash)) } if prevOut.Index != prevOutIndex { t.Errorf("NewOutPoint: wrong index - got %v, want %v", prevOut.Index, prevOutIndex) } // Ensure we get the same transaction input back out. sigScript := []byte{0x04, 0x31, 0xdc, 0x00, 0x1b, 0x01, 0x62} txIn := btcwire.NewTxIn(prevOut, sigScript) if !reflect.DeepEqual(&txIn.PreviousOutpoint, prevOut) { t.Errorf("NewTxIn: wrong prev outpoint - got %v, want %v", spew.Sprint(&txIn.PreviousOutpoint), spew.Sprint(prevOut)) } if !bytes.Equal(txIn.SignatureScript, sigScript) { t.Errorf("NewTxIn: wrong signature script - got %v, want %v", spew.Sdump(txIn.SignatureScript), spew.Sdump(sigScript)) } // Ensure we get the same transaction output back out. txValue := int64(5000000000) pkScript := []byte{ 0x41, // OP_DATA_65 0x04, 0xd6, 0x4b, 0xdf, 0xd0, 0x9e, 0xb1, 0xc5, 0xfe, 0x29, 0x5a, 0xbd, 0xeb, 0x1d, 0xca, 0x42, 0x81, 0xbe, 0x98, 0x8e, 0x2d, 0xa0, 0xb6, 0xc1, 0xc6, 0xa5, 0x9d, 0xc2, 0x26, 0xc2, 0x86, 0x24, 0xe1, 0x81, 0x75, 0xe8, 0x51, 0xc9, 0x6b, 0x97, 0x3d, 0x81, 0xb0, 0x1c, 0xc3, 0x1f, 0x04, 0x78, 0x34, 0xbc, 0x06, 0xd6, 0xd6, 0xed, 0xf6, 0x20, 0xd1, 0x84, 0x24, 0x1a, 0x6a, 0xed, 0x8b, 0x63, 0xa6, // 65-byte signature 0xac, // OP_CHECKSIG } txOut := btcwire.NewTxOut(txValue, pkScript) if txOut.Value != txValue { t.Errorf("NewTxOut: wrong pk script - got %v, want %v", txOut.Value, txValue) } if !bytes.Equal(txOut.PkScript, pkScript) { t.Errorf("NewTxOut: wrong pk script - got %v, want %v", spew.Sdump(txOut.PkScript), spew.Sdump(pkScript)) } // Ensure transaction inputs are added properly. msg.AddTxIn(txIn) if !reflect.DeepEqual(msg.TxIn[0], txIn) { t.Errorf("AddTxIn: wrong transaction input added - got %v, want %v", spew.Sprint(msg.TxIn[0]), spew.Sprint(txIn)) } // Ensure transaction outputs are added properly. msg.AddTxOut(txOut) if !reflect.DeepEqual(msg.TxOut[0], txOut) { t.Errorf("AddTxIn: wrong transaction output added - got %v, want %v", spew.Sprint(msg.TxOut[0]), spew.Sprint(txOut)) } // Ensure the copy produced an identical transaction message. newMsg := msg.Copy() if !reflect.DeepEqual(newMsg, msg) { t.Errorf("Copy: mismatched tx messages - got %v, want %v", spew.Sdump(newMsg), spew.Sdump(msg)) } return }
// TestAddr tests the MsgAddr API. func TestAddr(t *testing.T) { pver := wire.ProtocolVersion // Ensure the command is expected value. wantCmd := "addr" msg := wire.NewMsgAddr() if cmd := msg.Command(); cmd != wantCmd { t.Errorf("NewMsgAddr: wrong command - got %v want %v", cmd, wantCmd) } // Ensure max payload is expected value for latest protocol version. // Num addresses (varInt) + max allowed addresses. wantPayload := uint32(30009) maxPayload := msg.MaxPayloadLength(pver) if maxPayload != wantPayload { t.Errorf("MaxPayloadLength: wrong max payload length for "+ "protocol version %d - got %v, want %v", pver, maxPayload, wantPayload) } // Ensure NetAddresses are added properly. tcpAddr := &net.TCPAddr{IP: net.ParseIP("127.0.0.1"), Port: 8333} na, err := wire.NewNetAddress(tcpAddr, wire.SFNodeNetwork) if err != nil { t.Errorf("NewNetAddress: %v", err) } err = msg.AddAddress(na) if err != nil { t.Errorf("AddAddress: %v", err) } if msg.AddrList[0] != na { t.Errorf("AddAddress: wrong address added - got %v, want %v", spew.Sprint(msg.AddrList[0]), spew.Sprint(na)) } // Ensure the address list is cleared properly. msg.ClearAddresses() if len(msg.AddrList) != 0 { t.Errorf("ClearAddresses: address list is not empty - "+ "got %v [%v], want %v", len(msg.AddrList), spew.Sprint(msg.AddrList[0]), 0) } // Ensure adding more than the max allowed addresses per message returns // error. for i := 0; i < wire.MaxAddrPerMsg+1; i++ { err = msg.AddAddress(na) } if err == nil { t.Errorf("AddAddress: expected error on too many addresses " + "not received") } err = msg.AddAddresses(na) if err == nil { t.Errorf("AddAddresses: expected error on too many addresses " + "not received") } return }
func TestGroupReaper(t *testing.T) { tests := []struct { name string group string objects []runtime.Object expected []interface{} }{ { name: "no objects", group: "mygroup", objects: []runtime.Object{}, expected: []interface{}{ ktestclient.DeleteActionImpl{ActionImpl: ktestclient.ActionImpl{Verb: "delete", Resource: "groups"}, Name: "mygroup"}, }, }, { name: "cluster bindings", group: "mygroup", objects: []runtime.Object{ &authorizationapi.ClusterRoleBinding{ ObjectMeta: kapi.ObjectMeta{Name: "binding-no-subjects"}, RoleRef: kapi.ObjectReference{Name: "role"}, Subjects: []kapi.ObjectReference{}, }, &authorizationapi.ClusterRoleBinding{ ObjectMeta: kapi.ObjectMeta{Name: "binding-one-subject"}, RoleRef: kapi.ObjectReference{Name: "role"}, Subjects: []kapi.ObjectReference{{Name: "mygroup", Kind: "Group"}}, }, &authorizationapi.ClusterRoleBinding{ ObjectMeta: kapi.ObjectMeta{Name: "binding-mismatched-subject"}, RoleRef: kapi.ObjectReference{Name: "role"}, Subjects: []kapi.ObjectReference{{Name: "mygroup"}, {Name: "mygroup", Kind: "User"}, {Name: "mygroup", Kind: "Other"}}, }, }, expected: []interface{}{ ktestclient.UpdateActionImpl{ActionImpl: ktestclient.ActionImpl{Verb: "update", Resource: "clusterrolebindings"}, Object: &authorizationapi.ClusterRoleBinding{ ObjectMeta: kapi.ObjectMeta{Name: "binding-one-subject"}, RoleRef: kapi.ObjectReference{Name: "role"}, Subjects: []kapi.ObjectReference{}, }}, ktestclient.DeleteActionImpl{ActionImpl: ktestclient.ActionImpl{Verb: "delete", Resource: "groups"}, Name: "mygroup"}, }, }, { name: "namespaced bindings", group: "mygroup", objects: []runtime.Object{ &authorizationapi.RoleBinding{ ObjectMeta: kapi.ObjectMeta{Name: "binding-no-subjects", Namespace: "ns1"}, RoleRef: kapi.ObjectReference{Name: "role"}, Subjects: []kapi.ObjectReference{}, }, &authorizationapi.RoleBinding{ ObjectMeta: kapi.ObjectMeta{Name: "binding-one-subject", Namespace: "ns2"}, RoleRef: kapi.ObjectReference{Name: "role"}, Subjects: []kapi.ObjectReference{{Name: "mygroup", Kind: "Group"}}, }, &authorizationapi.RoleBinding{ ObjectMeta: kapi.ObjectMeta{Name: "binding-mismatched-subject", Namespace: "ns3"}, RoleRef: kapi.ObjectReference{Name: "role"}, Subjects: []kapi.ObjectReference{{Name: "mygroup"}, {Name: "mygroup", Kind: "User"}, {Name: "mygroup", Kind: "Other"}}, }, }, expected: []interface{}{ ktestclient.UpdateActionImpl{ActionImpl: ktestclient.ActionImpl{Verb: "update", Resource: "rolebindings", Namespace: "ns2"}, Object: &authorizationapi.RoleBinding{ ObjectMeta: kapi.ObjectMeta{Name: "binding-one-subject", Namespace: "ns2"}, RoleRef: kapi.ObjectReference{Name: "role"}, Subjects: []kapi.ObjectReference{}, }}, ktestclient.DeleteActionImpl{ActionImpl: ktestclient.ActionImpl{Verb: "delete", Resource: "groups"}, Name: "mygroup"}, }, }, { name: "sccs", group: "mygroup", objects: []runtime.Object{ &kapi.SecurityContextConstraints{ ObjectMeta: kapi.ObjectMeta{Name: "scc-no-subjects"}, Groups: []string{}, }, &kapi.SecurityContextConstraints{ ObjectMeta: kapi.ObjectMeta{Name: "scc-one-subject"}, Groups: []string{"mygroup"}, }, &kapi.SecurityContextConstraints{ ObjectMeta: kapi.ObjectMeta{Name: "scc-mismatched-subjects"}, Users: []string{"mygroup"}, Groups: []string{"mygroup2"}, }, }, expected: []interface{}{ ktestclient.UpdateActionImpl{ActionImpl: ktestclient.ActionImpl{Verb: "update", Resource: "securitycontextconstraints"}, Object: &kapi.SecurityContextConstraints{ ObjectMeta: kapi.ObjectMeta{Name: "scc-one-subject"}, Groups: []string{}, }}, ktestclient.DeleteActionImpl{ActionImpl: ktestclient.ActionImpl{Verb: "delete", Resource: "groups"}, Name: "mygroup"}, }, }, } for _, test := range tests { tc := testclient.NewSimpleFake(test.objects...) ktc := ktestclient.NewSimpleFake(test.objects...) actual := []interface{}{} reactor := func(action ktestclient.Action) (handled bool, ret runtime.Object, err error) { actual = append(actual, action) return false, nil, nil } tc.PrependReactor("update", "*", reactor) tc.PrependReactor("delete", "*", reactor) ktc.PrependReactor("update", "*", reactor) ktc.PrependReactor("delete", "*", reactor) reaper := NewGroupReaper(tc, tc, tc, ktc) err := reaper.Stop("", test.group, 0, nil) if err != nil { t.Errorf("%s: unexpected error: %v", test.name, err) } if !reflect.DeepEqual(test.expected, actual) { for i, x := range test.expected { t.Logf("Expected %d: %s", i, spew.Sprint(x)) } for i, x := range actual { t.Logf("Actual %d: %s", i, spew.Sprint(x)) } t.Errorf("%s: unexpected actions", test.name) } } }
func TestUserReaper(t *testing.T) { tests := []struct { name string user string objects []runtime.Object expected []interface{} }{ { name: "no objects", user: "******", objects: []runtime.Object{}, expected: []interface{}{ ktestclient.DeleteActionImpl{ktestclient.ActionImpl{Verb: "delete", Resource: "users"}, "bob"}, }, }, { name: "cluster bindings", user: "******", objects: []runtime.Object{ &authorizationapi.ClusterRoleBinding{ ObjectMeta: kapi.ObjectMeta{Name: "binding-no-subjects"}, RoleRef: kapi.ObjectReference{Name: "role"}, Subjects: []kapi.ObjectReference{}, }, &authorizationapi.ClusterRoleBinding{ ObjectMeta: kapi.ObjectMeta{Name: "binding-one-subject"}, RoleRef: kapi.ObjectReference{Name: "role"}, Subjects: []kapi.ObjectReference{{Name: "bob", Kind: "User"}}, }, &authorizationapi.ClusterRoleBinding{ ObjectMeta: kapi.ObjectMeta{Name: "binding-mismatched-subject"}, RoleRef: kapi.ObjectReference{Name: "role"}, Subjects: []kapi.ObjectReference{{Name: "bob"}, {Name: "bob", Kind: "Group"}, {Name: "bob", Kind: "Other"}}, }, }, expected: []interface{}{ ktestclient.UpdateActionImpl{ktestclient.ActionImpl{Verb: "update", Resource: "clusterrolebindings"}, &authorizationapi.ClusterRoleBinding{ ObjectMeta: kapi.ObjectMeta{Name: "binding-one-subject"}, RoleRef: kapi.ObjectReference{Name: "role"}, Subjects: []kapi.ObjectReference{}, }}, ktestclient.DeleteActionImpl{ktestclient.ActionImpl{Verb: "delete", Resource: "users"}, "bob"}, }, }, { name: "namespaced bindings", user: "******", objects: []runtime.Object{ &authorizationapi.RoleBinding{ ObjectMeta: kapi.ObjectMeta{Name: "binding-no-subjects", Namespace: "ns1"}, RoleRef: kapi.ObjectReference{Name: "role"}, Subjects: []kapi.ObjectReference{}, }, &authorizationapi.RoleBinding{ ObjectMeta: kapi.ObjectMeta{Name: "binding-one-subject", Namespace: "ns2"}, RoleRef: kapi.ObjectReference{Name: "role"}, Subjects: []kapi.ObjectReference{{Name: "bob", Kind: "User"}}, }, &authorizationapi.RoleBinding{ ObjectMeta: kapi.ObjectMeta{Name: "binding-mismatched-subject", Namespace: "ns3"}, RoleRef: kapi.ObjectReference{Name: "role"}, Subjects: []kapi.ObjectReference{{Name: "bob"}, {Name: "bob", Kind: "Group"}, {Name: "bob", Kind: "Other"}}, }, }, expected: []interface{}{ ktestclient.UpdateActionImpl{ktestclient.ActionImpl{Verb: "update", Resource: "rolebindings", Namespace: "ns2"}, &authorizationapi.RoleBinding{ ObjectMeta: kapi.ObjectMeta{Name: "binding-one-subject", Namespace: "ns2"}, RoleRef: kapi.ObjectReference{Name: "role"}, Subjects: []kapi.ObjectReference{}, }}, ktestclient.DeleteActionImpl{ktestclient.ActionImpl{Verb: "delete", Resource: "users"}, "bob"}, }, }, { name: "sccs", user: "******", objects: []runtime.Object{ &kapi.SecurityContextConstraints{ ObjectMeta: kapi.ObjectMeta{Name: "scc-no-subjects"}, Users: []string{}, }, &kapi.SecurityContextConstraints{ ObjectMeta: kapi.ObjectMeta{Name: "scc-one-subject"}, Users: []string{"bob"}, }, &kapi.SecurityContextConstraints{ ObjectMeta: kapi.ObjectMeta{Name: "scc-mismatched-subjects"}, Users: []string{"bob2"}, Groups: []string{"bob"}, }, }, expected: []interface{}{ ktestclient.UpdateActionImpl{ktestclient.ActionImpl{Verb: "update", Resource: "securitycontextconstraints"}, &kapi.SecurityContextConstraints{ ObjectMeta: kapi.ObjectMeta{Name: "scc-one-subject"}, Users: []string{}, }}, ktestclient.DeleteActionImpl{ktestclient.ActionImpl{Verb: "delete", Resource: "users"}, "bob"}, }, }, { name: "identities", user: "******", objects: []runtime.Object{ &authenticationapi.Identity{ ObjectMeta: kapi.ObjectMeta{Name: "identity-no-user"}, User: kapi.ObjectReference{}, }, &authenticationapi.Identity{ ObjectMeta: kapi.ObjectMeta{Name: "identity-matching-user"}, User: kapi.ObjectReference{Name: "bob"}, }, &authenticationapi.Identity{ ObjectMeta: kapi.ObjectMeta{Name: "identity-different-uid"}, User: kapi.ObjectReference{Name: "bob", UID: "123"}, }, &authenticationapi.Identity{ ObjectMeta: kapi.ObjectMeta{Name: "identity-different-user"}, User: kapi.ObjectReference{Name: "bob2"}, }, }, expected: []interface{}{ // Make sure identities are not messed with, only the user is removed ktestclient.DeleteActionImpl{ktestclient.ActionImpl{Verb: "delete", Resource: "users"}, "bob"}, }, }, { name: "groups", user: "******", objects: []runtime.Object{ &authenticationapi.Group{ ObjectMeta: kapi.ObjectMeta{Name: "group-no-users"}, Users: []string{}, }, &authenticationapi.Group{ ObjectMeta: kapi.ObjectMeta{Name: "group-one-user"}, Users: []string{"bob"}, }, &authenticationapi.Group{ ObjectMeta: kapi.ObjectMeta{Name: "group-multiple-users"}, Users: []string{"bob2", "bob", "steve"}, }, &authenticationapi.Group{ ObjectMeta: kapi.ObjectMeta{Name: "group-mismatched-users"}, Users: []string{"bob2", "steve"}, }, }, expected: []interface{}{ ktestclient.UpdateActionImpl{ktestclient.ActionImpl{Verb: "update", Resource: "groups"}, &authenticationapi.Group{ ObjectMeta: kapi.ObjectMeta{Name: "group-one-user"}, Users: []string{}, }}, ktestclient.UpdateActionImpl{ktestclient.ActionImpl{Verb: "update", Resource: "groups"}, &authenticationapi.Group{ ObjectMeta: kapi.ObjectMeta{Name: "group-multiple-users"}, Users: []string{"bob2", "steve"}, }}, ktestclient.DeleteActionImpl{ktestclient.ActionImpl{Verb: "delete", Resource: "users"}, "bob"}, }, }, } for _, test := range tests { tc := testclient.NewSimpleFake(test.objects...) ktc := ktestclient.NewSimpleFake(test.objects...) actual := []interface{}{} reactor := func(action ktestclient.Action) (handled bool, ret runtime.Object, err error) { actual = append(actual, action) return false, nil, nil } tc.PrependReactor("update", "*", reactor) tc.PrependReactor("delete", "*", reactor) ktc.PrependReactor("update", "*", reactor) ktc.PrependReactor("delete", "*", reactor) reaper := NewUserReaper(tc, tc, tc, tc, ktc) _, err := reaper.Stop("", test.user, 0, nil) if err != nil { t.Errorf("%s: unexpected error: %v", test.name, err) } if !reflect.DeepEqual(test.expected, actual) { for i, x := range test.expected { t.Logf("Expected %d: %s", i, spew.Sprint(x)) } for i, x := range actual { t.Logf("Actual %d: %s", i, spew.Sprint(x)) } t.Errorf("%s: unexpected actions", test.name) } } }
// TestBlockHeader tests the BlockHeader API. func TestBlockHeader(t *testing.T) { nonce64, err := wire.RandomUint64() if err != nil { t.Errorf("RandomUint64: Error generating nonce: %v", err) } nonce := uint32(nonce64) hash := mainNetGenesisHash merkleHash := mainNetGenesisMerkleRoot votebits := uint16(0x0000) bits := uint32(0x1d00ffff) finalState := [6]byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00} voters := uint16(0x0000) freshstake := uint8(0x00) revocations := uint8(0x00) poolsize := uint32(0) sbits := int64(0x0000000000000000) blockHeight := uint32(0) blockSize := uint32(0) extraData := [36]byte{} bh := wire.NewBlockHeader( 1, // verision &hash, &merkleHash, &merkleHash, // stakeRoot votebits, finalState, voters, freshstake, revocations, poolsize, bits, sbits, blockHeight, blockSize, nonce, extraData, ) // Ensure we get the same data back out. if !bh.PrevBlock.IsEqual(&hash) { t.Errorf("NewBlockHeader: wrong prev hash - got %v, want %v", spew.Sprint(bh.PrevBlock), spew.Sprint(hash)) } if !bh.MerkleRoot.IsEqual(&merkleHash) { t.Errorf("NewBlockHeader: wrong merkle root - got %v, want %v", spew.Sprint(bh.MerkleRoot), spew.Sprint(merkleHash)) } if !bh.StakeRoot.IsEqual(&merkleHash) { t.Errorf("NewBlockHeader: wrong merkle root - got %v, want %v", spew.Sprint(bh.MerkleRoot), spew.Sprint(merkleHash)) } if bh.VoteBits != votebits { t.Errorf("NewBlockHeader: wrong bits - got %v, want %v", bh.Bits, bits) } if bh.FinalState != finalState { t.Errorf("NewBlockHeader: wrong bits - got %v, want %v", bh.Bits, bits) } if bh.Voters != voters { t.Errorf("NewBlockHeader: wrong bits - got %v, want %v", bh.Bits, bits) } if bh.FreshStake != freshstake { t.Errorf("NewBlockHeader: wrong bits - got %v, want %v", bh.Bits, bits) } if bh.Revocations != revocations { t.Errorf("NewBlockHeader: wrong bits - got %v, want %v", bh.Bits, bits) } if bh.PoolSize != poolsize { t.Errorf("NewBlockHeader: wrong PoolSize - got %v, want %v", bh.PoolSize, poolsize) } if bh.Bits != bits { t.Errorf("NewBlockHeader: wrong bits - got %v, want %v", bh.Bits, bits) } if bh.SBits != sbits { t.Errorf("NewBlockHeader: wrong bits - got %v, want %v", bh.Bits, bits) } if bh.Nonce != nonce { t.Errorf("NewBlockHeader: wrong nonce - got %v, want %v", bh.Nonce, nonce) } }
// TestSpew executes all of the tests described by spewTests. func TestSpew(t *testing.T) { initSpewTests() t.Logf("Running %d tests", len(spewTests)) for i, test := range spewTests { buf := new(bytes.Buffer) switch test.f { case fCSFdump: test.cs.Fdump(buf, test.in) case fCSFprint: test.cs.Fprint(buf, test.in) case fCSFprintf: test.cs.Fprintf(buf, test.format, test.in) case fCSFprintln: test.cs.Fprintln(buf, test.in) case fCSPrint: b, err := redirStdout(func() { test.cs.Print(test.in) }) if err != nil { t.Errorf("%v #%d %v", test.f, i, err) continue } buf.Write(b) case fCSPrintln: b, err := redirStdout(func() { test.cs.Println(test.in) }) if err != nil { t.Errorf("%v #%d %v", test.f, i, err) continue } buf.Write(b) case fCSSdump: str := test.cs.Sdump(test.in) buf.WriteString(str) case fCSSprint: str := test.cs.Sprint(test.in) buf.WriteString(str) case fCSSprintf: str := test.cs.Sprintf(test.format, test.in) buf.WriteString(str) case fCSSprintln: str := test.cs.Sprintln(test.in) buf.WriteString(str) case fCSErrorf: err := test.cs.Errorf(test.format, test.in) buf.WriteString(err.Error()) case fCSNewFormatter: fmt.Fprintf(buf, test.format, test.cs.NewFormatter(test.in)) case fErrorf: err := spew.Errorf(test.format, test.in) buf.WriteString(err.Error()) case fFprint: spew.Fprint(buf, test.in) case fFprintln: spew.Fprintln(buf, test.in) case fPrint: b, err := redirStdout(func() { spew.Print(test.in) }) if err != nil { t.Errorf("%v #%d %v", test.f, i, err) continue } buf.Write(b) case fPrintln: b, err := redirStdout(func() { spew.Println(test.in) }) if err != nil { t.Errorf("%v #%d %v", test.f, i, err) continue } buf.Write(b) case fSdump: str := spew.Sdump(test.in) buf.WriteString(str) case fSprint: str := spew.Sprint(test.in) buf.WriteString(str) case fSprintf: str := spew.Sprintf(test.format, test.in) buf.WriteString(str) case fSprintln: str := spew.Sprintln(test.in) buf.WriteString(str) default: t.Errorf("%v #%d unrecognized function", test.f, i) continue } s := buf.String() if test.want != s { t.Errorf("ConfigState #%d\n got: %s want: %s", i, s, test.want) continue } } }
// TestTxSha tests the ability to generate the wtxid, and txid of a transaction // with witness inputs accurately. func TestWTxSha(t *testing.T) { hashStrTxid := "0f167d1385a84d1518cfee208b653fc9163b605ccf1b75347e2850b3e2eb19f3" wantHashTxid, err := chainhash.NewHashFromStr(hashStrTxid) if err != nil { t.Errorf("NewShaHashFromStr: %v", err) return } hashStrWTxid := "0858eab78e77b6b033da30f46699996396cf48fcf625a783c85a51403e175e74" wantHashWTxid, err := chainhash.NewHashFromStr(hashStrWTxid) if err != nil { t.Errorf("NewShaHashFromStr: %v", err) return } // From block 23157 in a past version of segnet. msgTx := NewMsgTx() txIn := TxIn{ PreviousOutPoint: OutPoint{ Hash: chainhash.Hash{ 0xa5, 0x33, 0x52, 0xd5, 0x13, 0x57, 0x66, 0xf0, 0x30, 0x76, 0x59, 0x74, 0x18, 0x26, 0x3d, 0xa2, 0xd9, 0xc9, 0x58, 0x31, 0x59, 0x68, 0xfe, 0xa8, 0x23, 0x52, 0x94, 0x67, 0x48, 0x1f, 0xf9, 0xcd, }, Index: 19, }, Witness: [][]byte{ []byte{ // 70-byte signature 0x30, 0x43, 0x02, 0x1f, 0x4d, 0x23, 0x81, 0xdc, 0x97, 0xf1, 0x82, 0xab, 0xd8, 0x18, 0x5f, 0x51, 0x75, 0x30, 0x18, 0x52, 0x32, 0x12, 0xf5, 0xdd, 0xc0, 0x7c, 0xc4, 0xe6, 0x3a, 0x8d, 0xc0, 0x36, 0x58, 0xda, 0x19, 0x02, 0x20, 0x60, 0x8b, 0x5c, 0x4d, 0x92, 0xb8, 0x6b, 0x6d, 0xe7, 0xd7, 0x8e, 0xf2, 0x3a, 0x2f, 0xa7, 0x35, 0xbc, 0xb5, 0x9b, 0x91, 0x4a, 0x48, 0xb0, 0xe1, 0x87, 0xc5, 0xe7, 0x56, 0x9a, 0x18, 0x19, 0x70, 0x01, }, []byte{ // 33-byte serialize pub key 0x03, 0x07, 0xea, 0xd0, 0x84, 0x80, 0x7e, 0xb7, 0x63, 0x46, 0xdf, 0x69, 0x77, 0x00, 0x0c, 0x89, 0x39, 0x2f, 0x45, 0xc7, 0x64, 0x25, 0xb2, 0x61, 0x81, 0xf5, 0x21, 0xd7, 0xf3, 0x70, 0x06, 0x6a, 0x8f, }, }, Sequence: 0xffffffff, } txOut := TxOut{ Value: 395019, PkScript: []byte{ 0x00, // Version 0 witness program 0x14, // OP_DATA_20 0x9d, 0xda, 0xc6, 0xf3, 0x9d, 0x51, 0xe0, 0x39, 0x8e, 0x53, 0x2a, 0x22, 0xc4, 0x1b, 0xa1, 0x89, 0x40, 0x6a, 0x85, 0x23, // 20-byte pub key hash }, } msgTx.AddTxIn(&txIn) msgTx.AddTxOut(&txOut) msgTx.LockTime = 0 // Ensure the correct txid, and wtxid is produced as expected. txid := msgTx.TxHash() if !txid.IsEqual(wantHashTxid) { t.Errorf("TxSha: wrong hash - got %v, want %v", spew.Sprint(txid), spew.Sprint(wantHashTxid)) } wtxid := msgTx.WitnessHash() if !wtxid.IsEqual(wantHashWTxid) { t.Errorf("WTxSha: wrong hash - got %v, want %v", spew.Sprint(wtxid), spew.Sprint(wantHashWTxid)) } }
func spewInspect(a ...interface{}) string { value := a[0].(reflect.Value) return spew.Sprint(value.Interface()) }