feat(rpc): Add a `generate` rpc method (#8849)

* implement `generate` rpc method

* update openapi

---------

Co-authored-by: Pili Guerra <mpguerra@users.noreply.github.com>
This commit is contained in:
Alfredo Garcia 2024-09-09 18:51:37 -03:00 committed by GitHub
parent 554a37d20a
commit 082cdad1c1
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 150 additions and 29 deletions

View File

@ -28,7 +28,7 @@ paths:
default: getinfo
id:
type: string
default: QWlDS9bxlK
default: dX2SRjFwfc
params:
type: array
items: {}
@ -61,7 +61,7 @@ paths:
default: getblockchaininfo
id:
type: string
default: XSg3wvZykA
default: LoRrjyRM4l
params:
type: array
items: {}
@ -99,7 +99,7 @@ paths:
default: getaddressbalance
id:
type: string
default: GEd1QJWprH
default: WWIvpPiJo0
params:
type: array
items: {}
@ -147,7 +147,7 @@ paths:
default: sendrawtransaction
id:
type: string
default: nhQi7D6Oru
default: '5tVg2R9ZeI'
params:
type: array
items: {}
@ -196,7 +196,7 @@ paths:
default: getblock
id:
type: string
default: qIEYMzgbJZ
default: vZ5KPOdiue
params:
type: array
items: {}
@ -239,7 +239,7 @@ paths:
default: getbestblockhash
id:
type: string
default: P9UBS8IXXU
default: IifeYgN2ZK
params:
type: array
items: {}
@ -272,7 +272,7 @@ paths:
default: getbestblockheightandhash
id:
type: string
default: gQNhsomx7N
default: tNLKsWqtNW
params:
type: array
items: {}
@ -305,7 +305,7 @@ paths:
default: getrawmempool
id:
type: string
default: c2ScL31PtX
default: IZ6todle9t
params:
type: array
items: {}
@ -343,7 +343,7 @@ paths:
default: z_gettreestate
id:
type: string
default: JQ0mENKbdm
default: SSZAwyUO6t
params:
type: array
items: {}
@ -393,7 +393,7 @@ paths:
default: z_getsubtreesbyindex
id:
type: string
default: bZUCv4t0f4
default: '3fJMQ0Hfxt'
params:
type: array
items: {}
@ -432,7 +432,7 @@ paths:
default: getrawtransaction
id:
type: string
default: I0FAejAi4r
default: RTdE1YnNxy
params:
type: array
items: {}
@ -480,7 +480,7 @@ paths:
default: getaddresstxids
id:
type: string
default: '3fMzDHOglf'
default: ifahwzVoYe
params:
type: array
items: {}
@ -528,7 +528,7 @@ paths:
default: getaddressutxos
id:
type: string
default: LE2AR8Tr6X
default: PcPdZ7aiKy
params:
type: array
items: {}
@ -571,7 +571,7 @@ paths:
default: stop
id:
type: string
default: PbxxqB0ZpF
default: rWlJLGe7VJ
params:
type: array
items: {}
@ -604,7 +604,7 @@ paths:
default: getblockcount
id:
type: string
default: WO6BAIKSCg
default: f4p3Cb4sDu
params:
type: array
items: {}
@ -642,7 +642,7 @@ paths:
default: getblockhash
id:
type: string
default: vHpKNIQRLF
default: '3QXvqbEWqb'
params:
type: array
items: {}
@ -690,7 +690,7 @@ paths:
default: getblocktemplate
id:
type: string
default: L04jp5F2QW
default: GXKjn81k0D
params:
type: array
items: {}
@ -728,7 +728,7 @@ paths:
default: submitblock
id:
type: string
default: Izn7vhiMaA
default: cwGy92Mwn9
params:
type: array
items: {}
@ -761,7 +761,7 @@ paths:
default: getmininginfo
id:
type: string
default: SgyuBQbMik
default: '4ZFY9ljh5I'
params:
type: array
items: {}
@ -794,7 +794,7 @@ paths:
default: getnetworksolps
id:
type: string
default: FXg2iH3eaX
default: tJlKGzARjU
params:
type: array
items: {}
@ -827,7 +827,7 @@ paths:
default: getnetworkhashps
id:
type: string
default: '2PWjf8QqfI'
default: '7pUkOt26PB'
params:
type: array
items: {}
@ -860,7 +860,7 @@ paths:
default: getpeerinfo
id:
type: string
default: OE9s5wkP0w
default: JjnSrPKeyS
params:
type: array
items: {}
@ -898,7 +898,7 @@ paths:
default: validateaddress
id:
type: string
default: '6FS4iGA4Ht'
default: pxZQt6VQ9U
params:
type: array
items: {}
@ -936,7 +936,7 @@ paths:
default: z_validateaddress
id:
type: string
default: utp8tN61yU
default: x2R2oRhdZE
params:
type: array
items: {}
@ -974,7 +974,7 @@ paths:
default: getblocksubsidy
id:
type: string
default: dgNZGo7lNa
default: vkhYJS3FH8
params:
type: array
items: {}
@ -1017,7 +1017,7 @@ paths:
default: getdifficulty
id:
type: string
default: KEJv30D2MI
default: bC6q9c3xYO
params:
type: array
items: {}
@ -1055,7 +1055,7 @@ paths:
default: z_listunifiedreceivers
id:
type: string
default: lfBqvYghGm
default: EQvPXkcJC2
params:
type: array
items: {}
@ -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

View File

@ -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,
},
@ -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,
@ -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.
@ -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.