diff --git a/docs/rtd/index.html b/docs/rtd/index.html
index 35bf4bda..1b76e336 100644
--- a/docs/rtd/index.html
+++ b/docs/rtd/index.html
@@ -1050,6 +1050,13 @@
DarksideStreamer
replacing any existing entries
+
+ | Stop |
+ Empty |
+ Empty |
+ Stop causes the server to shut down cleanly. |
+
+
diff --git a/frontend/service.go b/frontend/service.go
index 00b36857..65f79aea 100644
--- a/frontend/service.go
+++ b/frontend/service.go
@@ -11,6 +11,7 @@ import (
"encoding/json"
"errors"
"io"
+ "os"
"regexp"
"sort"
"strconv"
@@ -780,6 +781,17 @@ func (s *DarksideStreamer) Reset(ctx context.Context, ms *walletrpc.DarksideMeta
return &walletrpc.Empty{}, nil
}
+func (s *DarksideStreamer) Stop(ctx context.Context, _ *walletrpc.Empty) (*walletrpc.Empty, error) {
+ common.Log.Info("Stopping by gRPC request")
+ go func() {
+ // minor improvement: let the successful reply gets back to the client
+ // (otherwise it looks like the Stop request failed when it didn't)
+ common.Time.Sleep(1 * time.Second)
+ os.Exit(0)
+ }()
+ return &walletrpc.Empty{}, nil
+}
+
// StageBlocksStream accepts a list of blocks from the wallet test code,
// and makes them available to present from the mock zcashd's GetBlock rpc.
func (s *DarksideStreamer) StageBlocksStream(blocks walletrpc.DarksideStreamer_StageBlocksStreamServer) error {
diff --git a/smoke-test.bash b/smoke-test.bash
new file mode 100755
index 00000000..7767b7c0
--- /dev/null
+++ b/smoke-test.bash
@@ -0,0 +1,291 @@
+#!/usr/bin/env bash
+#
+# Copyright (c) 2025 The Zcash developers
+#
+# Run this test with no arguments.
+#
+# REQUIREMENTS:
+# - grpcurl
+# - jq
+
+set -e
+
+type -p grpcurl >/dev/null || {
+ echo "grpcurl not found"
+ echo "you may install grpcurl by running:"
+ echo " go install github.com/fullstorydev/grpcurl/cmd/grpcurl@latest"
+ exit 1
+}
+
+type -p jq >/dev/null || {
+ echo "jq not found"
+ echo "you may install jq by running (on debian, for example):"
+ echo " sudo apt install jq"
+ exit 1
+}
+
+kill_background_server() {
+ echo -n Stopping darkside server ...
+ grpcurl -plaintext localhost:9067 cash.z.wallet.sdk.rpc.DarksideStreamer/Stop
+}
+
+# Trap the EXIT signal and call the kill function
+trap kill_background_server EXIT
+
+# grpc production
+function gp {
+ method=$1; shift
+ test $# -gt 0 && set -- -d "$@"
+ grpcurl -plaintext "$@" localhost:9067 cash.z.wallet.sdk.rpc.CompactTxStreamer/$method
+}
+
+# grpc test (darksidewallet)
+function gt {
+ method=$1; shift
+ test $# -gt 0 && set -- -d "$@"
+ grpcurl -plaintext "$@" localhost:9067 cash.z.wallet.sdk.rpc.DarksideStreamer/$method
+}
+
+function wait_height {
+ i=0
+ while :
+ do
+ h=$(gp GetLightdInfo | jq .blockHeight)
+ h=${h//\"}
+ test $h -ge $1 && break
+ let i=$i+1
+ test $i -gt 10 && { echo cannot reach height $1;exit 1;}
+ sleep 1
+ done
+}
+
+function compare {
+ expected="$1"
+ actual="$2"
+ if test "$expected" != "$actual"
+ then
+ echo
+ echo FAILURE --------------------------------------
+ echo expected: "$expected"
+ echo
+ echo actual: "$actual"
+ echo
+ echo diff "(expected, actual)":
+ echo "$expected" > /tmp/expected.$$
+ echo "$actual" | diff /tmp/expected.$$ -
+ rm /tmp/expected.$$
+ exit 1
+ fi
+}
+
+go run main.go --donation-address udonationaddr --zcash-conf-path ~/.zcash/zcash.conf --no-tls-very-insecure --darkside-timeout 999999 --darkside-very-insecure &
+sleep 4
+
+# Most of this test comes from docs/darksidewalletd.md "Simulating a reorg that moves a transaction"
+echo -n test: Reset ...
+gt Reset '{"saplingActivation": 663150,"branchID": "bad", "chainName":"x"}'
+echo -n test: StageBlocks block 663150 ...
+gt StageBlocks '{"url": "https://raw.githubusercontent.com/zcash-hackworks/darksidewalletd-test-data/master/basic-reorg/663150.txt"}'
+echo -n test: StageBlocksCreate blocks 663151 to 663250 ...
+gt StageBlocksCreate '{"height":663151,"count":100}'
+# add a transaction
+echo -n test: StageTransactions to block 663190 ...
+gt StageTransactions '{"height":663190,"url":"https://raw.githubusercontent.com/zcash-hackworks/darksidewalletd-test-data/master/transactions/recv/0821a89be7f2fc1311792c3fa1dd2171a8cdfb2effd98590cbd5ebcdcfcf491f.txt"}'
+echo -n test: ApplyStaged to block 663210 ...
+gt ApplyStaged '{"height":663210}'
+
+# the block ingestor needs time to receive the block from the (fake) zcashd
+wait_height 663190
+
+echo Getblock 663190 ...
+actual=$(gp GetBlock '{"height":663190}')
+expected='{
+ "height": "663190",
+ "hash": "Ax/AHLeTfnDuXWX3ZiYo+nWvh24lyMjvR0e2CAfqEok=",
+ "prevHash": "m5/epQ9d3wl4Z8bctOB/ZCuSl8Uko4DeIpKtKZayK4U=",
+ "time": 1,
+ "vtx": [
+ {
+ "index": "1",
+ "hash": "H0nPz83r1cuQhdn/LvvNqHEh3aE/LHkRE/zy55uoIQg=",
+ "spends": [
+ {
+ "nf": "xrZLCu+Kbv6PXo8cqM+f25Hp55L2cm95bM68JwUnDHg="
+ }
+ ],
+ "outputs": [
+ {
+ "cmu": "pe/G9q13FyE6vAhrTPzIGpU5Dht5DvJTuc9zmTEx0gU=",
+ "ephemeralKey": "qw5MPsRoe8aOnvZ/VB3r1Ja/WkHb52TVU1vyHjGEOqc=",
+ "ciphertext": "R2uN3CHagj7Oo+6O9VeBrE6x4dQ07Jl18rVM27vGhl1Io75lFYCHA1SrV72Zu+bgwMilTA=="
+ },
+ {
+ "cmu": "3rQ9DMmk7RaWGf9q0uOYQ7FieHL/TE8Z+QCcS/IJfkA=",
+ "ephemeralKey": "U1NCOlTzIF1qlprAjuGUUj591GpO5Vs5WTsmCW35Pio=",
+ "ciphertext": "2MbBHjPbkDT/GVsXgDHhihFQizxvizHINXKVbXKnv3Ih1P4c1f3By+TLH2g1yAG3lSARuQ=="
+ }
+ ]
+ }
+ ],
+ "chainMetadata": {
+ "saplingCommitmentTreeSize": 2
+ }
+}'
+compare "$expected" "$actual"
+
+# force a reorg with the transactions now in 663195
+echo -n test: StageBlocksCreate blocks 663180 to 663179 ...
+gt StageBlocksCreate '{"height":663180,"count":100}'
+echo -n test: StageTransactions block 663195 ...
+gt StageTransactions '{"height":663195,"url":"https://raw.githubusercontent.com/zcash-hackworks/darksidewalletd-test-data/master/transactions/recv/0821a89be7f2fc1311792c3fa1dd2171a8cdfb2effd98590cbd5ebcdcfcf491f.txt"}'
+
+echo GetMempoolTx ...
+actual=$(gp GetMempoolTx '{"txid":""}')
+expected='{
+ "hash": "CCGom+fy/BMReSw/od0hcajN+y7/2YWQy9Xrzc/PSR8=",
+ "spends": [
+ {
+ "nf": "xrZLCu+Kbv6PXo8cqM+f25Hp55L2cm95bM68JwUnDHg="
+ }
+ ],
+ "outputs": [
+ {
+ "cmu": "pe/G9q13FyE6vAhrTPzIGpU5Dht5DvJTuc9zmTEx0gU=",
+ "ephemeralKey": "qw5MPsRoe8aOnvZ/VB3r1Ja/WkHb52TVU1vyHjGEOqc=",
+ "ciphertext": "R2uN3CHagj7Oo+6O9VeBrE6x4dQ07Jl18rVM27vGhl1Io75lFYCHA1SrV72Zu+bgwMilTA=="
+ },
+ {
+ "cmu": "3rQ9DMmk7RaWGf9q0uOYQ7FieHL/TE8Z+QCcS/IJfkA=",
+ "ephemeralKey": "U1NCOlTzIF1qlprAjuGUUj591GpO5Vs5WTsmCW35Pio=",
+ "ciphertext": "2MbBHjPbkDT/GVsXgDHhihFQizxvizHINXKVbXKnv3Ih1P4c1f3By+TLH2g1yAG3lSARuQ=="
+ }
+ ]
+}'
+compare "$expected" "$actual"
+
+echo -n test: ApplyStaged to block 663210 ...
+gt ApplyStaged '{"height":663210}'
+# hack: we can't just wait_height here because 663190 will exist immediately
+sleep 4
+echo GetBlock 663190 - transaction should no longer exist ...
+actual=$(gp GetBlock '{"height":663190}')
+expected='{
+ "height": "663190",
+ "hash": "btosPfiJBX9m3nNSCP+vjAxWpEDS7Kfut9H7FY+mSYo=",
+ "prevHash": "m5/epQ9d3wl4Z8bctOB/ZCuSl8Uko4DeIpKtKZayK4U=",
+ "time": 1,
+ "chainMetadata": {}
+}'
+compare "$expected" "$actual"
+
+echo GetBlock 663195 - transaction has moved to this block ...
+actual=$(gp GetBlock '{"height":663195}')
+expected='{
+ "height": "663195",
+ "hash": "CmcEQ/NZ9nSk+VdNfCEHvKu9MTNeWKoF1dZ7cWUTnCc=",
+ "prevHash": "04i1neRIgx7vgtDkrydYJu3KWjbY5g7QvUygNBfu6ug=",
+ "time": 1,
+ "vtx": [
+ {
+ "index": "1",
+ "hash": "H0nPz83r1cuQhdn/LvvNqHEh3aE/LHkRE/zy55uoIQg=",
+ "spends": [
+ {
+ "nf": "xrZLCu+Kbv6PXo8cqM+f25Hp55L2cm95bM68JwUnDHg="
+ }
+ ],
+ "outputs": [
+ {
+ "cmu": "pe/G9q13FyE6vAhrTPzIGpU5Dht5DvJTuc9zmTEx0gU=",
+ "ephemeralKey": "qw5MPsRoe8aOnvZ/VB3r1Ja/WkHb52TVU1vyHjGEOqc=",
+ "ciphertext": "R2uN3CHagj7Oo+6O9VeBrE6x4dQ07Jl18rVM27vGhl1Io75lFYCHA1SrV72Zu+bgwMilTA=="
+ },
+ {
+ "cmu": "3rQ9DMmk7RaWGf9q0uOYQ7FieHL/TE8Z+QCcS/IJfkA=",
+ "ephemeralKey": "U1NCOlTzIF1qlprAjuGUUj591GpO5Vs5WTsmCW35Pio=",
+ "ciphertext": "2MbBHjPbkDT/GVsXgDHhihFQizxvizHINXKVbXKnv3Ih1P4c1f3By+TLH2g1yAG3lSARuQ=="
+ }
+ ]
+ }
+ ],
+ "chainMetadata": {
+ "saplingCommitmentTreeSize": 2
+ }
+}'
+compare "$expected" "$actual"
+
+echo GetLatestBlock - height should be 663210 ...
+actual=$(gp GetLatestBlock)
+expected='{
+ "height": "663210",
+ "hash": "xIZXGJxDK7uOcP31fHkgaP32HEaU4qKKlIEBFqbjyq0="
+}'
+compare "$expected" "$actual"
+
+echo -n ApplyStaged 663220 ...
+gt ApplyStaged '{"height":663220}'
+wait_height 663220
+
+echo GetLatestBlock - height should be 663220 ...
+actual=$(gp GetLatestBlock)
+expected='{
+ "height": "663220",
+ "hash": "uyBTDoNsj0xDHIlTn7cOZ0cG2YtyFPu1wG24sl4dBWo="
+}'
+compare "$expected" "$actual"
+
+echo GetLightdInfo ...
+actual=$(gp GetLightdInfo)
+expected='{
+ "version": "v0.0.0.0-dev",
+ "vendor": "ECC DarksideWalletD",
+ "taddrSupport": true,
+ "chainName": "x",
+ "saplingActivationHeight": "663150",
+ "consensusBranchId": "bad",
+ "blockHeight": "663220",
+ "zcashdBuild": "darksidewallet-build",
+ "zcashdSubversion": "darksidewallet-subversion",
+ "donationAddress": "udonationaddr"
+}'
+compare "$expected" "$actual"
+
+echo GetBlockRange 663152 to 663154 ...
+actual=$(gp GetBlockRange '{"start":{"height":663152},"end":{"height":663154}}')
+expected='{
+ "height": "663152",
+ "hash": "uzuBbqy3JKKpssnPJHLXLq+nv1eTHsuyQAkYiR84y7M=",
+ "prevHash": "oh3nSTQCTZgnRGBgS8rEZt/cyjjxMI78X49lkTXJyBc=",
+ "time": 1,
+ "chainMetadata": {}
+}
+{
+ "height": "663153",
+ "hash": "BQpVcT2DPoC71Oo1DyL4arAeXWFEMDsOQfwsObbKY4s=",
+ "prevHash": "uzuBbqy3JKKpssnPJHLXLq+nv1eTHsuyQAkYiR84y7M=",
+ "time": 1,
+ "chainMetadata": {}
+}
+{
+ "height": "663154",
+ "hash": "MJmT360oQJ7IfD5xprEuqmzFu2oROyFRe7eGcejz/bQ=",
+ "prevHash": "BQpVcT2DPoC71Oo1DyL4arAeXWFEMDsOQfwsObbKY4s=",
+ "time": 1,
+ "chainMetadata": {}
+}'
+compare "$expected" "$actual"
+
+echo GetTransaction ...
+actual=$(gp GetTransaction '{"hash": "H0nPz83r1cuQhdn/LvvNqHEh3aE/LHkRE/zy55uoIQg="}')
+expected='{
+ "data": "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",
+ "height": "663195"
+}'
+compare "$expected" "$actual"
+
+echo SendTransaction ...
+actual=$(gp SendTransaction "$actual")
+expected='{
+ "errorMessage": "0821a89be7f2fc1311792c3fa1dd2171a8cdfb2effd98590cbd5ebcdcfcf491f"
+}'
+compare "$expected" "$actual"
diff --git a/walletrpc/darkside.pb.go b/walletrpc/darkside.pb.go
index d944a1f7..60d58d08 100644
--- a/walletrpc/darkside.pb.go
+++ b/walletrpc/darkside.pb.go
@@ -485,7 +485,7 @@ var file_darkside_proto_rawDesc = []byte{
0x32, 0x22, 0x2e, 0x63, 0x61, 0x73, 0x68, 0x2e, 0x7a, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74,
0x2e, 0x73, 0x64, 0x6b, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x75, 0x62, 0x74, 0x72, 0x65, 0x65,
0x52, 0x6f, 0x6f, 0x74, 0x52, 0x0c, 0x73, 0x75, 0x62, 0x74, 0x72, 0x65, 0x65, 0x52, 0x6f, 0x6f,
- 0x74, 0x73, 0x32, 0xe4, 0x0a, 0x0a, 0x10, 0x44, 0x61, 0x72, 0x6b, 0x73, 0x69, 0x64, 0x65, 0x53,
+ 0x74, 0x73, 0x32, 0xaa, 0x0b, 0x0a, 0x10, 0x44, 0x61, 0x72, 0x6b, 0x73, 0x69, 0x64, 0x65, 0x53,
0x74, 0x72, 0x65, 0x61, 0x6d, 0x65, 0x72, 0x12, 0x51, 0x0a, 0x05, 0x52, 0x65, 0x73, 0x65, 0x74,
0x12, 0x28, 0x2e, 0x63, 0x61, 0x73, 0x68, 0x2e, 0x7a, 0x2e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74,
0x2e, 0x73, 0x64, 0x6b, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x44, 0x61, 0x72, 0x6b, 0x73, 0x69, 0x64,
@@ -571,9 +571,14 @@ var file_darkside_proto_rawDesc = []byte{
0x2e, 0x72, 0x70, 0x63, 0x2e, 0x44, 0x61, 0x72, 0x6b, 0x73, 0x69, 0x64, 0x65, 0x53, 0x75, 0x62,
0x74, 0x72, 0x65, 0x65, 0x52, 0x6f, 0x6f, 0x74, 0x73, 0x1a, 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, 0x22, 0x00, 0x42, 0x1b, 0x5a, 0x16, 0x6c, 0x69, 0x67,
- 0x68, 0x74, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x64, 0x2f, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74,
- 0x72, 0x70, 0x63, 0xba, 0x02, 0x00, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
+ 0x63, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x00, 0x12, 0x44, 0x0a, 0x04, 0x53, 0x74, 0x6f,
+ 0x70, 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,
+ 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, 0x22, 0x00, 0x42,
+ 0x1b, 0x5a, 0x16, 0x6c, 0x69, 0x67, 0x68, 0x74, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x64, 0x2f,
+ 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x72, 0x70, 0x63, 0xba, 0x02, 0x00, 0x62, 0x06, 0x70, 0x72,
+ 0x6f, 0x74, 0x6f, 0x33,
}
var (
@@ -623,23 +628,25 @@ var file_darkside_proto_depIdxs = []int32{
13, // 14: cash.z.wallet.sdk.rpc.DarksideStreamer.RemoveTreeState:input_type -> cash.z.wallet.sdk.rpc.BlockID
10, // 15: cash.z.wallet.sdk.rpc.DarksideStreamer.ClearAllTreeStates:input_type -> cash.z.wallet.sdk.rpc.Empty
6, // 16: cash.z.wallet.sdk.rpc.DarksideStreamer.SetSubtreeRoots:input_type -> cash.z.wallet.sdk.rpc.DarksideSubtreeRoots
- 10, // 17: cash.z.wallet.sdk.rpc.DarksideStreamer.Reset:output_type -> cash.z.wallet.sdk.rpc.Empty
- 10, // 18: cash.z.wallet.sdk.rpc.DarksideStreamer.StageBlocksStream:output_type -> cash.z.wallet.sdk.rpc.Empty
- 10, // 19: cash.z.wallet.sdk.rpc.DarksideStreamer.StageBlocks:output_type -> cash.z.wallet.sdk.rpc.Empty
- 10, // 20: cash.z.wallet.sdk.rpc.DarksideStreamer.StageBlocksCreate:output_type -> cash.z.wallet.sdk.rpc.Empty
- 10, // 21: cash.z.wallet.sdk.rpc.DarksideStreamer.StageTransactionsStream:output_type -> cash.z.wallet.sdk.rpc.Empty
- 10, // 22: cash.z.wallet.sdk.rpc.DarksideStreamer.StageTransactions:output_type -> cash.z.wallet.sdk.rpc.Empty
- 10, // 23: cash.z.wallet.sdk.rpc.DarksideStreamer.ApplyStaged:output_type -> cash.z.wallet.sdk.rpc.Empty
- 9, // 24: cash.z.wallet.sdk.rpc.DarksideStreamer.GetIncomingTransactions:output_type -> cash.z.wallet.sdk.rpc.RawTransaction
- 10, // 25: cash.z.wallet.sdk.rpc.DarksideStreamer.ClearIncomingTransactions:output_type -> cash.z.wallet.sdk.rpc.Empty
- 10, // 26: cash.z.wallet.sdk.rpc.DarksideStreamer.AddAddressUtxo:output_type -> cash.z.wallet.sdk.rpc.Empty
- 10, // 27: cash.z.wallet.sdk.rpc.DarksideStreamer.ClearAddressUtxo:output_type -> cash.z.wallet.sdk.rpc.Empty
- 10, // 28: cash.z.wallet.sdk.rpc.DarksideStreamer.AddTreeState:output_type -> cash.z.wallet.sdk.rpc.Empty
- 10, // 29: cash.z.wallet.sdk.rpc.DarksideStreamer.RemoveTreeState:output_type -> cash.z.wallet.sdk.rpc.Empty
- 10, // 30: cash.z.wallet.sdk.rpc.DarksideStreamer.ClearAllTreeStates:output_type -> cash.z.wallet.sdk.rpc.Empty
- 10, // 31: cash.z.wallet.sdk.rpc.DarksideStreamer.SetSubtreeRoots:output_type -> cash.z.wallet.sdk.rpc.Empty
- 17, // [17:32] is the sub-list for method output_type
- 2, // [2:17] is the sub-list for method input_type
+ 10, // 17: cash.z.wallet.sdk.rpc.DarksideStreamer.Stop:input_type -> cash.z.wallet.sdk.rpc.Empty
+ 10, // 18: cash.z.wallet.sdk.rpc.DarksideStreamer.Reset:output_type -> cash.z.wallet.sdk.rpc.Empty
+ 10, // 19: cash.z.wallet.sdk.rpc.DarksideStreamer.StageBlocksStream:output_type -> cash.z.wallet.sdk.rpc.Empty
+ 10, // 20: cash.z.wallet.sdk.rpc.DarksideStreamer.StageBlocks:output_type -> cash.z.wallet.sdk.rpc.Empty
+ 10, // 21: cash.z.wallet.sdk.rpc.DarksideStreamer.StageBlocksCreate:output_type -> cash.z.wallet.sdk.rpc.Empty
+ 10, // 22: cash.z.wallet.sdk.rpc.DarksideStreamer.StageTransactionsStream:output_type -> cash.z.wallet.sdk.rpc.Empty
+ 10, // 23: cash.z.wallet.sdk.rpc.DarksideStreamer.StageTransactions:output_type -> cash.z.wallet.sdk.rpc.Empty
+ 10, // 24: cash.z.wallet.sdk.rpc.DarksideStreamer.ApplyStaged:output_type -> cash.z.wallet.sdk.rpc.Empty
+ 9, // 25: cash.z.wallet.sdk.rpc.DarksideStreamer.GetIncomingTransactions:output_type -> cash.z.wallet.sdk.rpc.RawTransaction
+ 10, // 26: cash.z.wallet.sdk.rpc.DarksideStreamer.ClearIncomingTransactions:output_type -> cash.z.wallet.sdk.rpc.Empty
+ 10, // 27: cash.z.wallet.sdk.rpc.DarksideStreamer.AddAddressUtxo:output_type -> cash.z.wallet.sdk.rpc.Empty
+ 10, // 28: cash.z.wallet.sdk.rpc.DarksideStreamer.ClearAddressUtxo:output_type -> cash.z.wallet.sdk.rpc.Empty
+ 10, // 29: cash.z.wallet.sdk.rpc.DarksideStreamer.AddTreeState:output_type -> cash.z.wallet.sdk.rpc.Empty
+ 10, // 30: cash.z.wallet.sdk.rpc.DarksideStreamer.RemoveTreeState:output_type -> cash.z.wallet.sdk.rpc.Empty
+ 10, // 31: cash.z.wallet.sdk.rpc.DarksideStreamer.ClearAllTreeStates:output_type -> cash.z.wallet.sdk.rpc.Empty
+ 10, // 32: cash.z.wallet.sdk.rpc.DarksideStreamer.SetSubtreeRoots:output_type -> cash.z.wallet.sdk.rpc.Empty
+ 10, // 33: cash.z.wallet.sdk.rpc.DarksideStreamer.Stop:output_type -> cash.z.wallet.sdk.rpc.Empty
+ 18, // [18:34] is the sub-list for method output_type
+ 2, // [2:18] is the sub-list for method input_type
2, // [2:2] is the sub-list for extension type_name
2, // [2:2] is the sub-list for extension extendee
0, // [0:2] is the sub-list for field type_name
diff --git a/walletrpc/darkside.proto b/walletrpc/darkside.proto
index 249af4a4..02a8855d 100644
--- a/walletrpc/darkside.proto
+++ b/walletrpc/darkside.proto
@@ -142,4 +142,7 @@ service DarksideStreamer {
// Sets the subtree roots cache (for GetSubtreeRoots),
// replacing any existing entries
rpc SetSubtreeRoots(DarksideSubtreeRoots) returns (Empty) {}
+
+ // Stop causes the server to shut down cleanly.
+ rpc Stop(Empty) returns (Empty) {}
}
diff --git a/walletrpc/darkside_grpc.pb.go b/walletrpc/darkside_grpc.pb.go
index 87ea604b..830d7c42 100644
--- a/walletrpc/darkside_grpc.pb.go
+++ b/walletrpc/darkside_grpc.pb.go
@@ -38,6 +38,7 @@ const (
DarksideStreamer_RemoveTreeState_FullMethodName = "/cash.z.wallet.sdk.rpc.DarksideStreamer/RemoveTreeState"
DarksideStreamer_ClearAllTreeStates_FullMethodName = "/cash.z.wallet.sdk.rpc.DarksideStreamer/ClearAllTreeStates"
DarksideStreamer_SetSubtreeRoots_FullMethodName = "/cash.z.wallet.sdk.rpc.DarksideStreamer/SetSubtreeRoots"
+ DarksideStreamer_Stop_FullMethodName = "/cash.z.wallet.sdk.rpc.DarksideStreamer/Stop"
)
// DarksideStreamerClient is the client API for DarksideStreamer service.
@@ -116,6 +117,8 @@ type DarksideStreamerClient interface {
// Sets the subtree roots cache (for GetSubtreeRoots),
// replacing any existing entries
SetSubtreeRoots(ctx context.Context, in *DarksideSubtreeRoots, opts ...grpc.CallOption) (*Empty, error)
+ // Stop causes the server to shut down cleanly.
+ Stop(ctx context.Context, in *Empty, opts ...grpc.CallOption) (*Empty, error)
}
type darksideStreamerClient struct {
@@ -334,6 +337,15 @@ func (c *darksideStreamerClient) SetSubtreeRoots(ctx context.Context, in *Darksi
return out, nil
}
+func (c *darksideStreamerClient) Stop(ctx context.Context, in *Empty, opts ...grpc.CallOption) (*Empty, error) {
+ out := new(Empty)
+ err := c.cc.Invoke(ctx, DarksideStreamer_Stop_FullMethodName, in, out, opts...)
+ if err != nil {
+ return nil, err
+ }
+ return out, nil
+}
+
// DarksideStreamerServer is the server API for DarksideStreamer service.
// All implementations must embed UnimplementedDarksideStreamerServer
// for forward compatibility
@@ -410,6 +422,8 @@ type DarksideStreamerServer interface {
// Sets the subtree roots cache (for GetSubtreeRoots),
// replacing any existing entries
SetSubtreeRoots(context.Context, *DarksideSubtreeRoots) (*Empty, error)
+ // Stop causes the server to shut down cleanly.
+ Stop(context.Context, *Empty) (*Empty, error)
mustEmbedUnimplementedDarksideStreamerServer()
}
@@ -462,6 +476,9 @@ func (UnimplementedDarksideStreamerServer) ClearAllTreeStates(context.Context, *
func (UnimplementedDarksideStreamerServer) SetSubtreeRoots(context.Context, *DarksideSubtreeRoots) (*Empty, error) {
return nil, status.Errorf(codes.Unimplemented, "method SetSubtreeRoots not implemented")
}
+func (UnimplementedDarksideStreamerServer) Stop(context.Context, *Empty) (*Empty, error) {
+ return nil, status.Errorf(codes.Unimplemented, "method Stop not implemented")
+}
func (UnimplementedDarksideStreamerServer) mustEmbedUnimplementedDarksideStreamerServer() {}
// UnsafeDarksideStreamerServer may be embedded to opt out of forward compatibility for this service.
@@ -764,6 +781,24 @@ func _DarksideStreamer_SetSubtreeRoots_Handler(srv interface{}, ctx context.Cont
return interceptor(ctx, in, info, handler)
}
+func _DarksideStreamer_Stop_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+ in := new(Empty)
+ if err := dec(in); err != nil {
+ return nil, err
+ }
+ if interceptor == nil {
+ return srv.(DarksideStreamerServer).Stop(ctx, in)
+ }
+ info := &grpc.UnaryServerInfo{
+ Server: srv,
+ FullMethod: DarksideStreamer_Stop_FullMethodName,
+ }
+ handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+ return srv.(DarksideStreamerServer).Stop(ctx, req.(*Empty))
+ }
+ return interceptor(ctx, in, info, handler)
+}
+
// DarksideStreamer_ServiceDesc is the grpc.ServiceDesc for DarksideStreamer service.
// It's only intended for direct use with grpc.RegisterService,
// and not to be introspected or modified (even as a copy)
@@ -819,6 +854,10 @@ var DarksideStreamer_ServiceDesc = grpc.ServiceDesc{
MethodName: "SetSubtreeRoots",
Handler: _DarksideStreamer_SetSubtreeRoots_Handler,
},
+ {
+ MethodName: "Stop",
+ Handler: _DarksideStreamer_Stop_Handler,
+ },
},
Streams: []grpc.StreamDesc{
{