// TxInfo returns a slice of maps that may be marshaled as a JSON array // of JSON objects for a listtransactions RPC reply. func (tx *SendTx) TxInfo(account string, curheight int32, net btcwire.BitcoinNet) []map[string]interface{} { reply := make([]map[string]interface{}, len(tx.Receivers)) var confirmations int32 if tx.BlockHeight != -1 { confirmations = curheight - tx.BlockHeight + 1 } // error is ignored since the length will always be correct. txID, _ := btcwire.NewShaHash(tx.TxID[:]) txIDStr := txID.String() // error is ignored since the length will always be correct. blockHash, _ := btcwire.NewShaHash(tx.BlockHash[:]) blockHashStr := blockHash.String() for i, pair := range tx.Receivers { address := "Unknown" addr, err := btcutil.NewAddressPubKeyHash(pair.PubkeyHash, net) if err == nil { address = addr.String() } info := map[string]interface{}{ "account": account, "address": address, "category": "send", "amount": float64(-pair.Amount) / float64(btcutil.SatoshiPerBitcoin), "fee": float64(tx.Fee) / float64(btcutil.SatoshiPerBitcoin), "confirmations": confirmations, "txid": txIDStr, "time": tx.Time, "timereceived": tx.Time, } if tx.BlockHeight != -1 { info["blockhash"] = blockHashStr info["blockindex"] = tx.BlockIndex info["blocktime"] = tx.BlockTime } reply[i] = info } return reply }
// TestShaHash tests the ShaHash API. func TestShaHash(t *testing.T) { // Hash of block 234439. blockHashStr := "14a0810ac680a3eb3f82edc878cea25ec41d6b790744e5daeef" blockHash, err := btcwire.NewShaHashFromStr(blockHashStr) if err != nil { t.Errorf("NewShaHashFromStr: %v", err) } // Hash of block 234440 as byte slice. buf := []byte{ 0x79, 0xa6, 0x1a, 0xdb, 0xc6, 0xe5, 0xa2, 0xe1, 0x39, 0xd2, 0x71, 0x3a, 0x54, 0x6e, 0xc7, 0xc8, 0x75, 0x63, 0x2e, 0x75, 0xf1, 0xdf, 0x9c, 0x3f, 0xa6, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, } hash, err := btcwire.NewShaHash(buf) if err != nil { t.Errorf("NewShaHash: unexpected error %v", err) } // Ensure proper size. if len(hash) != btcwire.HashSize { t.Errorf("NewShaHash: hash length mismatch - got: %v, want: %v", len(hash), btcwire.HashSize) } // Ensure contents match. if !bytes.Equal(hash[:], buf) { t.Errorf("NewShaHash: hash contents mismatch - got: %v, want: %v", hash[:], buf) } // Ensure contents of hash of block 234440 don't match 234439. if hash.IsEqual(blockHash) { t.Errorf("IsEqual: hash contents should not match - got: %v, want: %v", hash, blockHash) } // Set hash from byte slice and ensure contents match. err = hash.SetBytes(blockHash.Bytes()) if err != nil { t.Errorf("SetBytes: %v", err) } if !hash.IsEqual(blockHash) { t.Errorf("IsEqual: hash contents mismatch - got: %v, want: %v", hash, blockHash) } // Invalid size for SetBytes. err = hash.SetBytes([]byte{0x00}) if err == nil { t.Errorf("SetBytes: failed to received expected err - got: nil") } }
// hashMerkleBranches takes two hashes, treated as the left and right tree // nodes, and returns the hash of their concatenation. This is a helper // function used to during generatation of a merkle tree. func hashMerkleBranches(left *btcwire.ShaHash, right *btcwire.ShaHash) *btcwire.ShaHash { // Concatenate the left and right nodes. var sha [btcwire.HashSize * 2]byte copy(sha[:btcwire.HashSize], left.Bytes()) copy(sha[btcwire.HashSize:], right.Bytes()) // Create a new sha hash from the double sha 256. Ignore the error // here since SetBytes can't fail here due to the fact DoubleSha256 // always returns a []byte of the right size regardless of input. newSha, _ := btcwire.NewShaHash(btcwire.DoubleSha256(sha[:])) return newSha }
func NewCoin(index int64, value btcutil.Amount, numConfs int64) coinset.Coin { h := fastsha256.New() h.Write([]byte(fmt.Sprintf("%d", index))) hash, _ := btcwire.NewShaHash(h.Sum(nil)) c := &TestCoin{ TxHash: hash, TxIndex: 0, TxValue: value, TxNumConfs: numConfs, } return coinset.Coin(c) }
// BenchmarkMruInventoryList performs basic benchmarks on the most recently // used inventory handling. func BenchmarkMruInventoryList(b *testing.B) { // Create a bunch of fake inventory vectors to use in benchmarking // the mru inventory code. b.StopTimer() numInvVects := 100000 invVects := make([]*btcwire.InvVect, 0, numInvVects) for i := 0; i < numInvVects; i++ { hashBytes := make([]byte, btcwire.HashSize) rand.Read(hashBytes) hash, _ := btcwire.NewShaHash(hashBytes) iv := btcwire.NewInvVect(btcwire.InvTypeBlock, hash) invVects = append(invVects, iv) } b.StartTimer() // Benchmark the add plus evicition code. limit := 20000 mruInvMap := NewMruInventoryMap(uint(limit)) for i := 0; i < b.N; i++ { mruInvMap.Add(invVects[i%numInvVects]) } }
// TestMerkleBlock tests the MsgMerkleBlock API. func TestMerkleBlock(t *testing.T) { pver := btcwire.ProtocolVersion // Block 1 header. prevHash := &blockOne.Header.PrevBlock merkleHash := &blockOne.Header.MerkleRoot bits := blockOne.Header.Bits nonce := blockOne.Header.Nonce bh := btcwire.NewBlockHeader(prevHash, merkleHash, bits, nonce) // Ensure the command is expected value. wantCmd := "merkleblock" msg := btcwire.NewMsgMerkleBlock(bh) if cmd := msg.Command(); cmd != wantCmd { t.Errorf("NewMsgBlock: 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(1000000) 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) } // Load maxTxPerBlock hashes data := make([]byte, 32) for i := 0; i < btcwire.MaxTxPerBlock; i++ { rand.Read(data) hash, err := btcwire.NewShaHash(data) if err != nil { t.Errorf("NewShaHash failed: %v\n", err) return } if err = msg.AddTxHash(hash); err != nil { t.Errorf("AddTxHash failed: %v\n", err) return } } // Add one more Tx to test failure. rand.Read(data) hash, err := btcwire.NewShaHash(data) if err != nil { t.Errorf("NewShaHash failed: %v\n", err) return } if err = msg.AddTxHash(hash); err == nil { t.Errorf("AddTxHash succeeded when it should have failed") return } // Test encode with latest protocol version. var buf bytes.Buffer err = msg.BtcEncode(&buf, pver) if err != nil { t.Errorf("encode of MsgMerkleBlock failed %v err <%v>", msg, err) } // Test decode with latest protocol version. readmsg := btcwire.MsgMerkleBlock{} err = readmsg.BtcDecode(&buf, pver) if err != nil { t.Errorf("decode of MsgMerkleBlock failed [%v] err <%v>", buf, err) } // Force extra hash to test maxTxPerBlock. msg.Hashes = append(msg.Hashes, hash) err = msg.BtcEncode(&buf, pver) if err == nil { t.Errorf("encode of MsgMerkleBlock succeeded with too many " + "tx hashes when it should have failed") return } // Force too many flag bytes to test maxFlagsPerMerkleBlock. // Reset the number of hashes back to a valid value. msg.Hashes = msg.Hashes[len(msg.Hashes)-1:] msg.Flags = make([]byte, btcwire.MaxFlagsPerMerkleBlock+1) err = msg.BtcEncode(&buf, pver) if err == nil { t.Errorf("encode of MsgMerkleBlock succeeded with too many " + "flag bytes when it should have failed") return } }