// Copyright (c) 2019-2020 The Zcash developers // Distributed under the MIT software license, see the accompanying // file COPYING or https://www.opensource.org/licenses/mit-license.php . syntax = "proto3"; package cash.z.wallet.sdk.rpc; option go_package = ".;walletrpc"; option swift_prefix = ""; import "service.proto"; message DarksideMetaState { int32 saplingActivation = 1; string branchID = 2; string chainName = 3; } // A block is a hex-encoded string. message DarksideBlock { string block = 1; } // DarksideBlocksURL is typically something like: // https://raw.githubusercontent.com/zcash-hackworks/darksidewalletd-test-data/master/basic-reorg/before-reorg.txt message DarksideBlocksURL { string url = 1; } // DarksideTransactionsURL refers to an HTTP source that contains a list // of hex-encoded transactions, one per line, that are to be associated // with the given height (fake-mined into the block at that height) message DarksideTransactionsURL { int32 height = 1; string url = 2; } message DarksideHeight { int32 height = 1; } message DarksideEmptyBlocks { int32 height = 1; int32 nonce = 2; int32 count = 3; } // Darksidewalletd maintains two staging areas, blocks and transactions. The // Stage*() gRPCs add items to the staging area; ApplyStaged() "applies" everything // in the staging area to the working (operational) state that the mock zcashd // serves; transactions are placed into their corresponding blocks (by height). service DarksideStreamer { // Reset reverts all darksidewalletd state (active block range, latest height, // staged blocks and transactions) and lightwalletd state (cache) to empty, // the same as the initial state. This occurs synchronously and instantaneously; // no reorg happens in lightwalletd. This is good to do before each independent // test so that no state leaks from one test to another. // Also sets (some of) the values returned by GetLightdInfo(). The Sapling // activation height specified here must be where the block range starts. rpc Reset(DarksideMetaState) returns (Empty) {} // StageBlocksStream accepts a list of blocks and saves them into the blocks // staging area until ApplyStaged() is called; there is no immediate effect on // the mock zcashd. Blocks are hex-encoded. Order is important, see ApplyStaged. rpc StageBlocksStream(stream DarksideBlock) returns (Empty) {} // StageBlocks is the same as StageBlocksStream() except the blocks are fetched // from the given URL. Blocks are one per line, hex-encoded (not JSON). rpc StageBlocks(DarksideBlocksURL) returns (Empty) {} // StageBlocksCreate is like the previous two, except it creates 'count' // empty blocks at consecutive heights starting at height 'height'. The // 'nonce' is part of the header, so it contributes to the block hash; this // lets you create identical blocks (same transactions and height), but with // different hashes. rpc StageBlocksCreate(DarksideEmptyBlocks) returns (Empty) {} // StageTransactionsStream stores the given transaction-height pairs in the // staging area until ApplyStaged() is called. Note that these transactions // are not returned by the production GetTransaction() gRPC until they // appear in a "mined" block (contained in the active blockchain presented // by the mock zcashd). rpc StageTransactionsStream(stream RawTransaction) returns (Empty) {} // StageTransactions is the same except the transactions are fetched from // the given url. They are all staged into the block at the given height. // Staging transactions to different heights requires multiple calls. rpc StageTransactions(DarksideTransactionsURL) returns (Empty) {} // ApplyStaged iterates the list of blocks that were staged by the // StageBlocks*() gRPCs, in the order they were staged, and "merges" each // into the active, working blocks list that the mock zcashd is presenting // to lightwalletd. Even as each block is applied, the active list can't // have gaps; if the active block range is 1000-1006, and the staged block // range is 1003-1004, the resulting range is 1000-1004, with 1000-1002 // unchanged, blocks 1003-1004 from the new range, and 1005-1006 dropped. // // After merging all blocks, ApplyStaged() appends staged transactions (in // the order received) into each one's corresponding (by height) block // The staging area is then cleared. // // The argument specifies the latest block height that mock zcashd reports // (i.e. what's returned by GetLatestBlock). Note that ApplyStaged() can // also be used to simply advance the latest block height presented by mock // zcashd. That is, there doesn't need to be anything in the staging area. rpc ApplyStaged(DarksideHeight) returns (Empty) {} // Calls to the production gRPC SendTransaction() store the transaction in // a separate area (not the staging area); this method returns all transactions // in this separate area, which is then cleared. The height returned // with each transaction is -1 (invalid) since these transactions haven't // been mined yet. The intention is that the transactions returned here can // then, for example, be given to StageTransactions() to get them "mined" // into a specified block on the next ApplyStaged(). rpc GetIncomingTransactions(Empty) returns (stream RawTransaction) {} // Clear the incoming transaction pool. rpc ClearIncomingTransactions(Empty) returns (Empty) {} }