add GetMempoolTx()

This commit is contained in:
Larry Ruane 2020-09-10 13:50:14 -06:00 committed by Larry Ruane
parent 68836ee627
commit 7381129740
9 changed files with 544 additions and 148 deletions

View File

@ -117,7 +117,11 @@ func GetSaplingInfo() (int, int, string, string) {
func getBlockFromRPC(height int) (*walletrpc.CompactBlock, error) {
params := make([]json.RawMessage, 2)
params[0] = json.RawMessage("\"" + strconv.Itoa(height) + "\"")
heightJSON, err := json.Marshal(strconv.Itoa(height))
if err != nil {
return nil, errors.Wrap(err, "error marshaling height")
}
params[0] = heightJSON
params[1] = json.RawMessage("0") // non-verbose (raw hex)
result, rpcErr := RawRequest("getblock", params)
@ -131,7 +135,7 @@ func getBlockFromRPC(height int) (*walletrpc.CompactBlock, error) {
}
var blockDataHex string
err := json.Unmarshal(result, &blockDataHex)
err = json.Unmarshal(result, &blockDataHex)
if err != nil {
return nil, errors.Wrap(err, "error reading JSON response")
}
@ -314,13 +318,16 @@ func GetBlockRange(cache *BlockCache, blockOut chan<- *walletrpc.CompactBlock, e
errOut <- nil
}
// Reverse the given byte slice, returning a slice pointing to new data;
// the input slice is unchanged.
func Reverse(a []byte) []byte {
r := make([]byte, len(a), len(a))
for left, right := 0, len(a)-1; left < right; left, right = left+1, right-1 {
r[left], r[right] = a[right], a[left]
}
return r
}
func displayHash(hash []byte) string {
rhash := make([]byte, len(hash))
copy(rhash, hash)
// Reverse byte order
for i := 0; i < len(rhash)/2; i++ {
j := len(rhash) - 1 - i
rhash[i], rhash[j] = rhash[j], rhash[i]
}
return hex.EncodeToString(rhash)
return hex.EncodeToString(Reverse(hash))
}

View File

@ -66,11 +66,8 @@ func TestMain(m *testing.M) {
}
scan := bufio.NewScanner(testBlocks)
for scan.Scan() { // each line (block)
block := scan.Bytes()
// Enclose the hex string in quotes (to make it json, to match what's
// returned by the RPC)
block = []byte("\"" + string(block) + "\"")
blocks = append(blocks, block)
blockJSON, _ := json.Marshal(scan.Text())
blocks = append(blocks, blockJSON)
}
// Setup is done; run all tests.

View File

@ -404,7 +404,7 @@ func darksideRawRequest(method string, params []json.RawMessage) (json.RawMessag
if index >= len(state.activeBlocks) {
return nil, errors.New(notFoundErr)
}
return []byte("\"" + hex.EncodeToString(state.activeBlocks[index]) + "\""), nil
return json.Marshal(hex.EncodeToString(state.activeBlocks[index]))
case "getaddresstxids":
// Not required for minimal reorg testing.
@ -435,6 +435,26 @@ func darksideRawRequest(method string, params []json.RawMessage) (json.RawMessag
state.incomingTransactions = append(state.incomingTransactions, txBytes)
return []byte(hex.EncodeToString(tx.GetDisplayHash())), nil
case "getrawmempool":
reply := make([]string, 0)
addTxToReply := func(txBytes []byte) {
ctx := parser.NewTransaction()
ctx.ParseFromSlice(txBytes)
reply = append(reply, hex.EncodeToString(ctx.GetDisplayHash()))
}
for _, blockBytes := range state.stagedBlocks {
block := parser.NewBlock()
block.ParseFromSlice(blockBytes)
for _, tx := range block.Transactions() {
addTxToReply(tx.Bytes())
}
}
for _, tx := range state.stagedTransactions {
addTxToReply(tx.bytes)
}
return json.Marshal(reply)
default:
return nil, errors.New("there was an attempt to call an unsupported RPC")
}
@ -444,34 +464,64 @@ func darksideGetRawTransaction(params []json.RawMessage) (json.RawMessage, error
if !state.resetted {
return nil, errors.New("please call Reset first")
}
// remove the double-quotes from the beginning and end of the hex txid string
txbytes, err := hex.DecodeString(string(params[0][1 : 1+64]))
var rawtx string
err := json.Unmarshal(params[0], &rawtx)
if err != nil {
return nil, errors.New("failed to parse getrawtransaction JSON")
}
txid, err := hex.DecodeString(rawtx)
if err != nil {
return nil, errors.New("-9: " + err.Error())
}
marshalReply := func(tx *parser.Transaction, height int) []byte {
switch string(params[1]) {
case "0":
txJSON, _ := json.Marshal(hex.EncodeToString(tx.Bytes()))
return txJSON
case "1":
reply := struct {
Hex string
Height int
}{hex.EncodeToString(tx.Bytes()), height}
txVerboseJSON, _ := json.Marshal(reply)
return txVerboseJSON
default:
Log.Fatal("darkside only recognizes verbose 0 or 1")
return nil
}
}
// Linear search for the tx, somewhat inefficient but this is test code
// and there aren't many blocks. If this becomes a performance problem,
// we can maintain a map of transactions indexed by txid.
for _, b := range state.activeBlocks {
findTxInBlocks := func(blocks [][]byte) json.RawMessage {
for _, b := range blocks {
block := parser.NewBlock()
rest, err := block.ParseFromSlice(b)
if err != nil {
// this would be strange; we've already parsed this block
return nil, errors.New("-9: " + err.Error())
}
if len(rest) != 0 {
return nil, errors.New("-9: block serialization is too long")
}
_, _ = block.ParseFromSlice(b)
for _, tx := range block.Transactions() {
if bytes.Equal(tx.GetDisplayHash(), txbytes) {
reply := struct {
Hex string `json:"hex"`
Height int `json:"height"`
}{hex.EncodeToString(tx.Bytes()), block.GetHeight()}
return json.Marshal(reply)
if bytes.Equal(tx.GetDisplayHash(), txid) {
return marshalReply(tx, block.GetHeight())
}
}
}
return nil
}
// Search for the transaction (by txid) in the 3 places it could be.
reply := findTxInBlocks(state.activeBlocks)
if reply != nil {
return reply, nil
}
reply = findTxInBlocks(state.stagedBlocks)
if reply != nil {
return reply, nil
}
for _, stx := range state.stagedTransactions {
tx := parser.NewTransaction()
_, _ = tx.ParseFromSlice(stx.bytes)
if bytes.Equal(tx.GetDisplayHash(), txid) {
return marshalReply(tx, 0), nil
}
}
return nil, errors.New("-5: No information available about transaction")
}

View File

@ -339,6 +339,16 @@ block files. The sochain block explorer makes it easy to obtain the raw
transaction hex, by viewing the transaction (example), clicking “Raw Data”, then
copying the “tx_hex” field.
### Simulating the mempool
The `GetMempoolTx` gRPC will return staged transactions that are either within
staged blocks or that have been staged separately. Here is an example:
```
grpcurl -plaintext -d '{"saplingActivation": 663150,"branchID": "bad", "chainName":"x"}' localhost:9067 cash.z.wallet.sdk.rpc.DarksideStreamer/Reset
grpcurl -plaintext -d '{"url": "https://raw.githubusercontent.com/zcash-hackworks/darksidewalletd-test-data/master/tx-incoming/blocks.txt"}' localhost:9067 cash.z.wallet.sdk.rpc.DarksideStreamer/StageBlocks
grpcurl -plaintext -d '{"txid":["qg=="]}' localhost:9067 cash.z.wallet.sdk.rpc.CompactTxStreamer/GetMempoolTx
```
## Use cases
Check out some of the potential security test cases here: [wallet <->

View File

@ -67,11 +67,8 @@ func TestMain(m *testing.M) {
defer testBlocks.Close()
scan := bufio.NewScanner(testBlocks)
for scan.Scan() { // each line (block)
block := scan.Bytes()
// Enclose the hex string in quotes (to make it json, to match what's
// returned by the RPC)
block = []byte("\"" + string(block) + "\"")
blocks = append(blocks, block)
blockJSON, _ := json.Marshal(scan.Text())
blocks = append(blocks, blockJSON)
}
testData, err := os.Open("../testdata/zip243_raw_tx")
@ -242,8 +239,14 @@ func zcashdrpcStub(method string, params []json.RawMessage) (json.RawMessage, er
case "getrawtransaction":
switch step {
case 2:
txstr := hex.EncodeToString(rawTxData[0])
return []byte("{\"hex\": \"" + txstr + "\", \"height\": 1234567}"), nil
tx := &struct {
Hex string `json:"hex"`
Height int `json:"height"`
}{
Hex: hex.EncodeToString(rawTxData[0]),
Height: 1234567,
}
return json.Marshal(tx)
case 4:
// empty return value, should be okay
return []byte(""), errors.New("-5: test getrawtransaction error")
@ -500,3 +503,58 @@ func TestNewZRPCFromConf(t *testing.T) {
t.Fatal("NewZRPCFromClient unexpected success")
}
}
func TestMempoolFilter(t *testing.T) {
txidlist := []string{
"2e819d0bab5c819dc7d5f92d1bfb4127ce321daf847f6602",
"29e594c312eee49bc2c9ad37367ba58f857c4a7387ec9715",
"d4d090e60bf9141c6573f0598b84cc1f9817543e55a4d84d",
"d4714779c6dd32a72077bd79d4a70cb2153b552d7addec15",
"9839c1d4deca000656caff57c1f720f4fbd114b52239edde",
"ce5a28854a509ab309faa433542e73414fef6e903a3d52f5",
}
exclude := []string{
"98aa", // common prefix (98) but no match
"19", // no match
"29", // one match (should not appear)
"d4", // 2 matches (both should appear in result)
"ce5a28854a509ab309faa433542e73414fef6e903a3d52f5", // exact match
"ce5a28854a509ab309faa433542e73414fef6e903a3d52f500", // extra stuff ignored
}
expected := []string{
"2e819d0bab5c819dc7d5f92d1bfb4127ce321daf847f6602",
"9839c1d4deca000656caff57c1f720f4fbd114b52239edde",
"d4714779c6dd32a72077bd79d4a70cb2153b552d7addec15",
"d4d090e60bf9141c6573f0598b84cc1f9817543e55a4d84d",
}
actual := MempoolFilter(txidlist, exclude)
if len(actual) != len(expected) {
t.Fatal("mempool: wrong number of filter results")
}
for i := 0; i < len(actual); i++ {
if actual[i] != expected[i] {
t.Fatal(fmt.Sprintf("mempool: expected: %s actual: %s",
expected[i], actual[i]))
}
}
// If the exclude list is empty, return the entire mempool.
actual = MempoolFilter(txidlist, []string{})
expected = []string{
"29e594c312eee49bc2c9ad37367ba58f857c4a7387ec9715",
"2e819d0bab5c819dc7d5f92d1bfb4127ce321daf847f6602",
"9839c1d4deca000656caff57c1f720f4fbd114b52239edde",
"ce5a28854a509ab309faa433542e73414fef6e903a3d52f5",
"d4714779c6dd32a72077bd79d4a70cb2153b552d7addec15",
"d4d090e60bf9141c6573f0598b84cc1f9817543e55a4d84d",
}
if len(actual) != len(expected) {
t.Fatal("mempool: wrong number of filter results")
}
for i := 0; i < len(actual); i++ {
if actual[i] != expected[i] {
t.Fatal(fmt.Sprintf("mempool: expected: %s actual: %s",
expected[i], actual[i]))
}
}
}

View File

@ -12,12 +12,14 @@ import (
"errors"
"io"
"regexp"
"sort"
"strconv"
"strings"
"sync/atomic"
"time"
"github.com/zcash/lightwalletd/common"
"github.com/zcash/lightwalletd/parser"
"github.com/zcash/lightwalletd/walletrpc"
)
@ -63,11 +65,16 @@ func (s *lwdStreamer) GetTaddressTxids(addressBlockFilter *walletrpc.Transparent
}
params := make([]json.RawMessage, 1)
st := "{\"addresses\": [\"" + addressBlockFilter.Address + "\"]," +
"\"start\": " + strconv.FormatUint(addressBlockFilter.Range.Start.Height, 10) +
", \"end\": " + strconv.FormatUint(addressBlockFilter.Range.End.Height, 10) + "}"
params[0] = json.RawMessage(st)
request := &struct {
Addresses []string `json:"addresses"`
Start uint64 `json:"start"`
End uint64 `json:"end"`
}{
Addresses: []string{addressBlockFilter.Address},
Start: addressBlockFilter.Range.Start.Height,
End: addressBlockFilter.Range.End.Height,
}
params[0], _ = json.Marshal(request)
result, rpcErr := common.RawRequest("getaddresstxids", params)
@ -91,10 +98,7 @@ func (s *lwdStreamer) GetTaddressTxids(addressBlockFilter *walletrpc.Transparent
txid, _ := hex.DecodeString(txidstr)
// Txid is read as a string, which is in big-endian order. But when converting
// to bytes, it should be little-endian
for left, right := 0, len(txid)-1; left < right; left, right = left+1, right-1 {
txid[left], txid[right] = txid[right], txid[left]
}
tx, err := s.GetTransaction(timeout, &walletrpc.TxFilter{Hash: txid})
tx, err := s.GetTransaction(timeout, &walletrpc.TxFilter{Hash: common.Reverse(txid)})
if err != nil {
common.Log.Errorf("GetTransaction error: %s", err.Error())
return err
@ -154,17 +158,15 @@ func (s *lwdStreamer) GetBlockRange(span *walletrpc.BlockRange, resp walletrpc.C
// by the zcashd 'getrawtransaction' RPC.
func (s *lwdStreamer) GetTransaction(ctx context.Context, txf *walletrpc.TxFilter) (*walletrpc.RawTransaction, error) {
if txf.Hash != nil {
txid := txf.Hash
for left, right := 0, len(txid)-1; left < right; left, right = left+1, right-1 {
txid[left], txid[right] = txid[right], txid[left]
leHashStringJSON, err := json.Marshal(hex.EncodeToString(txf.Hash))
if err != nil {
common.Log.Errorf("GetTransaction: cannot encode txid: %s", err.Error())
return nil, err
}
leHashString := hex.EncodeToString(txid)
params := []json.RawMessage{
json.RawMessage("\"" + leHashString + "\""),
leHashStringJSON,
json.RawMessage("1"),
}
result, rpcErr := common.RawRequest("getrawtransaction", params)
// For some reason, the error responses are not JSON
@ -172,11 +174,12 @@ func (s *lwdStreamer) GetTransaction(ctx context.Context, txf *walletrpc.TxFilte
common.Log.Errorf("GetTransaction error: %s", rpcErr.Error())
return nil, errors.New((strings.Split(rpcErr.Error(), ":"))[0])
}
// Many other fields are returned, but we need only these two.
var txinfo struct {
Hex string
Height int
}
err := json.Unmarshal(result, &txinfo)
err = json.Unmarshal(result, &txinfo)
if err != nil {
return nil, err
}
@ -229,8 +232,8 @@ func (s *lwdStreamer) SendTransaction(ctx context.Context, rawtx *walletrpc.RawT
// Construct raw JSON-RPC params
params := make([]json.RawMessage, 1)
txHexString := hex.EncodeToString(rawtx.Data)
params[0] = json.RawMessage("\"" + txHexString + "\"")
txJSON, _ := json.Marshal(hex.EncodeToString(rawtx.Data))
params[0] = txJSON
result, rpcErr := common.RawRequest("sendrawtransaction", params)
var err error
@ -261,18 +264,13 @@ func (s *lwdStreamer) SendTransaction(ctx context.Context, rawtx *walletrpc.RawT
func getTaddressBalanceZcashdRpc(addressList []string) (*walletrpc.Balance, error) {
params := make([]json.RawMessage, 1)
addrList := "{\"addresses\":["
notFirst := false
for _, addr := range addressList {
if notFirst {
addrList += ","
addrList := &struct {
Addresses []string `json:"addresses"`
}{
Addresses: addressList,
}
addrList += "\"" + addr + "\""
notFirst = true
}
addrList += "]}"
params[0], _ = json.Marshal(addrList)
params[0] = json.RawMessage(addrList)
result, rpcErr := common.RawRequest("getaddressbalance", params)
if rpcErr != nil {
return &walletrpc.Balance{}, rpcErr
@ -313,6 +311,132 @@ func (s *lwdStreamer) GetTaddressBalanceStream(addresses walletrpc.CompactTxStre
return nil
}
// Key is 32-byte txid (as a 64-character string), data is pointer to compact tx.
var mempoolMap *map[string]*walletrpc.CompactTx
var mempoolList []string
// Last time we pulled a copy of the mempool from zcashd.
var lastMempool time.Time
func (s *lwdStreamer) GetMempoolTx(exclude *walletrpc.Exclude, resp walletrpc.CompactTxStreamer_GetMempoolTxServer) error {
if time.Now().Sub(lastMempool).Seconds() >= 2 {
lastMempool = time.Now()
// Refresh our copy of the mempool.
newmempoolMap := make(map[string]*walletrpc.CompactTx)
params := make([]json.RawMessage, 0)
result, rpcErr := common.RawRequest("getrawmempool", params)
if rpcErr != nil {
return rpcErr
}
err := json.Unmarshal(result, &mempoolList)
if err != nil {
return err
}
if mempoolMap == nil {
mempoolMap = &newmempoolMap
}
for _, txidstr := range mempoolList {
if ctx, ok := (*mempoolMap)[txidstr]; ok {
// This ctx has already been fetched, copy pointer to it.
newmempoolMap[txidstr] = ctx
continue
}
txidJSON, _ := json.Marshal(txidstr)
// The "0" is because we only need the raw hex, which is returned as
// just a hex string, and not even a json string (with quotes).
params := []json.RawMessage{txidJSON, json.RawMessage("0")}
result, rpcErr := common.RawRequest("getrawtransaction", params)
if rpcErr != nil {
// Not an error; mempool transactions can disappear
common.Log.Errorf("GetTransaction error: %s", rpcErr.Error())
continue
}
// strip the quotes
var txStr string
err := json.Unmarshal(result, &txStr)
if err != nil {
return err
}
// conver to binary
txBytes, err := hex.DecodeString(txStr)
if err != nil {
return err
}
tx := parser.NewTransaction()
txdata, err := tx.ParseFromSlice(txBytes)
if len(txdata) > 0 {
return errors.New("extra data deserializing transaction")
}
newmempoolMap[txidstr] = &walletrpc.CompactTx{}
if tx.HasSaplingElements() {
newmempoolMap[txidstr] = tx.ToCompact( /* height */ 0)
}
}
mempoolMap = &newmempoolMap
}
excludeHex := make([]string, len(exclude.Txid))
for i := 0; i < len(exclude.Txid); i++ {
excludeHex[i] = hex.EncodeToString(common.Reverse(exclude.Txid[i]))
}
for _, txid := range MempoolFilter(mempoolList, excludeHex) {
tx := (*mempoolMap)[txid]
if len(tx.Hash) > 0 {
err := resp.Send(tx)
if err != nil {
return err
}
}
}
return nil
}
// Return the subset of items that aren't excluded, but
// if more than one item matches an exclude entry, return
// all those items.
func MempoolFilter(items, exclude []string) []string {
sort.Slice(items, func(i, j int) bool {
return items[i] < items[j]
})
sort.Slice(exclude, func(i, j int) bool {
return exclude[i] < exclude[j]
})
// Determine how many items match each exclude item.
nmatches := make([]int, len(exclude))
// is the exclude string less than the item string?
lessthan := func(e, i string) bool {
l := len(e)
if l > len(i) {
l = len(i)
}
return e < i[0:l]
}
ei := 0
for _, item := range items {
for ei < len(exclude) && lessthan(exclude[ei], item) {
ei++
}
match := ei < len(exclude) && strings.HasPrefix(item, exclude[ei])
if match {
nmatches[ei]++
}
}
// Add each item that isn't uniquely excluded to the results.
tosend := make([]string, 0)
ei = 0
for _, item := range items {
for ei < len(exclude) && lessthan(exclude[ei], item) {
ei++
}
match := ei < len(exclude) && strings.HasPrefix(item, exclude[ei])
if !match || nmatches[ei] > 1 {
tosend = append(tosend, item)
}
}
return tosend
}
// This rpc is used only for testing.
var concurrent int64
@ -339,6 +463,8 @@ func (s *DarksideStreamer) Reset(ctx context.Context, ms *walletrpc.DarksideMeta
if err != nil {
return nil, err
}
mempoolMap = nil
mempoolList = nil
return &walletrpc.Empty{}, nil
}

View File

@ -4,8 +4,8 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.22.0
// protoc v3.11.4
// protoc-gen-go v1.25.0
// protoc v3.11.0
// source: darkside.proto
package walletrpc

View File

@ -809,6 +809,53 @@ func (x *Balance) GetValueZat() int64 {
return 0
}
type Exclude struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Txid [][]byte `protobuf:"bytes,1,rep,name=txid,proto3" json:"txid,omitempty"`
}
func (x *Exclude) Reset() {
*x = Exclude{}
if protoimpl.UnsafeEnabled {
mi := &file_service_proto_msgTypes[14]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *Exclude) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*Exclude) ProtoMessage() {}
func (x *Exclude) ProtoReflect() protoreflect.Message {
mi := &file_service_proto_msgTypes[14]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use Exclude.ProtoReflect.Descriptor instead.
func (*Exclude) Descriptor() ([]byte, []int) {
return file_service_proto_rawDescGZIP(), []int{14}
}
func (x *Exclude) GetTxid() [][]byte {
if x != nil {
return x.Txid
}
return nil
}
var File_service_proto protoreflect.FileDescriptor
var file_service_proto_rawDesc = []byte{
@ -881,68 +928,75 @@ var file_service_proto_rawDesc = []byte{
0x73, 0x73, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x09, 0x61, 0x64, 0x64, 0x72,
0x65, 0x73, 0x73, 0x65, 0x73, 0x22, 0x25, 0x0a, 0x07, 0x42, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65,
0x12, 0x1a, 0x0a, 0x08, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x5a, 0x61, 0x74, 0x18, 0x01, 0x20, 0x01,
0x28, 0x03, 0x52, 0x08, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x5a, 0x61, 0x74, 0x32, 0xab, 0x07, 0x0a,
0x11, 0x43, 0x6f, 0x6d, 0x70, 0x61, 0x63, 0x74, 0x54, 0x78, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d,
0x65, 0x72, 0x12, 0x54, 0x0a, 0x0e, 0x47, 0x65, 0x74, 0x4c, 0x61, 0x74, 0x65, 0x73, 0x74, 0x42,
0x6c, 0x6f, 0x63, 0x6b, 0x12, 0x20, 0x2e, 0x63, 0x61, 0x73, 0x68, 0x2e, 0x7a, 0x2e, 0x77, 0x61,
0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x73, 0x64, 0x6b, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x43, 0x68, 0x61,
0x69, 0x6e, 0x53, 0x70, 0x65, 0x63, 0x1a, 0x1e, 0x2e, 0x63, 0x61, 0x73, 0x68, 0x2e, 0x7a, 0x2e,
0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x73, 0x64, 0x6b, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x42,
0x6c, 0x6f, 0x63, 0x6b, 0x49, 0x44, 0x22, 0x00, 0x12, 0x51, 0x0a, 0x08, 0x47, 0x65, 0x74, 0x42,
0x6c, 0x6f, 0x63, 0x6b, 0x12, 0x1e, 0x2e, 0x63, 0x61, 0x73, 0x68, 0x2e, 0x7a, 0x2e, 0x77, 0x61,
0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x73, 0x64, 0x6b, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x42, 0x6c, 0x6f,
0x63, 0x6b, 0x49, 0x44, 0x1a, 0x23, 0x2e, 0x63, 0x61, 0x73, 0x68, 0x2e, 0x7a, 0x2e, 0x77, 0x61,
0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x73, 0x64, 0x6b, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x43, 0x6f, 0x6d,
0x70, 0x61, 0x63, 0x74, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x22, 0x00, 0x12, 0x5b, 0x0a, 0x0d, 0x47,
0x65, 0x74, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x52, 0x61, 0x6e, 0x67, 0x65, 0x12, 0x21, 0x2e, 0x63,
0x61, 0x73, 0x68, 0x2e, 0x7a, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x73, 0x64, 0x6b,
0x2e, 0x72, 0x70, 0x63, 0x2e, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x52, 0x61, 0x6e, 0x67, 0x65, 0x1a,
0x23, 0x2e, 0x63, 0x61, 0x73, 0x68, 0x2e, 0x7a, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e,
0x73, 0x64, 0x6b, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x43, 0x6f, 0x6d, 0x70, 0x61, 0x63, 0x74, 0x42,
0x6c, 0x6f, 0x63, 0x6b, 0x22, 0x00, 0x30, 0x01, 0x12, 0x5a, 0x0a, 0x0e, 0x47, 0x65, 0x74, 0x54,
0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1f, 0x2e, 0x63, 0x61, 0x73,
0x68, 0x2e, 0x7a, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x73, 0x64, 0x6b, 0x2e, 0x72,
0x70, 0x63, 0x2e, 0x54, 0x78, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x1a, 0x25, 0x2e, 0x63, 0x61,
0x28, 0x03, 0x52, 0x08, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x5a, 0x61, 0x74, 0x22, 0x1d, 0x0a, 0x07,
0x45, 0x78, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x78, 0x69, 0x64, 0x18,
0x01, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x04, 0x74, 0x78, 0x69, 0x64, 0x32, 0x81, 0x08, 0x0a, 0x11,
0x43, 0x6f, 0x6d, 0x70, 0x61, 0x63, 0x74, 0x54, 0x78, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x65,
0x72, 0x12, 0x54, 0x0a, 0x0e, 0x47, 0x65, 0x74, 0x4c, 0x61, 0x74, 0x65, 0x73, 0x74, 0x42, 0x6c,
0x6f, 0x63, 0x6b, 0x12, 0x20, 0x2e, 0x63, 0x61, 0x73, 0x68, 0x2e, 0x7a, 0x2e, 0x77, 0x61, 0x6c,
0x6c, 0x65, 0x74, 0x2e, 0x73, 0x64, 0x6b, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x43, 0x68, 0x61, 0x69,
0x6e, 0x53, 0x70, 0x65, 0x63, 0x1a, 0x1e, 0x2e, 0x63, 0x61, 0x73, 0x68, 0x2e, 0x7a, 0x2e, 0x77,
0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x73, 0x64, 0x6b, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x42, 0x6c,
0x6f, 0x63, 0x6b, 0x49, 0x44, 0x22, 0x00, 0x12, 0x51, 0x0a, 0x08, 0x47, 0x65, 0x74, 0x42, 0x6c,
0x6f, 0x63, 0x6b, 0x12, 0x1e, 0x2e, 0x63, 0x61, 0x73, 0x68, 0x2e, 0x7a, 0x2e, 0x77, 0x61, 0x6c,
0x6c, 0x65, 0x74, 0x2e, 0x73, 0x64, 0x6b, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x42, 0x6c, 0x6f, 0x63,
0x6b, 0x49, 0x44, 0x1a, 0x23, 0x2e, 0x63, 0x61, 0x73, 0x68, 0x2e, 0x7a, 0x2e, 0x77, 0x61, 0x6c,
0x6c, 0x65, 0x74, 0x2e, 0x73, 0x64, 0x6b, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x43, 0x6f, 0x6d, 0x70,
0x61, 0x63, 0x74, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x22, 0x00, 0x12, 0x5b, 0x0a, 0x0d, 0x47, 0x65,
0x74, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x52, 0x61, 0x6e, 0x67, 0x65, 0x12, 0x21, 0x2e, 0x63, 0x61,
0x73, 0x68, 0x2e, 0x7a, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x73, 0x64, 0x6b, 0x2e,
0x72, 0x70, 0x63, 0x2e, 0x52, 0x61, 0x77, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69,
0x6f, 0x6e, 0x22, 0x00, 0x12, 0x5f, 0x0a, 0x0f, 0x53, 0x65, 0x6e, 0x64, 0x54, 0x72, 0x61, 0x6e,
0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x25, 0x2e, 0x63, 0x61, 0x73, 0x68, 0x2e, 0x7a,
0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x73, 0x64, 0x6b, 0x2e, 0x72, 0x70, 0x63, 0x2e,
0x52, 0x61, 0x77, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x1a, 0x23,
0x72, 0x70, 0x63, 0x2e, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x52, 0x61, 0x6e, 0x67, 0x65, 0x1a, 0x23,
0x2e, 0x63, 0x61, 0x73, 0x68, 0x2e, 0x7a, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x73,
0x64, 0x6b, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x65, 0x6e, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f,
0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x73, 0x0a, 0x10, 0x47, 0x65, 0x74, 0x54, 0x61, 0x64, 0x64,
0x72, 0x65, 0x73, 0x73, 0x54, 0x78, 0x69, 0x64, 0x73, 0x12, 0x34, 0x2e, 0x63, 0x61, 0x73, 0x68,
0x64, 0x6b, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x43, 0x6f, 0x6d, 0x70, 0x61, 0x63, 0x74, 0x42, 0x6c,
0x6f, 0x63, 0x6b, 0x22, 0x00, 0x30, 0x01, 0x12, 0x5a, 0x0a, 0x0e, 0x47, 0x65, 0x74, 0x54, 0x72,
0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1f, 0x2e, 0x63, 0x61, 0x73, 0x68,
0x2e, 0x7a, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x73, 0x64, 0x6b, 0x2e, 0x72, 0x70,
0x63, 0x2e, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x41, 0x64, 0x64,
0x72, 0x65, 0x73, 0x73, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x1a,
0x25, 0x2e, 0x63, 0x61, 0x73, 0x68, 0x2e, 0x7a, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e,
0x73, 0x64, 0x6b, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x52, 0x61, 0x77, 0x54, 0x72, 0x61, 0x6e, 0x73,
0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x00, 0x30, 0x01, 0x12, 0x5a, 0x0a, 0x12, 0x47, 0x65,
0x74, 0x54, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x42, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65,
0x12, 0x22, 0x2e, 0x63, 0x61, 0x73, 0x68, 0x2e, 0x7a, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74,
0x2e, 0x73, 0x64, 0x6b, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73,
0x4c, 0x69, 0x73, 0x74, 0x1a, 0x1e, 0x2e, 0x63, 0x61, 0x73, 0x68, 0x2e, 0x7a, 0x2e, 0x77, 0x61,
0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x73, 0x64, 0x6b, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x42, 0x61, 0x6c,
0x61, 0x6e, 0x63, 0x65, 0x22, 0x00, 0x12, 0x5e, 0x0a, 0x18, 0x47, 0x65, 0x74, 0x54, 0x61, 0x64,
0x64, 0x72, 0x65, 0x73, 0x73, 0x42, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x53, 0x74, 0x72, 0x65,
0x61, 0x6d, 0x12, 0x1e, 0x2e, 0x63, 0x61, 0x73, 0x68, 0x2e, 0x7a, 0x2e, 0x77, 0x61, 0x6c, 0x6c,
0x65, 0x74, 0x2e, 0x73, 0x64, 0x6b, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x41, 0x64, 0x64, 0x72, 0x65,
0x73, 0x73, 0x1a, 0x1e, 0x2e, 0x63, 0x61, 0x73, 0x68, 0x2e, 0x7a, 0x2e, 0x77, 0x61, 0x6c, 0x6c,
0x65, 0x74, 0x2e, 0x73, 0x64, 0x6b, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x42, 0x61, 0x6c, 0x61, 0x6e,
0x63, 0x65, 0x22, 0x00, 0x28, 0x01, 0x12, 0x52, 0x0a, 0x0d, 0x47, 0x65, 0x74, 0x4c, 0x69, 0x67,
0x68, 0x74, 0x64, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x1c, 0x2e, 0x63, 0x61, 0x73, 0x68, 0x2e, 0x7a,
0x63, 0x2e, 0x54, 0x78, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x1a, 0x25, 0x2e, 0x63, 0x61, 0x73,
0x68, 0x2e, 0x7a, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x73, 0x64, 0x6b, 0x2e, 0x72,
0x70, 0x63, 0x2e, 0x52, 0x61, 0x77, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f,
0x6e, 0x22, 0x00, 0x12, 0x5f, 0x0a, 0x0f, 0x53, 0x65, 0x6e, 0x64, 0x54, 0x72, 0x61, 0x6e, 0x73,
0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x25, 0x2e, 0x63, 0x61, 0x73, 0x68, 0x2e, 0x7a, 0x2e,
0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x73, 0x64, 0x6b, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x52,
0x61, 0x77, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x1a, 0x23, 0x2e,
0x63, 0x61, 0x73, 0x68, 0x2e, 0x7a, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x73, 0x64,
0x6b, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x65, 0x6e, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e,
0x73, 0x65, 0x22, 0x00, 0x12, 0x73, 0x0a, 0x10, 0x47, 0x65, 0x74, 0x54, 0x61, 0x64, 0x64, 0x72,
0x65, 0x73, 0x73, 0x54, 0x78, 0x69, 0x64, 0x73, 0x12, 0x34, 0x2e, 0x63, 0x61, 0x73, 0x68, 0x2e,
0x7a, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x73, 0x64, 0x6b, 0x2e, 0x72, 0x70, 0x63,
0x2e, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x41, 0x64, 0x64, 0x72,
0x65, 0x73, 0x73, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x1a, 0x25,
0x2e, 0x63, 0x61, 0x73, 0x68, 0x2e, 0x7a, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x73,
0x64, 0x6b, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x52, 0x61, 0x77, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61,
0x63, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x00, 0x30, 0x01, 0x12, 0x5a, 0x0a, 0x12, 0x47, 0x65, 0x74,
0x54, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x42, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x12,
0x22, 0x2e, 0x63, 0x61, 0x73, 0x68, 0x2e, 0x7a, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e,
0x73, 0x64, 0x6b, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x4c,
0x69, 0x73, 0x74, 0x1a, 0x1e, 0x2e, 0x63, 0x61, 0x73, 0x68, 0x2e, 0x7a, 0x2e, 0x77, 0x61, 0x6c,
0x6c, 0x65, 0x74, 0x2e, 0x73, 0x64, 0x6b, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x42, 0x61, 0x6c, 0x61,
0x6e, 0x63, 0x65, 0x22, 0x00, 0x12, 0x5e, 0x0a, 0x18, 0x47, 0x65, 0x74, 0x54, 0x61, 0x64, 0x64,
0x72, 0x65, 0x73, 0x73, 0x42, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x53, 0x74, 0x72, 0x65, 0x61,
0x6d, 0x12, 0x1e, 0x2e, 0x63, 0x61, 0x73, 0x68, 0x2e, 0x7a, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65,
0x74, 0x2e, 0x73, 0x64, 0x6b, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73,
0x73, 0x1a, 0x1e, 0x2e, 0x63, 0x61, 0x73, 0x68, 0x2e, 0x7a, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65,
0x74, 0x2e, 0x73, 0x64, 0x6b, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x42, 0x61, 0x6c, 0x61, 0x6e, 0x63,
0x65, 0x22, 0x00, 0x28, 0x01, 0x12, 0x54, 0x0a, 0x0c, 0x47, 0x65, 0x74, 0x4d, 0x65, 0x6d, 0x70,
0x6f, 0x6f, 0x6c, 0x54, 0x78, 0x12, 0x1e, 0x2e, 0x63, 0x61, 0x73, 0x68, 0x2e, 0x7a, 0x2e, 0x77,
0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x73, 0x64, 0x6b, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x45, 0x78,
0x63, 0x6c, 0x75, 0x64, 0x65, 0x1a, 0x20, 0x2e, 0x63, 0x61, 0x73, 0x68, 0x2e, 0x7a, 0x2e, 0x77,
0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x73, 0x64, 0x6b, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x43, 0x6f,
0x6d, 0x70, 0x61, 0x63, 0x74, 0x54, 0x78, 0x22, 0x00, 0x30, 0x01, 0x12, 0x52, 0x0a, 0x0d, 0x47,
0x65, 0x74, 0x4c, 0x69, 0x67, 0x68, 0x74, 0x64, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x1c, 0x2e, 0x63,
0x61, 0x73, 0x68, 0x2e, 0x7a, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x73, 0x64, 0x6b,
0x2e, 0x72, 0x70, 0x63, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x21, 0x2e, 0x63, 0x61, 0x73,
0x68, 0x2e, 0x7a, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x73, 0x64, 0x6b, 0x2e, 0x72,
0x70, 0x63, 0x2e, 0x4c, 0x69, 0x67, 0x68, 0x74, 0x64, 0x49, 0x6e, 0x66, 0x6f, 0x22, 0x00, 0x12,
0x4e, 0x0a, 0x04, 0x50, 0x69, 0x6e, 0x67, 0x12, 0x1f, 0x2e, 0x63, 0x61, 0x73, 0x68, 0x2e, 0x7a,
0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x73, 0x64, 0x6b, 0x2e, 0x72, 0x70, 0x63, 0x2e,
0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x21, 0x2e, 0x63, 0x61, 0x73, 0x68, 0x2e, 0x7a, 0x2e, 0x77,
0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x73, 0x64, 0x6b, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x4c, 0x69,
0x67, 0x68, 0x74, 0x64, 0x49, 0x6e, 0x66, 0x6f, 0x22, 0x00, 0x12, 0x4e, 0x0a, 0x04, 0x50, 0x69,
0x6e, 0x67, 0x12, 0x1f, 0x2e, 0x63, 0x61, 0x73, 0x68, 0x2e, 0x7a, 0x2e, 0x77, 0x61, 0x6c, 0x6c,
0x65, 0x74, 0x2e, 0x73, 0x64, 0x6b, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x44, 0x75, 0x72, 0x61, 0x74,
0x69, 0x6f, 0x6e, 0x1a, 0x23, 0x2e, 0x63, 0x61, 0x73, 0x68, 0x2e, 0x7a, 0x2e, 0x77, 0x61, 0x6c,
0x6c, 0x65, 0x74, 0x2e, 0x73, 0x64, 0x6b, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x50, 0x69, 0x6e, 0x67,
0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x42, 0x10, 0x5a, 0x0b, 0x2e, 0x3b,
0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x72, 0x70, 0x63, 0xba, 0x02, 0x00, 0x62, 0x06, 0x70, 0x72,
0x6f, 0x74, 0x6f, 0x33,
0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x1a, 0x23, 0x2e, 0x63, 0x61, 0x73, 0x68, 0x2e,
0x7a, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x73, 0x64, 0x6b, 0x2e, 0x72, 0x70, 0x63,
0x2e, 0x50, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x42,
0x10, 0x5a, 0x0b, 0x2e, 0x3b, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x72, 0x70, 0x63, 0xba, 0x02,
0x00, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
}
var (
@ -957,7 +1011,7 @@ func file_service_proto_rawDescGZIP() []byte {
return file_service_proto_rawDescData
}
var file_service_proto_msgTypes = make([]protoimpl.MessageInfo, 14)
var file_service_proto_msgTypes = make([]protoimpl.MessageInfo, 15)
var file_service_proto_goTypes = []interface{}{
(*BlockID)(nil), // 0: cash.z.wallet.sdk.rpc.BlockID
(*BlockRange)(nil), // 1: cash.z.wallet.sdk.rpc.BlockRange
@ -973,7 +1027,9 @@ var file_service_proto_goTypes = []interface{}{
(*Address)(nil), // 11: cash.z.wallet.sdk.rpc.Address
(*AddressList)(nil), // 12: cash.z.wallet.sdk.rpc.AddressList
(*Balance)(nil), // 13: cash.z.wallet.sdk.rpc.Balance
(*CompactBlock)(nil), // 14: cash.z.wallet.sdk.rpc.CompactBlock
(*Exclude)(nil), // 14: cash.z.wallet.sdk.rpc.Exclude
(*CompactBlock)(nil), // 15: cash.z.wallet.sdk.rpc.CompactBlock
(*CompactTx)(nil), // 16: cash.z.wallet.sdk.rpc.CompactTx
}
var file_service_proto_depIdxs = []int32{
0, // 0: cash.z.wallet.sdk.rpc.BlockRange.start:type_name -> cash.z.wallet.sdk.rpc.BlockID
@ -988,20 +1044,22 @@ var file_service_proto_depIdxs = []int32{
8, // 9: cash.z.wallet.sdk.rpc.CompactTxStreamer.GetTaddressTxids:input_type -> cash.z.wallet.sdk.rpc.TransparentAddressBlockFilter
12, // 10: cash.z.wallet.sdk.rpc.CompactTxStreamer.GetTaddressBalance:input_type -> cash.z.wallet.sdk.rpc.AddressList
11, // 11: cash.z.wallet.sdk.rpc.CompactTxStreamer.GetTaddressBalanceStream:input_type -> cash.z.wallet.sdk.rpc.Address
6, // 12: cash.z.wallet.sdk.rpc.CompactTxStreamer.GetLightdInfo:input_type -> cash.z.wallet.sdk.rpc.Empty
9, // 13: cash.z.wallet.sdk.rpc.CompactTxStreamer.Ping:input_type -> cash.z.wallet.sdk.rpc.Duration
0, // 14: cash.z.wallet.sdk.rpc.CompactTxStreamer.GetLatestBlock:output_type -> cash.z.wallet.sdk.rpc.BlockID
14, // 15: cash.z.wallet.sdk.rpc.CompactTxStreamer.GetBlock:output_type -> cash.z.wallet.sdk.rpc.CompactBlock
14, // 16: cash.z.wallet.sdk.rpc.CompactTxStreamer.GetBlockRange:output_type -> cash.z.wallet.sdk.rpc.CompactBlock
3, // 17: cash.z.wallet.sdk.rpc.CompactTxStreamer.GetTransaction:output_type -> cash.z.wallet.sdk.rpc.RawTransaction
4, // 18: cash.z.wallet.sdk.rpc.CompactTxStreamer.SendTransaction:output_type -> cash.z.wallet.sdk.rpc.SendResponse
3, // 19: cash.z.wallet.sdk.rpc.CompactTxStreamer.GetTaddressTxids:output_type -> cash.z.wallet.sdk.rpc.RawTransaction
13, // 20: cash.z.wallet.sdk.rpc.CompactTxStreamer.GetTaddressBalance:output_type -> cash.z.wallet.sdk.rpc.Balance
13, // 21: cash.z.wallet.sdk.rpc.CompactTxStreamer.GetTaddressBalanceStream:output_type -> cash.z.wallet.sdk.rpc.Balance
7, // 22: cash.z.wallet.sdk.rpc.CompactTxStreamer.GetLightdInfo:output_type -> cash.z.wallet.sdk.rpc.LightdInfo
10, // 23: cash.z.wallet.sdk.rpc.CompactTxStreamer.Ping:output_type -> cash.z.wallet.sdk.rpc.PingResponse
14, // [14:24] is the sub-list for method output_type
4, // [4:14] is the sub-list for method input_type
14, // 12: cash.z.wallet.sdk.rpc.CompactTxStreamer.GetMempoolTx:input_type -> cash.z.wallet.sdk.rpc.Exclude
6, // 13: cash.z.wallet.sdk.rpc.CompactTxStreamer.GetLightdInfo:input_type -> cash.z.wallet.sdk.rpc.Empty
9, // 14: cash.z.wallet.sdk.rpc.CompactTxStreamer.Ping:input_type -> cash.z.wallet.sdk.rpc.Duration
0, // 15: cash.z.wallet.sdk.rpc.CompactTxStreamer.GetLatestBlock:output_type -> cash.z.wallet.sdk.rpc.BlockID
15, // 16: cash.z.wallet.sdk.rpc.CompactTxStreamer.GetBlock:output_type -> cash.z.wallet.sdk.rpc.CompactBlock
15, // 17: cash.z.wallet.sdk.rpc.CompactTxStreamer.GetBlockRange:output_type -> cash.z.wallet.sdk.rpc.CompactBlock
3, // 18: cash.z.wallet.sdk.rpc.CompactTxStreamer.GetTransaction:output_type -> cash.z.wallet.sdk.rpc.RawTransaction
4, // 19: cash.z.wallet.sdk.rpc.CompactTxStreamer.SendTransaction:output_type -> cash.z.wallet.sdk.rpc.SendResponse
3, // 20: cash.z.wallet.sdk.rpc.CompactTxStreamer.GetTaddressTxids:output_type -> cash.z.wallet.sdk.rpc.RawTransaction
13, // 21: cash.z.wallet.sdk.rpc.CompactTxStreamer.GetTaddressBalance:output_type -> cash.z.wallet.sdk.rpc.Balance
13, // 22: cash.z.wallet.sdk.rpc.CompactTxStreamer.GetTaddressBalanceStream:output_type -> cash.z.wallet.sdk.rpc.Balance
16, // 23: cash.z.wallet.sdk.rpc.CompactTxStreamer.GetMempoolTx:output_type -> cash.z.wallet.sdk.rpc.CompactTx
7, // 24: cash.z.wallet.sdk.rpc.CompactTxStreamer.GetLightdInfo:output_type -> cash.z.wallet.sdk.rpc.LightdInfo
10, // 25: cash.z.wallet.sdk.rpc.CompactTxStreamer.Ping:output_type -> cash.z.wallet.sdk.rpc.PingResponse
15, // [15:26] is the sub-list for method output_type
4, // [4:15] is the sub-list for method input_type
4, // [4:4] is the sub-list for extension type_name
4, // [4:4] is the sub-list for extension extendee
0, // [0:4] is the sub-list for field type_name
@ -1182,6 +1240,18 @@ func file_service_proto_init() {
return nil
}
}
file_service_proto_msgTypes[14].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*Exclude); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
}
type x struct{}
out := protoimpl.TypeBuilder{
@ -1189,7 +1259,7 @@ func file_service_proto_init() {
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: file_service_proto_rawDesc,
NumEnums: 0,
NumMessages: 14,
NumMessages: 15,
NumExtensions: 0,
NumServices: 1,
},
@ -1229,6 +1299,7 @@ type CompactTxStreamerClient interface {
GetTaddressTxids(ctx context.Context, in *TransparentAddressBlockFilter, opts ...grpc.CallOption) (CompactTxStreamer_GetTaddressTxidsClient, error)
GetTaddressBalance(ctx context.Context, in *AddressList, opts ...grpc.CallOption) (*Balance, error)
GetTaddressBalanceStream(ctx context.Context, opts ...grpc.CallOption) (CompactTxStreamer_GetTaddressBalanceStreamClient, error)
GetMempoolTx(ctx context.Context, in *Exclude, opts ...grpc.CallOption) (CompactTxStreamer_GetMempoolTxClient, error)
// Return information about this lightwalletd instance and the blockchain
GetLightdInfo(ctx context.Context, in *Empty, opts ...grpc.CallOption) (*LightdInfo, error)
// Testing-only
@ -1386,6 +1457,38 @@ func (x *compactTxStreamerGetTaddressBalanceStreamClient) CloseAndRecv() (*Balan
return m, nil
}
func (c *compactTxStreamerClient) GetMempoolTx(ctx context.Context, in *Exclude, opts ...grpc.CallOption) (CompactTxStreamer_GetMempoolTxClient, error) {
stream, err := c.cc.NewStream(ctx, &_CompactTxStreamer_serviceDesc.Streams[3], "/cash.z.wallet.sdk.rpc.CompactTxStreamer/GetMempoolTx", opts...)
if err != nil {
return nil, err
}
x := &compactTxStreamerGetMempoolTxClient{stream}
if err := x.ClientStream.SendMsg(in); err != nil {
return nil, err
}
if err := x.ClientStream.CloseSend(); err != nil {
return nil, err
}
return x, nil
}
type CompactTxStreamer_GetMempoolTxClient interface {
Recv() (*CompactTx, error)
grpc.ClientStream
}
type compactTxStreamerGetMempoolTxClient struct {
grpc.ClientStream
}
func (x *compactTxStreamerGetMempoolTxClient) Recv() (*CompactTx, error) {
m := new(CompactTx)
if err := x.ClientStream.RecvMsg(m); err != nil {
return nil, err
}
return m, nil
}
func (c *compactTxStreamerClient) GetLightdInfo(ctx context.Context, in *Empty, opts ...grpc.CallOption) (*LightdInfo, error) {
out := new(LightdInfo)
err := c.cc.Invoke(ctx, "/cash.z.wallet.sdk.rpc.CompactTxStreamer/GetLightdInfo", in, out, opts...)
@ -1420,6 +1523,7 @@ type CompactTxStreamerServer interface {
GetTaddressTxids(*TransparentAddressBlockFilter, CompactTxStreamer_GetTaddressTxidsServer) error
GetTaddressBalance(context.Context, *AddressList) (*Balance, error)
GetTaddressBalanceStream(CompactTxStreamer_GetTaddressBalanceStreamServer) error
GetMempoolTx(*Exclude, CompactTxStreamer_GetMempoolTxServer) error
// Return information about this lightwalletd instance and the blockchain
GetLightdInfo(context.Context, *Empty) (*LightdInfo, error)
// Testing-only
@ -1454,6 +1558,9 @@ func (*UnimplementedCompactTxStreamerServer) GetTaddressBalance(context.Context,
func (*UnimplementedCompactTxStreamerServer) GetTaddressBalanceStream(CompactTxStreamer_GetTaddressBalanceStreamServer) error {
return status.Errorf(codes.Unimplemented, "method GetTaddressBalanceStream not implemented")
}
func (*UnimplementedCompactTxStreamerServer) GetMempoolTx(*Exclude, CompactTxStreamer_GetMempoolTxServer) error {
return status.Errorf(codes.Unimplemented, "method GetMempoolTx not implemented")
}
func (*UnimplementedCompactTxStreamerServer) GetLightdInfo(context.Context, *Empty) (*LightdInfo, error) {
return nil, status.Errorf(codes.Unimplemented, "method GetLightdInfo not implemented")
}
@ -1623,6 +1730,27 @@ func (x *compactTxStreamerGetTaddressBalanceStreamServer) Recv() (*Address, erro
return m, nil
}
func _CompactTxStreamer_GetMempoolTx_Handler(srv interface{}, stream grpc.ServerStream) error {
m := new(Exclude)
if err := stream.RecvMsg(m); err != nil {
return err
}
return srv.(CompactTxStreamerServer).GetMempoolTx(m, &compactTxStreamerGetMempoolTxServer{stream})
}
type CompactTxStreamer_GetMempoolTxServer interface {
Send(*CompactTx) error
grpc.ServerStream
}
type compactTxStreamerGetMempoolTxServer struct {
grpc.ServerStream
}
func (x *compactTxStreamerGetMempoolTxServer) Send(m *CompactTx) error {
return x.ServerStream.SendMsg(m)
}
func _CompactTxStreamer_GetLightdInfo_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(Empty)
if err := dec(in); err != nil {
@ -1708,6 +1836,11 @@ var _CompactTxStreamer_serviceDesc = grpc.ServiceDesc{
Handler: _CompactTxStreamer_GetTaddressBalanceStream_Handler,
ClientStreams: true,
},
{
StreamName: "GetMempoolTx",
Handler: _CompactTxStreamer_GetMempoolTx_Handler,
ServerStreams: true,
},
},
Metadata: "service.proto",
}

View File

@ -96,6 +96,10 @@ message Balance {
int64 valueZat = 1;
}
message Exclude {
repeated bytes txid = 1;
}
service CompactTxStreamer {
// Return the height of the tip of the best chain
rpc GetLatestBlock(ChainSpec) returns (BlockID) {}
@ -114,6 +118,17 @@ service CompactTxStreamer {
rpc GetTaddressBalance(AddressList) returns (Balance) {}
rpc GetTaddressBalanceStream(stream Address) returns (Balance) {}
// Return the compact transactions currently in the mempool; the results
// can be a few seconds out of date. If the Exclude list is empty, return
// all transactions; otherwise return all *except* those in the Exclude list
// (if any); this allows the client to avoid receiving transactions that it
// already has (from an earlier call to this rpc). The transaction IDs in the
// Exclude list can be shortened to any number of bytes to make the request
// more bandwidth-efficient; if two or more transactions in the mempool
// match a shortened txid, they are all sent (none is excluded). Transactions
// in the exclude list that don't exist in the mempool are ignored.
rpc GetMempoolTx(Exclude) returns (stream CompactTx) {}
// Return information about this lightwalletd instance and the blockchain
rpc GetLightdInfo(Empty) returns (LightdInfo) {}
// Testing-only