Skip to content

Commit

Permalink
2. change(rpc): Add some transaction fields to the getblocktemplate
Browse files Browse the repository at this point in the history
… RPC (#5496)

* Add documentation for the getblocktemplate RPC

* Add a new mempool::Request::Transactions

* Add conversions from Vec<UnminedTx> to merkle::Root and AuthDataRoot

* Fill in the merkle root and auth data root fields

* Delete the Coinbase type, it's the same as Transaction

* Fill in some other existing types

* Add Hex serialization support to some zebra-chain types

* Add TransactionTemplate fields and fill some in

* Fix test hangs by spawning async tasks

* Add temporary workaround for no transactions in the block

* Encode hashes and roots as hex

* Update RPC snapshots

* Add a missing Request::Transactions handler

* Fix doc warnings

* Fix fee serialization

* Update snapshots for serialization changes

* Add a missing Cargo.lock change

* Change depends type

* Remove duplicate feature entry

* Document the new RPC feature

* Fix a comment typo

Co-authored-by: Alfredo Garcia <[email protected]>

* Update default roots docs

* Fix comment typo

* Fix a comment typo

Co-authored-by: Arya <[email protected]>

Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
Co-authored-by: Alfredo Garcia <[email protected]>
Co-authored-by: Arya <[email protected]>
  • Loading branch information
4 people authored Nov 3, 2022
1 parent 26d0455 commit 1424115
Show file tree
Hide file tree
Showing 34 changed files with 769 additions and 145 deletions.
24 changes: 22 additions & 2 deletions zebra-chain/src/amount.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
use std::{
cmp::Ordering,
convert::{TryFrom, TryInto},
hash::{Hash, Hasher},
marker::PhantomData,
ops::RangeInclusive,
Expand All @@ -28,7 +27,8 @@ pub type Result<T, E = Error> = std::result::Result<T, E>;
/// A runtime validated type for representing amounts of zatoshis
#[derive(Clone, Copy, Serialize, Deserialize)]
#[serde(try_from = "i64")]
#[serde(bound = "C: Constraint")]
#[serde(into = "i64")]
#[serde(bound = "C: Constraint + Clone")]
pub struct Amount<C = NegativeAllowed>(
/// The inner amount value.
i64,
Expand Down Expand Up @@ -498,6 +498,26 @@ impl Constraint for NonNegative {
}
}

/// Marker type for `Amount` that requires negative or zero values.
///
/// Used for coinbase transactions in `getblocktemplate` RPCs.
///
/// ```
/// # use zebra_chain::amount::{Constraint, MAX_MONEY, NegativeOrZero};
/// assert_eq!(
/// NegativeOrZero::valid_range(),
/// -MAX_MONEY..=0,
/// );
/// ```
#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash)]
pub struct NegativeOrZero;

impl Constraint for NegativeOrZero {
fn valid_range() -> RangeInclusive<i64> {
-MAX_MONEY..=0
}
}

/// Number of zatoshis in 1 ZEC
pub const COIN: i64 = 100_000_000;

Expand Down
111 changes: 111 additions & 0 deletions zebra-chain/src/block/commitment.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
//! The Commitment enum, used for the corresponding block header field.
use hex::{FromHex, ToHex};
use thiserror::Error;

use crate::{
Expand Down Expand Up @@ -159,6 +160,62 @@ impl From<ChainHistoryMmrRootHash> for [u8; 32] {
}
}

impl ChainHistoryMmrRootHash {
/// Return the hash bytes in big-endian byte-order suitable for printing out byte by byte.
///
/// Zebra displays transaction and block hashes in big-endian byte-order,
/// following the u256 convention set by Bitcoin and zcashd.
pub fn bytes_in_display_order(&self) -> [u8; 32] {
let mut reversed_bytes = self.0;
reversed_bytes.reverse();
reversed_bytes
}

/// Convert bytes in big-endian byte-order into a `ChainHistoryMmrRootHash`.
///
/// Zebra displays transaction and block hashes in big-endian byte-order,
/// following the u256 convention set by Bitcoin and zcashd.
pub fn from_bytes_in_display_order(
bytes_in_display_order: &[u8; 32],
) -> ChainHistoryMmrRootHash {
let mut internal_byte_order = *bytes_in_display_order;
internal_byte_order.reverse();

ChainHistoryMmrRootHash(internal_byte_order)
}
}

impl ToHex for &ChainHistoryMmrRootHash {
fn encode_hex<T: FromIterator<char>>(&self) -> T {
self.bytes_in_display_order().encode_hex()
}

fn encode_hex_upper<T: FromIterator<char>>(&self) -> T {
self.bytes_in_display_order().encode_hex_upper()
}
}

impl ToHex for ChainHistoryMmrRootHash {
fn encode_hex<T: FromIterator<char>>(&self) -> T {
(&self).encode_hex()
}

fn encode_hex_upper<T: FromIterator<char>>(&self) -> T {
(&self).encode_hex_upper()
}
}

impl FromHex for ChainHistoryMmrRootHash {
type Error = <[u8; 32] as FromHex>::Error;

fn from_hex<T: AsRef<[u8]>>(hex: T) -> Result<Self, Self::Error> {
let mut hash = <[u8; 32]>::from_hex(hex)?;
hash.reverse();

Ok(hash.into())
}
}

/// A block commitment to chain history and transaction auth.
/// - the chain history tree for all ancestors in the current network upgrade,
/// and
Expand Down Expand Up @@ -212,6 +269,60 @@ impl ChainHistoryBlockTxAuthCommitmentHash {
.expect("32 byte array");
Self(hash_block_commitments)
}

/// Return the hash bytes in big-endian byte-order suitable for printing out byte by byte.
///
/// Zebra displays transaction and block hashes in big-endian byte-order,
/// following the u256 convention set by Bitcoin and zcashd.
pub fn bytes_in_display_order(&self) -> [u8; 32] {
let mut reversed_bytes = self.0;
reversed_bytes.reverse();
reversed_bytes
}

/// Convert bytes in big-endian byte-order into a `ChainHistoryBlockTxAuthCommitmentHash`.
///
/// Zebra displays transaction and block hashes in big-endian byte-order,
/// following the u256 convention set by Bitcoin and zcashd.
pub fn from_bytes_in_display_order(
bytes_in_display_order: &[u8; 32],
) -> ChainHistoryBlockTxAuthCommitmentHash {
let mut internal_byte_order = *bytes_in_display_order;
internal_byte_order.reverse();

ChainHistoryBlockTxAuthCommitmentHash(internal_byte_order)
}
}

impl ToHex for &ChainHistoryBlockTxAuthCommitmentHash {
fn encode_hex<T: FromIterator<char>>(&self) -> T {
self.bytes_in_display_order().encode_hex()
}

fn encode_hex_upper<T: FromIterator<char>>(&self) -> T {
self.bytes_in_display_order().encode_hex_upper()
}
}

impl ToHex for ChainHistoryBlockTxAuthCommitmentHash {
fn encode_hex<T: FromIterator<char>>(&self) -> T {
(&self).encode_hex()
}

fn encode_hex_upper<T: FromIterator<char>>(&self) -> T {
(&self).encode_hex_upper()
}
}

impl FromHex for ChainHistoryBlockTxAuthCommitmentHash {
type Error = <[u8; 32] as FromHex>::Error;

fn from_hex<T: AsRef<[u8]>>(hex: T) -> Result<Self, Self::Error> {
let mut hash = <[u8; 32]>::from_hex(hex)?;
hash.reverse();

Ok(hash.into())
}
}

/// Errors that can occur when checking RootHash consensus rules.
Expand Down
Loading

0 comments on commit 1424115

Please sign in to comment.