block_template_to_proposal/
main.rs1mod args;
8
9use std::io::Read;
10
11use color_eyre::eyre::Result;
12use serde_json::Value;
13use structopt::StructOpt;
14
15use zebra_chain::serialization::{DateTime32, ZcashSerialize};
16use zebra_rpc::{
17 client::{BlockTemplateResponse, LONG_POLL_ID_LENGTH},
18 proposal_block_from_template,
19};
20use zebra_utils::init_tracing;
21
22const MIN_TEMPLATE_BYTES: usize = 500;
26
27#[allow(clippy::print_stdout, clippy::print_stderr)]
29fn main() -> Result<()> {
30 init_tracing();
32 color_eyre::install()?;
33
34 let args = args::Args::from_args();
36
37 let time_source = args.time_source;
38
39 let template = args.template.unwrap_or_else(|| {
41 let mut template = String::new();
42 let bytes_read = std::io::stdin().read_to_string(&mut template).expect("missing JSON block template: must be supplied on command-line or standard input");
43
44 if bytes_read < MIN_TEMPLATE_BYTES {
45 panic!("JSON block template is too small: expected at least {MIN_TEMPLATE_BYTES} characters");
46 }
47
48 template
49 });
50
51 let mut template: Value = serde_json::from_str(&template)?;
53 eprintln!(
54 "{}",
55 serde_json::to_string_pretty(&template).expect("re-serialization never fails")
56 );
57
58 let template_obj = template
59 .as_object_mut()
60 .expect("template must be a JSON object");
61
62 template_obj["longpollid"] = "0".repeat(LONG_POLL_ID_LENGTH).into();
67
68 template_obj["coinbasetxn"]["required"] = true.into();
73 for tx in template_obj["transactions"]
74 .as_array_mut()
75 .expect("transactions must be a JSON array")
76 {
77 tx["required"] = false.into();
78 }
79
80 let current_time: DateTime32 = template_obj["curtime"]
83 .to_string()
84 .parse()
85 .expect("curtime is always a valid DateTime32");
86
87 template_obj.entry("maxtime").or_insert_with(|| {
88 if time_source.uses_max_time() {
89 eprintln!("maxtime field is missing, using curtime for maxtime: {current_time:?}");
90 }
91
92 current_time.timestamp().into()
93 });
94
95 let template: BlockTemplateResponse = serde_json::from_value(template)?;
97
98 let proposal = proposal_block_from_template(&template, time_source, &args.net)?;
100 eprintln!("{proposal:#?}");
101
102 let proposal = proposal
103 .zcash_serialize_to_vec()
104 .expect("serialization to Vec never fails");
105
106 println!("{}", hex::encode(proposal));
107
108 Ok(())
109}