add GetMempoolTx()
This commit is contained in:
parent
68836ee627
commit
7381129740
|
@ -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
|
||||
}
|
||||
|
||||
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]
|
||||
// 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 hex.EncodeToString(rhash)
|
||||
return r
|
||||
}
|
||||
|
||||
func displayHash(hash []byte) string {
|
||||
return hex.EncodeToString(Reverse(hash))
|
||||
}
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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,33 +464,63 @@ 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 {
|
||||
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")
|
||||
}
|
||||
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)
|
||||
findTxInBlocks := func(blocks [][]byte) json.RawMessage {
|
||||
for _, b := range blocks {
|
||||
block := parser.NewBlock()
|
||||
_, _ = block.ParseFromSlice(b)
|
||||
for _, tx := range block.Transactions() {
|
||||
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")
|
||||
}
|
||||
|
|
|
@ -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 <->
|
||||
|
|
|
@ -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]))
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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 += "\"" + addr + "\""
|
||||
notFirst = true
|
||||
addrList := &struct {
|
||||
Addresses []string `json:"addresses"`
|
||||
}{
|
||||
Addresses: addressList,
|
||||
}
|
||||
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
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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",
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue