Пример #1
0
// NtfnTxMined handles btcd notifications resulting from newly
// mined transactions that originated from this wallet.
func NtfnTxMined(n btcjson.Cmd, marshaled []byte) {
	tmn, ok := n.(*btcws.TxMinedNtfn)
	if !ok {
		log.Errorf("%v handler: unexpected type", n.Method())
		return
	}

	txid, err := btcwire.NewShaHashFromStr(tmn.TxID)
	if err != nil {
		log.Errorf("%v handler: invalid hash string", n.Method())
		return
	}
	blockhash, err := btcwire.NewShaHashFromStr(tmn.BlockHash)
	if err != nil {
		log.Errorf("%v handler: invalid block hash string", n.Method())
		return
	}

	err = accountstore.RecordMinedTx(txid, blockhash,
		tmn.BlockHeight, tmn.Index, tmn.BlockTime)
	if err != nil {
		log.Errorf("%v handler: %v", n.Method(), err)
		return
	}

	// Remove mined transaction from pool.
	UnminedTxs.Lock()
	delete(UnminedTxs.m, TXID(*txid))
	UnminedTxs.Unlock()
}
Пример #2
0
func TestFilterInsertUpdateNone(t *testing.T) {
	f := bloom.NewFilter(10, 0, 0.000001, btcwire.BloomUpdateNone)

	// Add the generation pubkey
	inputStr := "04eaafc2314def4ca98ac970241bcab022b9c1e1f4ea423a20f134c" +
		"876f2c01ec0f0dd5b2e86e7168cefe0d81113c3807420ce13ad1357231a" +
		"2252247d97a46a91"
	inputBytes, err := hex.DecodeString(inputStr)
	if err != nil {
		t.Errorf("TestFilterInsertUpdateNone DecodeString failed: %v", err)
		return
	}
	f.Add(inputBytes)

	// Add the output address for the 4th transaction
	inputStr = "b6efd80d99179f4f4ff6f4dd0a007d018c385d21"
	inputBytes, err = hex.DecodeString(inputStr)
	if err != nil {
		t.Errorf("TestFilterInsertUpdateNone DecodeString failed: %v", err)
		return
	}
	f.Add(inputBytes)

	inputStr = "147caa76786596590baa4e98f5d9f48b86c7765e489f7a6ff3360fe5c674360b"
	sha, err := btcwire.NewShaHashFromStr(inputStr)
	if err != nil {
		t.Errorf("TestFilterInsertUpdateNone NewShaHashFromStr failed: %v", err)
		return
	}
	outpoint := btcwire.NewOutPoint(sha, 0)

	if f.MatchesOutPoint(outpoint) {
		t.Errorf("TestFilterInsertUpdateNone matched outpoint %s", inputStr)
		return
	}

	inputStr = "02981fa052f0481dbc5868f4fc2166035a10f27a03cfd2de67326471df5bc041"
	sha, err = btcwire.NewShaHashFromStr(inputStr)
	if err != nil {
		t.Errorf("TestFilterInsertUpdateNone NewShaHashFromStr failed: %v", err)
		return
	}
	outpoint = btcwire.NewOutPoint(sha, 0)

	if f.MatchesOutPoint(outpoint) {
		t.Errorf("TestFilterInsertUpdateNone matched outpoint %s", inputStr)
		return
	}
}
Пример #3
0
// This example demonstrates how to create a new bloom filter, add a transaction
// hash to it, and check if the filter matches the transaction.
func ExampleNewFilter() {
	rand.Seed(time.Now().UnixNano())
	tweak := rand.Uint32()

	// Create a new bloom filter intended to hold 10 elements with a 0.01%
	// false positive rate and does not include any automatic update
	// functionality when transactions are matched.
	filter := bloom.NewFilter(10, tweak, 0.0001, btcwire.BloomUpdateNone)

	// Create a transaction hash and add it to the filter.  This particular
	// trasaction is the first transaction in block 310,000 of the main
	// bitcoin block chain.
	txHashStr := "fd611c56ca0d378cdcd16244b45c2ba9588da3adac367c4ef43e808b280b8a45"
	txHash, err := btcwire.NewShaHashFromStr(txHashStr)
	if err != nil {
		fmt.Println(err)
		return
	}
	filter.AddShaHash(txHash)

	// Show that the filter matches.
	matches := filter.Matches(txHash.Bytes())
	fmt.Println("Filter Matches?:", matches)

	// Output:
	// Filter Matches?: true
}
Пример #4
0
// parseTxAcceptedNtfnParams parses out the transaction hash and total amount
// from the parameters of a txaccepted notification.
func parseTxAcceptedNtfnParams(params []json.RawMessage) (*btcwire.ShaHash,
	btcutil.Amount, error) {

	if len(params) != 2 {
		return nil, 0, wrongNumParams(len(params))
	}

	// Unmarshal first parameter as a string.
	var txShaStr string
	err := json.Unmarshal(params[0], &txShaStr)
	if err != nil {
		return nil, 0, err
	}

	// Unmarshal second parameter as an integer.
	var amt int64
	err = json.Unmarshal(params[1], &amt)
	if err != nil {
		return nil, 0, err
	}

	// Decode string encoding of transaction sha.
	txSha, err := btcwire.NewShaHashFromStr(txShaStr)
	if err != nil {
		return nil, 0, err
	}

	return txSha, btcutil.Amount(amt), nil
}
Пример #5
0
// parseRescanProgressParams parses out the height of the last rescanned block
// from the parameters of rescanfinished and rescanprogress notifications.
func parseRescanProgressParams(params []json.RawMessage) (*btcwire.ShaHash, int32, time.Time, error) {
	if len(params) != 3 {
		return nil, 0, time.Time{}, wrongNumParams(len(params))
	}

	// Unmarshal first parameter as an string.
	var hashStr string
	err := json.Unmarshal(params[0], &hashStr)
	if err != nil {
		return nil, 0, time.Time{}, err
	}

	// Unmarshal second parameter as an integer.
	var height int32
	err = json.Unmarshal(params[1], &height)
	if err != nil {
		return nil, 0, time.Time{}, err
	}

	// Unmarshal third parameter as an integer.
	var blkTime int64
	err = json.Unmarshal(params[2], &blkTime)
	if err != nil {
		return nil, 0, time.Time{}, err
	}

	// Decode string encoding of block hash.
	hash, err := btcwire.NewShaHashFromStr(hashStr)
	if err != nil {
		return nil, 0, time.Time{}, err
	}

	return hash, height, time.Unix(blkTime, 0), nil
}
Пример #6
0
// parseChainNtfnParams parses out the block hash and height from the parameters
// of blockconnected and blockdisconnected notifications.
func parseChainNtfnParams(params []json.RawMessage) (*btcwire.ShaHash,
	int32, error) {

	if len(params) != 2 {
		return nil, 0, wrongNumParams(len(params))
	}

	// Unmarshal first parameter as a string.
	var blockShaStr string
	err := json.Unmarshal(params[0], &blockShaStr)
	if err != nil {
		return nil, 0, err
	}

	// Unmarshal second parameter as an integer.
	var blockHeight int32
	err = json.Unmarshal(params[1], &blockHeight)
	if err != nil {
		return nil, 0, err
	}

	// Create ShaHash from block sha string.
	blockSha, err := btcwire.NewShaHashFromStr(blockShaStr)
	if err != nil {
		return nil, 0, err
	}

	return blockSha, blockHeight, nil
}
Пример #7
0
// Receive waits for the response promised by the future and returns the hashes
// of all transactions in the memory pool.
func (r FutureGetRawMempoolResult) Receive() ([]*btcwire.ShaHash, error) {
	res, err := receiveFuture(r)
	if err != nil {
		return nil, err
	}

	// Unmarshal the result as an array of strings.
	var txHashStrs []string
	err = json.Unmarshal(res, &txHashStrs)
	if err != nil {
		return nil, err
	}

	// Create a slice of ShaHash arrays from the string slice.
	txHashes := make([]*btcwire.ShaHash, 0, len(txHashStrs))
	for _, hashStr := range txHashStrs {
		txHash, err := btcwire.NewShaHashFromStr(hashStr)
		if err != nil {
			return nil, err
		}
		txHashes = append(txHashes, txHash)
	}

	return txHashes, nil
}
Пример #8
0
// parseNotifySpentCmd parses a NotifySpentCmd into a concrete type
// satisifying the btcjson.Cmd interface.  This is used when registering
// the custom command with the btcjson parser.
func parseNotifySpentCmd(r *btcjson.RawCmd) (btcjson.Cmd, error) {
	if len(r.Params) != 2 {
		return nil, btcjson.ErrWrongNumberOfParams
	}

	hashStr, ok := r.Params[0].(string)
	if !ok {
		return nil, errors.New("first parameter must be a string")
	}
	hash, err := btcwire.NewShaHashFromStr(hashStr)
	if err != nil {
		return nil, errors.New("first parameter is not a valid " +
			"hash string")
	}
	idx, ok := r.Params[1].(float64)
	if !ok {
		return nil, errors.New("second parameter is not a number")
	}
	if idx < 0 {
		return nil, errors.New("second parameter cannot be negative")
	}

	cmd := NewNotifySpentCmd(r.Id, btcwire.NewOutPoint(hash, uint32(idx)))
	return cmd, nil
}
Пример #9
0
func handleMain(w http.ResponseWriter, r *http.Request) {
	sha, err := client.GetBestBlockHash()
	if err != nil {
		printErrorPage(w, "Unable to get best blockhash")
		return
	}

	blocks := make([]*btcjson.BlockResult, numMainPageBlocks)
	blocks[0], err = client.GetBlockVerbose(sha, true)
	if err != nil {
		printErrorPage(w, "Error retrieving block")
		return
	}

	for j := 1; j < numMainPageBlocks && blocks[j-1].PreviousHash != ""; j++ {
		prevsha, _ := btcwire.NewShaHashFromStr(blocks[j-1].PreviousHash)
		blocks[j], err = client.GetBlockVerbose(prevsha, true)
		if err != nil {
			printErrorPage(w, "Error retrieving block")
			return
		}
	}

	printHTMLHeader(w, "Welcome")
	printMainBlock(w, blocks)
	printHTMLFooter(w)
}
Пример #10
0
// GetCurBlock returns the blockchain height and SHA hash of the most
// recently seen block.  If no blocks have been seen since btcd has
// connected, btcd is queried for the current block height and hash.
func GetCurBlock() (bs wallet.BlockStamp, err error) {
	curBlock.RLock()
	bs = curBlock.BlockStamp
	curBlock.RUnlock()
	if bs.Height != int32(btcutil.BlockHeightUnknown) {
		return bs, nil
	}

	bb, _ := GetBestBlock(CurrentServerConn())
	if bb == nil {
		return wallet.BlockStamp{
			Height: int32(btcutil.BlockHeightUnknown),
		}, errors.New("current block unavailable")
	}

	hash, err := btcwire.NewShaHashFromStr(bb.Hash)
	if err != nil {
		return wallet.BlockStamp{
			Height: int32(btcutil.BlockHeightUnknown),
		}, err
	}

	curBlock.Lock()
	if bb.Height > curBlock.BlockStamp.Height {
		bs = wallet.BlockStamp{
			Height: bb.Height,
			Hash:   *hash,
		}
		curBlock.BlockStamp = bs
	}
	curBlock.Unlock()
	return bs, nil
}
Пример #11
0
// TestTx tests the API for Tx.
func TestTx(t *testing.T) {
	testTx := Block100000.Transactions[0]
	tx := btcutil.NewTx(testTx)

	// Ensure we get the same data back out.
	if msgTx := tx.MsgTx(); !reflect.DeepEqual(msgTx, testTx) {
		t.Errorf("MsgTx: mismatched MsgTx - got %v, want %v",
			spew.Sdump(msgTx), spew.Sdump(testTx))
	}

	// Ensure transaction index set and get work properly.
	wantIndex := 0
	tx.SetIndex(0)
	if gotIndex := tx.Index(); gotIndex != wantIndex {
		t.Errorf("Index: mismatched index - got %v, want %v",
			gotIndex, wantIndex)
	}

	// Hash for block 100,000 transaction 0.
	wantShaStr := "8c14f0db3df150123e6f3dbbf30f8b955a8249b62ac1d1ff16284aefa3d06d87"
	wantSha, err := btcwire.NewShaHashFromStr(wantShaStr)
	if err != nil {
		t.Errorf("NewShaHashFromStr: %v", err)
	}

	// Request the sha multiple times to test generation and caching.
	for i := 0; i < 2; i++ {
		sha := tx.Sha()
		if !sha.IsEqual(wantSha) {
			t.Errorf("Sha #%d mismatched sha - got %v, want %v", i,
				sha, wantSha)
		}
	}
}
Пример #12
0
func makeTx(outputs []output, amount, value int64, toAddr, changeAddr string) (*btcwire.MsgTx, error) {
	msgTx := btcwire.NewMsgTx()

	for _, op := range outputs {
		hash, err := btcwire.NewShaHashFromStr(op.TxHash)
		if err != nil {
			return nil, err
		}
		b, err := hex.DecodeString(op.Script)
		if err != nil {
			return nil, err
		}
		txIn := btcwire.NewTxIn(btcwire.NewOutPoint(hash, op.TxN), b)
		msgTx.AddTxIn(txIn)
	}

	script, err := makeScriptPubKey(toAddr)
	if err != nil {
		return nil, err
	}
	txOut := btcwire.NewTxOut(value, script)
	msgTx.AddTxOut(txOut)

	if amount > value {
		script, err = makeScriptPubKey(changeAddr)
		if err != nil {
			return nil, err
		}
		txOut := btcwire.NewTxOut(amount-value, script)
		msgTx.AddTxOut(txOut)
	}
	return msgTx, nil
}
Пример #13
0
func TestMerkleBlock3(t *testing.T) {
	blockStr := "0100000079cda856b143d9db2c1caff01d1aecc8630d30625d10e8b" +
		"4b8b0000000000000b50cc069d6a3e33e3ff84a5c41d9d3febe7c770fdc" +
		"c96b2c3ff60abe184f196367291b4d4c86041b8fa45d630101000000010" +
		"00000000000000000000000000000000000000000000000000000000000" +
		"0000ffffffff08044c86041b020a02ffffffff0100f2052a01000000434" +
		"104ecd3229b0571c3be876feaac0442a9f13c5a572742927af1dc623353" +
		"ecf8c202225f64868137a18cdd85cbbb4c74fbccfd4f49639cf1bdc94a5" +
		"672bb15ad5d4cac00000000"
	blockBytes, err := hex.DecodeString(blockStr)
	if err != nil {
		t.Errorf("TestMerkleBlock3 DecodeString failed: %v", err)
		return
	}
	blk, err := btcutil.NewBlockFromBytes(blockBytes)
	if err != nil {
		t.Errorf("TestMerkleBlock3 NewBlockFromBytes failed: %v", err)
		return
	}

	f := bloom.NewFilter(10, 0, 0.000001, btcwire.BloomUpdateAll)

	inputStr := "63194f18be0af63f2c6bc9dc0f777cbefed3d9415c4af83f3ee3a3d669c00cb5"
	sha, err := btcwire.NewShaHashFromStr(inputStr)
	if err != nil {
		t.Errorf("TestMerkleBlock3 NewShaHashFromStr failed: %v", err)
		return
	}

	f.AddShaHash(sha)

	mBlock, _ := bloom.NewMerkleBlock(blk, f)

	wantStr := "0100000079cda856b143d9db2c1caff01d1aecc8630d30625d10e8b4" +
		"b8b0000000000000b50cc069d6a3e33e3ff84a5c41d9d3febe7c770fdcc" +
		"96b2c3ff60abe184f196367291b4d4c86041b8fa45d630100000001b50c" +
		"c069d6a3e33e3ff84a5c41d9d3febe7c770fdcc96b2c3ff60abe184f196" +
		"30101"
	want, err := hex.DecodeString(wantStr)
	if err != nil {
		t.Errorf("TestMerkleBlock3 DecodeString failed: %v", err)
		return
	}

	got := bytes.NewBuffer(nil)
	err = mBlock.BtcEncode(got, btcwire.ProtocolVersion)
	if err != nil {
		t.Errorf("TestMerkleBlock3 BtcEncode failed: %v", err)
		return
	}

	if !bytes.Equal(want, got.Bytes()) {
		t.Errorf("TestMerkleBlock3 failed merkle block comparison: "+
			"got %v want %v", got.Bytes, want)
		return
	}
}
Пример #14
0
// 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")
	}
}
Пример #15
0
// TestGetHeaders tests the MsgGetHeader API.
func TestGetHeaders(t *testing.T) {
	pver := btcwire.ProtocolVersion

	// Block 99500 hash.
	hashStr := "000000000002e7ad7b9eef9479e4aabc65cb831269cc20d2632c13684406dee0"
	locatorHash, err := btcwire.NewShaHashFromStr(hashStr)
	if err != nil {
		t.Errorf("NewShaHashFromStr: %v", err)
	}

	// Ensure the command is expected value.
	wantCmd := "getheaders"
	msg := btcwire.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 < btcwire.MaxBlockLocatorsPerMsg; i++ {
		err = msg.AddBlockLocatorHash(locatorHash)
	}
	if err == nil {
		t.Errorf("AddBlockLocatorHash: expected error on too many " +
			"block locator hashes not received")
	}

	return
}
Пример #16
0
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))
	}
}
Пример #17
0
// handleWalletSendRawTransaction implements the websocket extended version of
// the sendrawtransaction command.
func handleWalletSendRawTransaction(s *rpcServer, cmd btcjson.Cmd, wallet walletChan) error {
	result, err := handleSendRawTransaction(s, cmd)
	if err != nil {
		return err
	}

	// The result is already guaranteed to be a valid hash string if no
	// error was returned above, so it's safe to ignore the error here.
	txSha, _ := btcwire.NewShaHashFromStr(result.(string))

	// Request to be notified when the transaction is mined.
	s.ws.AddMinedTxRequest(wallet, txSha)
	return nil
}
Пример #18
0
// newShaHashFromStr converts the passed big-endian hex string into a
// btcwire.ShaHash.  It only differs from the one available in btcwire in that
// it panics on an error since it will only (and must only) be called with
// hard-coded, and therefore known good, hashes.
func newShaHashFromStr(hexStr string) *btcwire.ShaHash {
	sha, err := btcwire.NewShaHashFromStr(hexStr)
	if err != nil {
		// Ordinarily I don't like panics in library code since it
		// can take applications down without them having a chance to
		// recover which is extremely annoying, however an exception is
		// being made in this case because the only way this can panic
		// is if there is an error in the hard-coded hashes.  Thus it
		// will only ever potentially panic on init and therefore is
		// 100% predictable.
		panic(err)
	}
	return sha
}
Пример #19
0
// Receive waits for the response promised by the future and returns the hash of
// the block in the best block chain at the given height.
func (r FutureGetBlockHashResult) Receive() (*btcwire.ShaHash, error) {
	res, err := receiveFuture(r)
	if err != nil {
		return nil, err
	}

	// Unmarshal the result as a string-encoded sha.
	var txHashStr string
	err = json.Unmarshal(res, &txHashStr)
	if err != nil {
		return nil, err
	}
	return btcwire.NewShaHashFromStr(txHashStr)
}
Пример #20
0
// Receive waits for the response promised by the future and returns the result
// of submitting the encoded transaction to the server which then relays it to
// the network.
func (r FutureSendRawTransactionResult) Receive() (*btcwire.ShaHash, error) {
	reply, err := receiveFuture(r)
	if err != nil {
		return nil, err
	}

	// Ensure the returned data is the expected type.
	txHashStr, ok := reply.(string)
	if !ok {
		return nil, fmt.Errorf("unexpected response type for "+
			"decoderawtransaction: %T\n", reply)
	}

	return btcwire.NewShaHashFromStr(txHashStr)
}
Пример #21
0
func parseBlock(block *btcws.BlockDetails) (*txstore.Block, int, error) {
	if block == nil {
		return nil, btcutil.TxIndexUnknown, nil
	}
	blksha, err := btcwire.NewShaHashFromStr(block.Hash)
	if err != nil {
		return nil, btcutil.TxIndexUnknown, err
	}
	b := &txstore.Block{
		Height: block.Height,
		Hash:   *blksha,
		Time:   time.Unix(block.Time, 0),
	}
	return b, block.Index, nil
}
Пример #22
0
// Receive waits for the response promised by the future and returns the result
// of submitting the encoded transaction to the server which then relays it to
// the network.
func (r FutureSendRawTransactionResult) Receive() (*btcwire.ShaHash, error) {
	res, err := receiveFuture(r)
	if err != nil {
		return nil, err
	}

	// Unmarshal result as a string.
	var txHashStr string
	err = json.Unmarshal(res, &txHashStr)
	if err != nil {
		return nil, err
	}

	return btcwire.NewShaHashFromStr(txHashStr)
}
Пример #23
0
// Receive waits for the response promised by the future and returns the hash of
// the block in the best block chain at the given height.
func (r FutureGetBlockHashResult) Receive() (*btcwire.ShaHash, error) {
	reply, err := receiveFuture(r)
	if err != nil {
		return nil, err
	}

	// Ensure the returned data is the expected type.
	txHashStr, ok := reply.(string)
	if !ok {
		return nil, fmt.Errorf("unexpected response type for "+
			"getblockhash: %T\n", reply)
	}

	return btcwire.NewShaHashFromStr(txHashStr)
}
Пример #24
0
// TestBlockSha tests the ability to generate the hash of a block accurately.
func TestBlockSha(t *testing.T) {
	// 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()
	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))
	}
}
Пример #25
0
// NtfnBlockDisconnected handles btcd notifications resulting from
// blocks disconnected from the main chain in the event of a chain
// switch and notifies frontends of the new blockchain height.
func NtfnBlockDisconnected(n btcjson.Cmd, marshaled []byte) {
	bdn, ok := n.(*btcws.BlockDisconnectedNtfn)
	if !ok {
		log.Errorf("%v handler: unexpected type", n.Method())
		return
	}
	hash, err := btcwire.NewShaHashFromStr(bdn.Hash)
	if err != nil {
		log.Errorf("%v handler: invalid hash string", n.Method())
		return
	}

	// Rollback Utxo and Tx data stores.
	accountstore.Rollback(bdn.Height, hash)

	// Pass notification to frontends too.
	frontendNotificationMaster <- marshaled
}
Пример #26
0
func rpcTxPick(exact bool, targetAmnt int64, params BuilderParams) (*TxInParams, error) {
	// selects an unspent outpoint that is funded over the minAmount
	list, err := params.Client.ListUnspent()
	if err != nil {
		log.Println("list unpsent threw")
		return nil, err
	}
	if len(list) < 1 {
		return nil, errors.New("No unspent outputs at all.")
	}

	for _, prevJson := range list {
		_amnt, _ := btcutil.NewAmount(prevJson.Amount)
		amnt := int64(_amnt)
		txid := prevJson.TxId
		prevHash, _ := btcwire.NewShaHashFromStr(txid)
		outPoint := btcwire.NewOutPoint(prevHash, prevJson.Vout)

		_, contained := params.PendingSet[outPointStr(outPoint)]
		// This unpsent is in the pending set and it either exactly equals the target or
		// has a value above that target
		if !contained && (exact && targetAmnt == amnt || !exact && targetAmnt <= amnt) {
			// Found one, lets use it
			script, _ := hex.DecodeString(prevJson.ScriptPubKey)
			// None of the above ~should~ ever throw errors
			txOut := btcwire.NewTxOut(amnt, script)

			prevAddress, _ := btcutil.DecodeAddress(prevJson.Address, params.NetParams)
			wifkey, err := params.Client.DumpPrivKey(prevAddress)
			if err != nil {
				return nil, err
			}
			inParams := TxInParams{
				TxOut:    txOut,
				OutPoint: outPoint,
				Wif:      wifkey,
			}
			params.PendingSet[outPointStr(outPoint)] = struct{}{}
			return &inParams, nil
		}
	}
	// Never found a good outpoint
	return nil, errors.New("No txout with the right funds")
}
Пример #27
0
// NtfnBlockDisconnected handles btcd notifications resulting from
// blocks disconnected from the main chain in the event of a chain
// switch and notifies frontends of the new blockchain height.
func NtfnBlockDisconnected(n btcjson.Cmd) error {
	bdn, ok := n.(*btcws.BlockDisconnectedNtfn)
	if !ok {
		return fmt.Errorf("%v handler: unexpected type", n.Method())
	}
	hash, err := btcwire.NewShaHashFromStr(bdn.Hash)
	if err != nil {
		return fmt.Errorf("%v handler: invalid hash string", n.Method())
	}

	// Rollback Utxo and Tx data stores.
	AcctMgr.Rollback(bdn.Height, hash)

	// Pass notification to frontends too.
	marshaled, _ := n.MarshalJSON()
	allClients <- marshaled

	return nil
}
Пример #28
0
// TestBlockTxShas tests the ability to generate a slice of all transaction
// hashes from a block accurately.
func TestBlockTxShas(t *testing.T) {
	// Block 1, transaction 1 hash.
	hashStr := "0e3e2357e806b6cdb1f70b54c3a3a17b6714ee1f0e68bebb44a74b1efd512098"
	wantHash, err := btcwire.NewShaHashFromStr(hashStr)
	if err != nil {
		t.Errorf("NewShaHashFromStr: %v", err)
		return
	}

	wantShas := []btcwire.ShaHash{*wantHash}
	shas, err := blockOne.TxShas()
	if err != nil {
		t.Errorf("TxShas: %v", err)
	}
	if !reflect.DeepEqual(shas, wantShas) {
		t.Errorf("TxShas: wrong transaction hashes - got %v, want %v",
			spew.Sdump(shas), spew.Sdump(wantShas))
	}
}
Пример #29
0
// Receive waits for the response promised by the future and returns the hash
// and height of the block in the longest (best) chain.
func (r FutureGetBestBlockResult) Receive() (*btcwire.ShaHash, int32, error) {
	reply, err := receiveFuture(r)
	if err != nil {
		return nil, 0, err
	}

	// Ensure the returned data is the expected type.
	result, ok := reply.(*btcws.GetBestBlockResult)
	if !ok {
		return nil, 0, fmt.Errorf("unexpected response type for "+
			"getbestblock: %T\n", reply)
	}

	// Convert hash string.
	hash, err := btcwire.NewShaHashFromStr(result.Hash)
	if err != nil {
		return nil, 0, err
	}

	return hash, result.Height, nil
}
Пример #30
0
// Receive waits for the response promised by the future and returns the hash
// and height of the block in the longest (best) chain.
func (r FutureGetBestBlockResult) Receive() (*btcwire.ShaHash, int32, error) {
	res, err := receiveFuture(r)
	if err != nil {
		return nil, 0, err
	}

	// Unmarsal result as a getbestblock result object.
	var bestBlock btcws.GetBestBlockResult
	err = json.Unmarshal(res, &bestBlock)
	if err != nil {
		return nil, 0, err
	}

	// Convert hash string.
	hash, err := btcwire.NewShaHashFromStr(bestBlock.Hash)
	if err != nil {
		return nil, 0, err
	}

	return hash, bestBlock.Height, nil
}