// GetHeadersAsync returns an instance of a type that can be used to get the result // of the RPC at some future time by invoking the Receive function on the returned instance. // // See GetHeaders for the blocking version and more details. func (c *Client) GetHeadersAsync(blockLocators []chainhash.Hash, hashStop *chainhash.Hash) FutureGetHeadersResult { concatenatedLocators := make([]byte, chainhash.HashSize*len(blockLocators)) for i := range blockLocators { copy(concatenatedLocators[i*chainhash.HashSize:], blockLocators[i][:]) } cmd := dcrjson.NewGetHeadersCmd(hex.EncodeToString(concatenatedLocators), hashStop.String()) return c.sendCmd(cmd) }
// GetRawTransactionAsync returns an instance of a type that can be used to get // the result of the RPC at some future time by invoking the Receive function on // the returned instance. // // See GetRawTransaction for the blocking version and more details. func (c *Client) GetRawTransactionAsync(txHash *chainhash.Hash) FutureGetRawTransactionResult { hash := "" if txHash != nil { hash = txHash.String() } cmd := dcrjson.NewGetRawTransactionCmd(hash, dcrjson.Int(0)) return c.sendCmd(cmd) }
// GetBlockAsync returns an instance of a type that can be used to get the // result of the RPC at some future time by invoking the Receive function on the // returned instance. // // See GetBlock for the blocking version and more details. func (c *Client) GetBlockAsync(blockHash *chainhash.Hash) FutureGetBlockResult { hash := "" if blockHash != nil { hash = blockHash.String() } cmd := dcrjson.NewGetBlockCmd(hash, dcrjson.Bool(false), nil) return c.sendCmd(cmd) }
// GetBlockVerboseAsync returns an instance of a type that can be used to get // the result of the RPC at some future time by invoking the Receive function on // the returned instance. // // See GetBlockVerbose for the blocking version and more details. func (c *Client) GetBlockVerboseAsync(blockHash *chainhash.Hash, verboseTx bool) FutureGetBlockVerboseResult { hash := "" if blockHash != nil { hash = blockHash.String() } cmd := dcrjson.NewGetBlockCmd(hash, dcrjson.Bool(true), &verboseTx) return c.sendCmd(cmd) }
// GetTxOutAsync returns an instance of a type that can be used to get // the result of the RPC at some future time by invoking the Receive function on // the returned instance. // // See GetTxOut for the blocking version and more details. func (c *Client) GetTxOutAsync(txHash *chainhash.Hash, index uint32, mempool bool) FutureGetTxOutResult { hash := "" if txHash != nil { hash = txHash.String() } cmd := dcrjson.NewGetTxOutCmd(hash, index, &mempool) return c.sendCmd(cmd) }
// fetchSStxRecord retrieves a tx record from the sstx records bucket // with the given hash. func fetchSStxRecord(tx walletdb.Tx, hash *chainhash.Hash) (*sstxRecord, error) { bucket := tx.RootBucket().Bucket(sstxRecordsBucketName) key := hash.Bytes() val := bucket.Get(key) if val == nil { str := fmt.Sprintf("missing sstx record for hash '%s'", hash.String()) return nil, stakeStoreError(ErrSStxNotFound, str, nil) } return deserializeSStxRecord(val) }
// fetchSSRtxRecords retrieves SSRtx records from the SSRtxRecords bucket with // the given hash. func fetchSSRtxRecords(ns walletdb.ReadBucket, hash *chainhash.Hash) ([]*ssrtxRecord, error) { bucket := ns.NestedReadBucket(ssrtxRecordsBucketName) key := hash.Bytes() val := bucket.Get(key) if val == nil { str := fmt.Sprintf("missing ssrtx records for hash '%s'", hash.String()) return nil, stakeStoreError(ErrSSRtxsNotFound, str, nil) } return deserializeSSRtxRecords(val) }
// fetchSStxRecordSStxTicketHash160 retrieves a ticket 0th output script or // pubkeyhash from the sstx records bucket with the given hash. func fetchSStxRecordSStxTicketHash160(ns walletdb.ReadBucket, hash *chainhash.Hash) (hash160 []byte, p2sh bool, err error) { bucket := ns.NestedReadBucket(sstxRecordsBucketName) key := hash.Bytes() val := bucket.Get(key) if val == nil { str := fmt.Sprintf("missing sstx record for hash '%s'", hash.String()) return nil, false, stakeStoreError(ErrSStxNotFound, str, nil) } return deserializeSStxTicketHash160(val) }
// updateSStxRecordVoteBits updates an individual ticket's intended voteBits // which are used to override the default voteBits when voting. func updateSStxRecordVoteBits(ns walletdb.ReadWriteBucket, hash *chainhash.Hash, voteBits stake.VoteBits) error { if len(voteBits.ExtendedBits) > stake.MaxSingleBytePushLength-2 { str := fmt.Sprintf("voteBitsExt too long (got %v bytes, want max %v)", len(voteBits.ExtendedBits), stake.MaxSingleBytePushLength-2) return stakeStoreError(ErrData, str, nil) } bucket := ns.NestedReadWriteBucket(sstxRecordsBucketName) key := hash.Bytes() val := bucket.Get(key) if val == nil { str := fmt.Sprintf("missing sstx record for hash '%s'", hash.String()) return stakeStoreError(ErrSStxNotFound, str, nil) } valLen := len(val) valCopy := make([]byte, valLen, valLen) copy(valCopy, val) // Move the cursor to the voteBits position and rewrite it. curPos := 0 curPos += int64Size curPos += int32Size // Write the intended votebits length (uint8). valCopy[curPos] = byte(int16Size + len(voteBits.ExtendedBits)) curPos += int8Size // Write the first two bytes for the intended votebits. byteOrder.PutUint16(valCopy[curPos:curPos+int16Size], voteBits.Bits) curPos += int16Size // Copy the remaining data from voteBitsExt. copy(valCopy[curPos:], voteBits.ExtendedBits[:]) err := bucket.Put(key, valCopy) if err != nil { str := fmt.Sprintf("failed to update sstxrecord votebits for '%s'", hash) return stakeStoreError(ErrDatabase, str, err) } return nil }
// fetchSStxRecordVoteBits fetches an individual ticket's intended voteBits // which are used to override the default voteBits when voting. func fetchSStxRecordVoteBits(ns walletdb.ReadBucket, hash *chainhash.Hash) (bool, stake.VoteBits, error) { bucket := ns.NestedReadBucket(sstxRecordsBucketName) key := hash.Bytes() val := bucket.Get(key) if val == nil { str := fmt.Sprintf("missing sstx record for hash '%s'", hash.String()) return false, stake.VoteBits{}, stakeStoreError(ErrSStxNotFound, str, nil) } valLen := len(val) valCopy := make([]byte, valLen, valLen) copy(valCopy, val) // Move the cursor to the voteBits position and rewrite it. curPos := 0 curPos += int64Size curPos += int32Size // Read the intended votebits length (uint8). If it is unset, return now. // Check it for sanity. voteBitsLen := uint8(val[curPos]) if voteBitsLen == 0 { return false, stake.VoteBits{}, nil } if voteBitsLen < 2 || voteBitsLen > stake.MaxSingleBytePushLength { str := fmt.Sprintf("corrupt votebits length '%v'", voteBitsLen) return false, stake.VoteBits{}, stakeStoreError(ErrData, str, nil) } curPos += int8Size // Read the first two bytes for the intended votebits. voteBits := byteOrder.Uint16(valCopy[curPos : curPos+int16Size]) curPos += int16Size // Retrieve the extended vote bits. voteBitsExt := make([]byte, voteBitsLen-int16Size) copy(voteBitsExt[:], valCopy[curPos:(curPos+int(voteBitsLen)-int16Size)]) return true, stake.VoteBits{Bits: voteBits, ExtendedBits: voteBitsExt}, nil }
// ExistsLiveTicketAsync returns an instance of a type that can be used to get the // result of the RPC at some future time by invoking the Receive function on the // returned instance. func (c *Client) ExistsLiveTicketAsync(hash *chainhash.Hash) FutureExistsLiveTicketResult { cmd := dcrjson.NewExistsLiveTicketCmd(hash.String()) return c.sendCmd(cmd) }