Skip to content

Commit

Permalink
feat(rpc): Add a generate rpc method (#8849)
Browse files Browse the repository at this point in the history
* implement `generate` rpc method

* update openapi

---------

Co-authored-by: Pili Guerra <mpguerra@users.noreply.github.com>
  • Loading branch information
oxarbitrage and mpguerra authored Sep 9, 2024
1 parent 554a37d commit 082cdad
Show file tree
Hide file tree
Showing 2 changed files with 150 additions and 29 deletions.
102 changes: 75 additions & 27 deletions openapi.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ paths:
default: getinfo
id:
type: string
default: QWlDS9bxlK
default: dX2SRjFwfc
params:
type: array
items: {}
Expand Down Expand Up @@ -61,7 +61,7 @@ paths:
default: getblockchaininfo
id:
type: string
default: XSg3wvZykA
default: LoRrjyRM4l
params:
type: array
items: {}
Expand Down Expand Up @@ -99,7 +99,7 @@ paths:
default: getaddressbalance
id:
type: string
default: GEd1QJWprH
default: WWIvpPiJo0
params:
type: array
items: {}
Expand Down Expand Up @@ -147,7 +147,7 @@ paths:
default: sendrawtransaction
id:
type: string
default: nhQi7D6Oru
default: '5tVg2R9ZeI'
params:
type: array
items: {}
Expand Down Expand Up @@ -196,7 +196,7 @@ paths:
default: getblock
id:
type: string
default: qIEYMzgbJZ
default: vZ5KPOdiue
params:
type: array
items: {}
Expand Down Expand Up @@ -239,7 +239,7 @@ paths:
default: getbestblockhash
id:
type: string
default: P9UBS8IXXU
default: IifeYgN2ZK
params:
type: array
items: {}
Expand Down Expand Up @@ -272,7 +272,7 @@ paths:
default: getbestblockheightandhash
id:
type: string
default: gQNhsomx7N
default: tNLKsWqtNW
params:
type: array
items: {}
Expand Down Expand Up @@ -305,7 +305,7 @@ paths:
default: getrawmempool
id:
type: string
default: c2ScL31PtX
default: IZ6todle9t
params:
type: array
items: {}
Expand Down Expand Up @@ -343,7 +343,7 @@ paths:
default: z_gettreestate
id:
type: string
default: JQ0mENKbdm
default: SSZAwyUO6t
params:
type: array
items: {}
Expand Down Expand Up @@ -393,7 +393,7 @@ paths:
default: z_getsubtreesbyindex
id:
type: string
default: bZUCv4t0f4
default: '3fJMQ0Hfxt'
params:
type: array
items: {}
Expand Down Expand Up @@ -432,7 +432,7 @@ paths:
default: getrawtransaction
id:
type: string
default: I0FAejAi4r
default: RTdE1YnNxy
params:
type: array
items: {}
Expand Down Expand Up @@ -480,7 +480,7 @@ paths:
default: getaddresstxids
id:
type: string
default: '3fMzDHOglf'
default: ifahwzVoYe
params:
type: array
items: {}
Expand Down Expand Up @@ -528,7 +528,7 @@ paths:
default: getaddressutxos
id:
type: string
default: LE2AR8Tr6X
default: PcPdZ7aiKy
params:
type: array
items: {}
Expand Down Expand Up @@ -571,7 +571,7 @@ paths:
default: stop
id:
type: string
default: PbxxqB0ZpF
default: rWlJLGe7VJ
params:
type: array
items: {}
Expand Down Expand Up @@ -604,7 +604,7 @@ paths:
default: getblockcount
id:
type: string
default: WO6BAIKSCg
default: f4p3Cb4sDu
params:
type: array
items: {}
Expand Down Expand Up @@ -642,7 +642,7 @@ paths:
default: getblockhash
id:
type: string
default: vHpKNIQRLF
default: '3QXvqbEWqb'
params:
type: array
items: {}
Expand Down Expand Up @@ -690,7 +690,7 @@ paths:
default: getblocktemplate
id:
type: string
default: L04jp5F2QW
default: GXKjn81k0D
params:
type: array
items: {}
Expand Down Expand Up @@ -728,7 +728,7 @@ paths:
default: submitblock
id:
type: string
default: Izn7vhiMaA
default: cwGy92Mwn9
params:
type: array
items: {}
Expand Down Expand Up @@ -761,7 +761,7 @@ paths:
default: getmininginfo
id:
type: string
default: SgyuBQbMik
default: '4ZFY9ljh5I'
params:
type: array
items: {}
Expand Down Expand Up @@ -794,7 +794,7 @@ paths:
default: getnetworksolps
id:
type: string
default: FXg2iH3eaX
default: tJlKGzARjU
params:
type: array
items: {}
Expand Down Expand Up @@ -827,7 +827,7 @@ paths:
default: getnetworkhashps
id:
type: string
default: '2PWjf8QqfI'
default: '7pUkOt26PB'
params:
type: array
items: {}
Expand Down Expand Up @@ -860,7 +860,7 @@ paths:
default: getpeerinfo
id:
type: string
default: OE9s5wkP0w
default: JjnSrPKeyS
params:
type: array
items: {}
Expand Down Expand Up @@ -898,7 +898,7 @@ paths:
default: validateaddress
id:
type: string
default: '6FS4iGA4Ht'
default: pxZQt6VQ9U
params:
type: array
items: {}
Expand Down Expand Up @@ -936,7 +936,7 @@ paths:
default: z_validateaddress
id:
type: string
default: utp8tN61yU
default: x2R2oRhdZE
params:
type: array
items: {}
Expand Down Expand Up @@ -974,7 +974,7 @@ paths:
default: getblocksubsidy
id:
type: string
default: dgNZGo7lNa
default: vkhYJS3FH8
params:
type: array
items: {}
Expand Down Expand Up @@ -1017,7 +1017,7 @@ paths:
default: getdifficulty
id:
type: string
default: KEJv30D2MI
default: bC6q9c3xYO
params:
type: array
items: {}
Expand Down Expand Up @@ -1055,7 +1055,7 @@ paths:
default: z_listunifiedreceivers
id:
type: string
default: lfBqvYghGm
default: EQvPXkcJC2
params:
type: array
items: {}
Expand All @@ -1071,3 +1071,51 @@ paths:
result:
type: object
default: '{"orchard":"orchard address if any","sapling":"sapling address if any","p2pkh":"p2pkh address if any","p2sh":"p2sh address if any"}'
/generate:
post:
tags:
- generating
description: |-
Mine blocks immediately. Returns the block hashes of the generated blocks.
**Request body `params` arguments:**
- `num_blocks` - Number of blocks to be generated.
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
method:
type: string
default: generate
id:
type: string
default: w41FKROii3
params:
type: array
items: {}
default: '[1]'
responses:
'200':
description: OK
content:
application/json:
schema:
type: object
properties:
result:
type: object
default: '{}'
'400':
description: Bad request
content:
application/json:
schema:
type: object
properties:
error:
type: string
default: Invalid parameters
77 changes: 75 additions & 2 deletions zebra-rpc/src/methods/get_block_template_rpcs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ use zebra_chain::{
Network, NetworkKind, NetworkUpgrade, POW_AVERAGING_WINDOW,
},
primitives,
serialization::ZcashDeserializeInto,
serialization::{ZcashDeserializeInto, ZcashSerialize},
transparent::{
self, EXTRA_ZEBRA_COINBASE_DATA, MAX_COINBASE_DATA_LEN, MAX_COINBASE_HEIGHT_DATA_LEN,
},
Expand Down Expand Up @@ -47,7 +47,9 @@ use crate::methods::{
// TODO: move the types/* modules directly under get_block_template_rpcs,
// and combine any modules with the same names.
types::{
get_block_template::GetBlockTemplate,
get_block_template::{
proposal::TimeSource, proposal_block_from_template, GetBlockTemplate,
},
get_mining_info,
long_poll::LongPollInput,
peer_info::PeerInfo,
Expand Down Expand Up @@ -283,6 +285,22 @@ pub trait GetBlockTemplateRpc {
&self,
address: String,
) -> BoxFuture<Result<unified_address::Response>>;

#[rpc(name = "generate")]
/// Mine blocks immediately. Returns the block hashes of the generated blocks.
///
/// # Parameters
///
/// - `num_blocks`: (numeric, required, example=1) Number of blocks to be generated.
///
/// # Notes
///
/// Only works if the network of the running zebrad process is `Regtest`.
///
/// zcashd reference: [`generate`](https://zcash.github.io/rpc/generate.html)
/// method: post
/// tags: generating
fn generate(&self, num_blocks: u32) -> BoxFuture<Result<Vec<GetBlockHash>>>;
}

/// RPC method implementations.
Expand Down Expand Up @@ -1357,6 +1375,61 @@ where
}
.boxed()
}

