func (db *LevelDb) getData(data []byte) ([]database.TxData, error) { var list []database.TxData key := dataToKey(data, nil, 0) iter := db.lDb.NewIterator(util.BytesPrefix(key), nil) for iter.Next() { item := database.TxData{} val := iter.Value() var err error if len(val) == 32 { // TODO remove this once db has been updated. item.TxSha, err = wire.NewShaHash(val) if err != nil { return nil, err } } else if len(val) == 72 { item.TxSha, err = wire.NewShaHash(val[0:32]) if err != nil { return nil, err } item.BlockSha, err = wire.NewShaHash(val[32:64]) if err != nil { return nil, err } b := bytes.NewBuffer(val[64:72]) binary.Read(b, binary.LittleEndian, &item.Time) } else { return nil, fmt.Errorf("Non-standard length %d", len(val)) } list = append(list, item) } iter.Release() if err := iter.Error(); err != nil { return nil, err } return list, nil }
// BUGS: // - MinimumRecentTransactions is ignored. // - Wrong error codes when a block height or hash is not recognized func (s *walletServer) GetTransactions(ctx context.Context, req *pb.GetTransactionsRequest) ( resp *pb.GetTransactionsResponse, err error) { var startBlock, endBlock *wallet.BlockIdentifier if req.StartingBlockHash != nil && req.StartingBlockHeight != 0 { return nil, errors.New( "starting block hash and height may not be specified simultaneously") } else if req.StartingBlockHash != nil { startBlockHash, err := wire.NewShaHash(req.StartingBlockHash) if err != nil { return nil, grpc.Errorf(codes.InvalidArgument, "%s", err.Error()) } startBlock = wallet.NewBlockIdentifierFromHash(startBlockHash) } else if req.StartingBlockHeight != 0 { startBlock = wallet.NewBlockIdentifierFromHeight(req.StartingBlockHeight) } if req.EndingBlockHash != nil && req.EndingBlockHeight != 0 { return nil, grpc.Errorf(codes.InvalidArgument, "ending block hash and height may not be specified simultaneously") } else if req.EndingBlockHash != nil { endBlockHash, err := wire.NewShaHash(req.EndingBlockHash) if err != nil { return nil, grpc.Errorf(codes.InvalidArgument, "%s", err.Error()) } endBlock = wallet.NewBlockIdentifierFromHash(endBlockHash) } else if req.EndingBlockHeight != 0 { endBlock = wallet.NewBlockIdentifierFromHeight(req.EndingBlockHeight) } var minRecentTxs int if req.MinimumRecentTransactions != 0 { if endBlock != nil { return nil, grpc.Errorf(codes.InvalidArgument, "ending block and minimum number of recent transactions "+ "may not be specified simultaneously") } minRecentTxs = int(req.MinimumRecentTransactions) if minRecentTxs < 0 { return nil, grpc.Errorf(codes.InvalidArgument, "minimum number of recent transactions may not be negative") } } _ = minRecentTxs gtr, err := s.wallet.GetTransactions(startBlock, endBlock, ctx.Done()) if err != nil { return nil, translateError(err) } return marshalGetTransactionsResult(gtr) }
func NewCoin(txid []byte, index uint32, value btc.Amount, numConfs int64, scriptPubKey []byte) coinset.Coin { shaTxid, _ := wire.NewShaHash(txid) c := &Coin{ TxHash: shaTxid, TxIndex: index, TxValue: value, TxNumConfs: numConfs, ScriptPubKey: scriptPubKey, } return coinset.Coin(c) }
func NewCoin(index int64, value btcutil.Amount, numConfs int64) coinset.Coin { h := fastsha256.New() h.Write([]byte(fmt.Sprintf("%d", index))) hash, _ := wire.NewShaHash(h.Sum(nil)) c := &TestCoin{ TxHash: hash, TxIndex: 0, TxValue: value, TxNumConfs: numConfs, } return coinset.Coin(c) }
// 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 aid in the generation of a merkle tree. func HashMerkleBranches(left *wire.ShaHash, right *wire.ShaHash) *wire.ShaHash { // Concatenate the left and right nodes. var sha [wire.HashSize * 2]byte copy(sha[:wire.HashSize], left.Bytes()) copy(sha[wire.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, _ := wire.NewShaHash(wire.DoubleSha256(sha[:])) return newSha }
// 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([]*wire.InvVect, 0, numInvVects) for i := 0; i < numInvVects; i++ { hashBytes := make([]byte, wire.HashSize) rand.Read(hashBytes) hash, _ := wire.NewShaHash(hashBytes) iv := wire.NewInvVect(wire.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]) } }
// genBlockHash deterministically generates a dummy block header hash for use // within our tests below. func genBlockHash(n int) *wire.ShaHash { sha := sha256.Sum256([]byte{byte(n)}) hash, _ := wire.NewShaHash(sha[:]) return hash }
// TestShaHash tests the ShaHash API. func TestShaHash(t *testing.T) { // Hash of block 234439. blockHashStr := "14a0810ac680a3eb3f82edc878cea25ec41d6b790744e5daeef" blockHash, err := wire.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 := wire.NewShaHash(buf) if err != nil { t.Errorf("NewShaHash: unexpected error %v", err) } // Ensure proper size. if len(hash) != wire.HashSize { t.Errorf("NewShaHash: hash length mismatch - got: %v, want: %v", len(hash), wire.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") } // Invalid size for NewShaHash. invalidHash := make([]byte, wire.HashSize+1) _, err = wire.NewShaHash(invalidHash) if err == nil { t.Errorf("NewShaHash: failed to received expected err - got: nil") } }
// TestMerkleBlock tests the MsgMerkleBlock API. func TestMerkleBlock(t *testing.T) { pver := wire.ProtocolVersion // Block 1 header. prevHash := &blockOne.Header.PrevBlock merkleHash := &blockOne.Header.MerkleRoot bits := blockOne.Header.Bits nonce := blockOne.Header.Nonce bh := wire.NewBlockHeader(prevHash, merkleHash, bits, nonce) // Ensure the command is expected value. wantCmd := "merkleblock" msg := wire.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 < wire.MaxTxPerBlock; i++ { rand.Read(data) hash, err := wire.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 := wire.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 := wire.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, wire.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 } }
address = pubKey // Delivery PkScript // Privkey: f2c00ead9cbcfec63098dc0a5f152c0165aff40a2ab92feb4e24869a284c32a7 // PKhash: n2fkWVphUzw3zSigzPsv9GuDyg9mohzKpz deliveryPkScript, _ = hex.DecodeString("76a914e8048c0fb75bdecc91ebfb99c174f4ece29ffbd488ac") // Change PkScript // Privkey: 5b18f5049efd9d3aff1fb9a06506c0b809fb71562b6ecd02f6c5b3ab298f3b0f // PKhash: miky84cHvLuk6jcT6GsSbgHR8d7eZCu9Qc changePkScript, _ = hex.DecodeString("76a914238ee44bb5c8c1314dd03974a17ec6c406fdcb8388ac") // echo -n | openssl sha256 // This stuff gets reversed!!! shaHash1Bytes, _ = hex.DecodeString("e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855") shaHash1, _ = wire.NewShaHash(shaHash1Bytes) outpoint1 = wire.NewOutPoint(shaHash1, 0) // echo | openssl sha256 // This stuff gets reversed!!! shaHash2Bytes, _ = hex.DecodeString("01ba4719c80b6fe911b091a7c05124b64eeece964e09c058ef8f9805daca546b") shaHash2, _ = wire.NewShaHash(shaHash2Bytes) outpoint2 = wire.NewOutPoint(shaHash2, 1) // create inputs from outpoint1 and outpoint2 inputs = []*wire.TxIn{wire.NewTxIn(outpoint1, nil), wire.NewTxIn(outpoint2, nil)} // Commitment Signature tx = wire.NewMsgTx() emptybytes = new([]byte) sigStr, _ = txscript.RawTxInSignature(tx, 0, *emptybytes, txscript.SigHashAll, privKey) commitSig, _ = btcec.ParseSignature(sigStr, btcec.S256())
func (l *LibbitcoinClient) Parse(command string, data []byte, callback func(interface{}, error)) { switch command { case "address.fetch_history2": numRows := (len(data) - 4) / 49 buff := bytes.NewBuffer(data) err := ParseError(buff.Next(4)) rows := []FetchHistory2Resp{} for i := 0; i < numRows; i++ { r := FetchHistory2Resp{} spendByte := int(buff.Next(1)[0]) var spendBool bool if spendByte == 0 { spendBool = false } else { spendBool = true } r.IsSpend = spendBool lehash := buff.Next(32) sh, _ := wire.NewShaHash(lehash) r.TxHash = sh.String() indexBytes := buff.Next(4) r.Index = binary.LittleEndian.Uint32(indexBytes) heightBytes := buff.Next(4) r.Height = binary.LittleEndian.Uint32(heightBytes) valueBytes := buff.Next(8) r.Value = binary.LittleEndian.Uint64(valueBytes) rows = append(rows, r) } callback(rows, err) case "blockchain.fetch_last_height": height := binary.LittleEndian.Uint32(data[4:]) callback(height, ParseError(data[:4])) case "blockchain.fetch_transaction": txn, _ := btc.NewTxFromBytes(data[4:]) callback(txn, ParseError(data[:4])) case "transaction_pool.fetch_transaction": txn, _ := btc.NewTxFromBytes(data[4:]) callback(txn, ParseError(data[:4])) case "address.update": buff := bytes.NewBuffer(data) addressVersion := buff.Next(1)[0] addressHash160 := buff.Next(20) height := buff.Next(4) block := buff.Next(32) tx := buff.Bytes() var addr btc.Address if addressVersion == byte(111) || addressVersion == byte(0) { a, _ := btc.NewAddressPubKeyHash(addressHash160, l.Params) addr = a } else if addressVersion == byte(5) || addressVersion == byte(196) { a, _ := btc.NewAddressScriptHashFromHash(addressHash160, l.Params) addr = a } bl, _ := wire.NewShaHash(block) txn, _ := btc.NewTxFromBytes(tx) resp := SubscribeResp{ Address: addr.String(), Height: binary.LittleEndian.Uint32(height), Block: bl.String(), Tx: *txn, } l.lock.Lock() l.subscriptions[addr.String()].callback(resp) l.lock.Unlock() case "protocol.broadcast_transaction": callback(nil, ParseError(data[:4])) case "transaction_pool.validate": b := data[4:5] success, _ := strconv.ParseBool(string(b)) callback(success, ParseError(data[:4])) } }
func TestInsertData(t *testing.T) { // Ignore db remove errors since it means we didn't have an old one. dbname := fmt.Sprintf("tstdbdata1") dbnamever := dbname + ".ver" _ = os.RemoveAll(dbname) _ = os.RemoveAll(dbnamever) db, err := database.CreateDB("leveldb", dbname) if err != nil { t.Fatalf("Failed to open test database %v", err) } defer os.RemoveAll(dbname) defer os.RemoveAll(dbnamever) defer func() { if err := db.Close(); err != nil { t.Errorf("Close: unexpected error: %v", err) } }() list, err := db.FetchTxsByData([]byte("dhaskj2")) if err != nil { t.Fatalf("Get data failed %v", err) } if len(list) != 0 { t.Errorf("Expected empty list, got length %d.", len(list)) } txSha0, err := wire.NewShaHash([]byte("00001111222233334444555566667777")) if err != nil { t.Fatalf("Failed to set-up ShaHash %v", err) } txSha1, err := wire.NewShaHash([]byte("10001111222233334444555566667777")) if err != nil { t.Fatalf("Failed to set-up ShaHash %v", err) } err = db.InsertData([]byte("dhaskj1"), txSha0, 0) if err != nil { t.Fatalf("Insert data failed %v", err) } list, err = db.FetchTxsByData([]byte("dhaskj2")) if err != nil { t.Fatalf("Get data failed %v", err) } if len(list) != 0 { t.Errorf("Expected empty list, got length %d.", len(list)) } err = db.InsertData([]byte("dhaskj2"), txSha0, 0) if err != nil { t.Fatalf("Insert data failed %v", err) } err = db.InsertData([]byte("dhaskj2"), txSha1, 0) if err != nil { t.Fatalf("Insert data failed %v", err) } list, err = db.FetchTxsByData([]byte("dhaskj2")) if err != nil { t.Fatalf("Get data failed %v", err) } if len(list) != 2 { t.Errorf("Expected list with 2 items, got %d.", len(list)) } }
func readElement(r io.Reader, element interface{}) error { var err error switch e := element.(type) { case *uint8: var b [1]uint8 _, err = r.Read(b[:]) if err != nil { return err } *e = b[0] return nil case *uint16: var b [2]byte _, err = io.ReadFull(r, b[:]) if err != nil { return err } *e = binary.BigEndian.Uint16(b[:]) return nil case *CreditsAmount: var b [4]byte _, err = io.ReadFull(r, b[:]) if err != nil { return err } *e = CreditsAmount(int32(binary.BigEndian.Uint32(b[:]))) return nil case *uint32: var b [4]byte _, err = io.ReadFull(r, b[:]) if err != nil { return err } *e = binary.BigEndian.Uint32(b[:]) return nil case *uint64: var b [8]byte _, err = io.ReadFull(r, b[:]) if err != nil { return err } *e = binary.BigEndian.Uint64(b[:]) return nil case *HTLCKey: var b [8]byte _, err = io.ReadFull(r, b[:]) if err != nil { return err } *e = HTLCKey(binary.BigEndian.Uint64(b[:])) return nil case *btcutil.Amount: var b [8]byte _, err = io.ReadFull(r, b[:]) if err != nil { return err } *e = btcutil.Amount(int64(binary.BigEndian.Uint64(b[:]))) return nil case **wire.ShaHash: var b wire.ShaHash _, err = io.ReadFull(r, b[:]) if err != nil { return err } *e = &b return nil case **btcec.PublicKey: var b [33]byte _, err = io.ReadFull(r, b[:]) if err != nil { return err } x, err := btcec.ParsePubKey(b[:], btcec.S256()) if err != nil { return err } *e = &*x return nil case *[]uint64: var numItems uint16 err = readElement(r, &numItems) if err != nil { return err } // if numItems > 65535 { // return fmt.Errorf("Too many items in []uint64") // } // Read the number of items var items []uint64 for i := uint16(0); i < numItems; i++ { var item uint64 err = readElement(r, &item) if err != nil { return err } items = append(items, item) } *e = *&items return nil case *[]*btcec.Signature: var numSigs uint8 err = readElement(r, &numSigs) if err != nil { return err } if numSigs > 127 { return fmt.Errorf("Too many signatures!") } // Read that number of signatures var sigs []*btcec.Signature for i := uint8(0); i < numSigs; i++ { sig := new(btcec.Signature) err = readElement(r, &sig) if err != nil { return err } sigs = append(sigs, sig) } *e = *&sigs return nil case **btcec.Signature: var sigLength uint8 err = readElement(r, &sigLength) if err != nil { return err } if sigLength > 73 { return fmt.Errorf("Signature too long!") } // Read the sig length l := io.LimitReader(r, int64(sigLength)) sig, err := ioutil.ReadAll(l) if err != nil { return err } if len(sig) != int(sigLength) { return fmt.Errorf("EOF: Signature length mismatch.") } btcecSig, err := btcec.ParseSignature(sig, btcec.S256()) if err != nil { return err } *e = &*btcecSig return nil case *[]*[20]byte: // How many to read var sliceSize uint16 err = readElement(r, &sliceSize) if err != nil { return err } var data []*[20]byte // Append the actual for i := uint16(0); i < sliceSize; i++ { var element [20]byte err = readElement(r, &element) if err != nil { return err } data = append(data, &element) } *e = data return nil case *[20]byte: _, err = io.ReadFull(r, e[:]) if err != nil { return err } return nil case *wire.BitcoinNet: var b [4]byte _, err := io.ReadFull(r, b[:]) if err != nil { return err } *e = wire.BitcoinNet(binary.BigEndian.Uint32(b[:])) return nil case *[]byte: // Get the blob length first var blobLength uint16 err = readElement(r, &blobLength) if err != nil { return err } // Shouldn't need to do this, since it's uint16, but we // might have a different value for MAX_SLICE_LENGTH... if int(blobLength) > MAX_SLICE_LENGTH { return fmt.Errorf("Slice length too long!") } // Read the slice length l := io.LimitReader(r, int64(blobLength)) *e, err = ioutil.ReadAll(l) if err != nil { return err } if len(*e) != int(blobLength) { return fmt.Errorf("EOF: Slice length mismatch.") } return nil case *PkScript: // Get the script length first var scriptLength uint8 err = readElement(r, &scriptLength) if err != nil { return err } if scriptLength > 25 { return fmt.Errorf("PkScript too long!") } // Read the script length l := io.LimitReader(r, int64(scriptLength)) *e, err = ioutil.ReadAll(l) if err != nil { return err } if len(*e) != int(scriptLength) { return fmt.Errorf("EOF: Signature length mismatch.") } return nil case *string: // Get the string length first var strlen uint16 err = readElement(r, &strlen) if err != nil { return err } // Read the string for the length l := io.LimitReader(r, int64(strlen)) b, err := ioutil.ReadAll(l) if len(b) != int(strlen) { return fmt.Errorf("EOF: String length mismatch.") } *e = string(b) if err != nil { return err } return nil case *[]*wire.TxIn: // Read the size (1-byte number of txins) var numScripts uint8 err = readElement(r, &numScripts) if err != nil { return err } if numScripts > 127 { return fmt.Errorf("Too many txins") } // Append the actual TxIns var txins []*wire.TxIn for i := uint8(0); i < numScripts; i++ { outpoint := new(wire.OutPoint) txin := wire.NewTxIn(outpoint, nil) err = readElement(r, &txin) if err != nil { return err } txins = append(txins, txin) } *e = *&txins return nil case **wire.TxIn: // Hash var h [32]byte _, err = io.ReadFull(r, h[:]) if err != nil { return err } hash, err := wire.NewShaHash(h[:]) if err != nil { return err } (*e).PreviousOutPoint.Hash = *hash // Index var idxBytes [4]byte _, err = io.ReadFull(r, idxBytes[:]) if err != nil { return err } (*e).PreviousOutPoint.Index = binary.BigEndian.Uint32(idxBytes[:]) return nil default: return fmt.Errorf("Unknown type in readElement: %T", e) } return nil }