fn generate(&self, num_blocks: u32) -> BoxFuture<Result<Vec<GetBlockHash>>> {
let rpc: GetBlockTemplateRpcImpl<
Mempool,
State,
Tip,
BlockVerifierRouter,
SyncStatus,
AddressBook,
> = self.clone();
let network = self.network.clone();

async move {
if !network.is_regtest() {
return Err(Error {
code: ErrorCode::ServerError(0),
message: "generate is only supported on regtest".to_string(),
data: None,
});
}

let mut block_hashes = Vec::new();
for _ in 0..num_blocks {
let block_template = rpc.get_block_template(None).await.map_server_error()?;

let get_block_template::Response::TemplateMode(block_template) = block_template
else {
return Err(Error {
code: ErrorCode::ServerError(0),
message: "error generating block template".to_string(),
data: None,
});
};

let proposal_block = proposal_block_from_template(
&block_template,
TimeSource::CurTime,
NetworkUpgrade::current(&network, Height(block_template.height)),
)
.map_server_error()?;
let hex_proposal_block =
HexData(proposal_block.zcash_serialize_to_vec().map_server_error()?);

let _submit = rpc
.submit_block(hex_proposal_block, None)
.await
.map_server_error()?;

block_hashes.push(GetBlockHash(proposal_block.hash()));
}

Ok(block_hashes)
}
.boxed()
}
}

// Put support functions in a submodule, to keep this file small.

0 comments on commit 082cdad

Please sign in to comment.