Skip to content

Commit

Permalink
Merge pull request #895 from anoma/tiago/ethbridge/process-proposal-a…
Browse files Browse the repository at this point in the history
…llocator

Plug `BlockSpaceAllocator` logic into `ProcessProposal`
  • Loading branch information
sug0 authored Dec 20, 2022
2 parents 698cbc7 + 93fcdda commit a8f5abf
Show file tree
Hide file tree
Showing 13 changed files with 248 additions and 178 deletions.
4 changes: 2 additions & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion apps/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ eyre = "0.6.5"
flate2 = "1.0.22"
file-lock = "2.0.2"
futures = "0.3"
index-set = {git = "https://github.com/heliaxdev/index-set", tag = "v0.5.0"}
index-set = {git = "https://github.com/heliaxdev/index-set", tag = "v0.7.1"}
itertools = "0.10.1"
libc = "0.2.97"
libloading = "0.7.2"
Expand Down
2 changes: 1 addition & 1 deletion apps/src/lib/client/tx.rs
Original file line number Diff line number Diff line change
Expand Up @@ -778,7 +778,7 @@ impl ShieldedContext {
/// associated to notes, memos, and diversifiers. And the set of notes that
/// we have spent are updated. The witness map is maintained to make it
/// easier to construct note merkle paths in other code. See
/// https://zips.z.cash/protocol/protocol.pdf#scan
/// <https://zips.z.cash/protocol/protocol.pdf#scan>
pub fn scan_tx(
&mut self,
height: BlockHeight,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,9 @@ use std::marker::PhantomData;
use namada::core::ledger::storage::{self, Storage};
use namada::ledger::queries_ext::QueriesExt;

#[allow(unused_imports)]
use crate::facade::tendermint_proto::abci::RequestPrepareProposal;

/// Block space allocation failure status responses.
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
pub enum AllocFailure {
Expand Down Expand Up @@ -160,7 +163,7 @@ impl<State> BlockSpaceAllocator<State> {
/// Allotted space for a batch of transactions of the same kind in some
/// proposed block, measured in bytes.
#[derive(Debug, Copy, Clone, Default)]
struct TxBin {
pub struct TxBin {
/// The current space utilized by the batch of transactions.
occupied_space_in_bytes: u64,
/// The maximum space the batch of transactions may occupy.
Expand All @@ -171,7 +174,7 @@ impl TxBin {
/// Return a new [`TxBin`] with a total allotted space equal to the
/// floor of the fraction `frac` of the available block space `max_bytes`.
#[inline]
fn init_over_ratio(max_bytes: u64, frac: threshold::Threshold) -> Self {
pub fn init_over_ratio(max_bytes: u64, frac: threshold::Threshold) -> Self {
let allotted_space_in_bytes = frac.over(max_bytes);
Self {
allotted_space_in_bytes,
Expand All @@ -181,13 +184,13 @@ impl TxBin {

/// Return the amount of space left in this [`TxBin`].
#[inline]
fn space_left_in_bytes(&self) -> u64 {
pub fn space_left_in_bytes(&self) -> u64 {
self.allotted_space_in_bytes - self.occupied_space_in_bytes
}

/// Construct a new [`TxBin`], with a capacity of `max_bytes`.
#[inline]
fn init(max_bytes: u64) -> Self {
pub fn init(max_bytes: u64) -> Self {
Self {
allotted_space_in_bytes: max_bytes,
occupied_space_in_bytes: 0,
Expand All @@ -197,15 +200,15 @@ impl TxBin {
/// Shrink the allotted space of this [`TxBin`] to whatever
/// space is currently being utilized.
#[inline]
fn shrink_to_fit(&mut self) {
pub fn shrink_to_fit(&mut self) {
self.allotted_space_in_bytes = self.occupied_space_in_bytes;
}

/// Try to dump a new transaction into this [`TxBin`].
///
/// Signal the caller if the tx is larger than its max
/// allotted bin space.
fn try_dump(&mut self, tx: &[u8]) -> Result<(), AllocFailure> {
pub fn try_dump(&mut self, tx: &[u8]) -> Result<(), AllocFailure> {
let tx_len = tx.len() as u64;
if tx_len > self.allotted_space_in_bytes {
let bin_size = self.allotted_space_in_bytes;
Expand All @@ -222,7 +225,7 @@ impl TxBin {
}
}

mod threshold {
pub mod threshold {
//! Transaction allotment thresholds.
use num_rational::Ratio;
Expand Down
6 changes: 4 additions & 2 deletions apps/src/lib/node/ledger/shell/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
//! and [`Shell::process_proposal`] must be also reverted
//! (unless we can simply overwrite them in the next block).
//! More info in <https://github.com/anoma/namada/issues/362>.
mod block_space_alloc;
mod finalize_block;
mod governance;
mod init_chain;
Expand Down Expand Up @@ -124,8 +125,8 @@ pub enum ErrorCodes {
ExtraTxs = 5,
Undecryptable = 6,
InvalidVoteExtension = 7,
// NOTE: keep these values in sync with
// [`ErrorCodes::is_recoverable`]
AllocationError = 8, /* NOTE: keep these values in sync with
* [`ErrorCodes::is_recoverable`] */
}

impl ErrorCodes {
Expand Down Expand Up @@ -1019,6 +1020,7 @@ mod test_utils {
/// Same as [`TestShell::new_at_height`], but returns a shell at block
/// height 0.
#[inline]
#[allow(dead_code)]
pub fn new() -> (Self, UnboundedReceiver<Vec<u8>>, Sender<EthereumEvent>)
{
Self::new_at_height(BlockHeight(1))
Expand Down
130 changes: 64 additions & 66 deletions apps/src/lib/node/ledger/shell/prepare_proposal.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
//! Implementation of the [`RequestPrepareProposal`] ABCI++ method for the Shell
mod block_space_alloc;

#[cfg(not(feature = "abcipp"))]
use index_set::vec::VecIndexSet;
use namada::core::hints;
Expand All @@ -18,13 +16,13 @@ use namada::types::transaction::{AffineCurve, DecryptedTx, EllipticCurve};
#[cfg(feature = "abcipp")]
use namada::types::vote_extensions::VoteExtensionDigest;

use self::block_space_alloc::states::{
use super::super::*;
use super::block_space_alloc::states::{
BuildingDecryptedTxBatch, BuildingProtocolTxBatch,
EncryptedTxBatchAllocator, FillingRemainingSpace, NextState,
NextStateWithEncryptedTxs, NextStateWithoutEncryptedTxs, TryAlloc,
};
use self::block_space_alloc::{AllocFailure, BlockSpaceAllocator};
use super::super::*;
use super::block_space_alloc::{AllocFailure, BlockSpaceAllocator};
#[cfg(feature = "abcipp")]
use crate::facade::tendermint_proto::abci::ExtendedCommitInfo;
use crate::facade::tendermint_proto::abci::RequestPrepareProposal;
Expand Down Expand Up @@ -112,6 +110,67 @@ where
response::PrepareProposal { txs }
}

/// Builds a batch of DKG decrypted transactions.
// NOTE: we won't have frontrunning protection until V2 of the
// Anoma protocol; Namada runs V1, therefore this method is
// essentially a NOOP
//
// sources:
// - https://specs.namada.net/main/releases/v2.html
// - https://github.com/anoma/ferveo
fn build_decrypted_txs(
&mut self,
mut alloc: BlockSpaceAllocator<BuildingDecryptedTxBatch>,
) -> (Vec<TxBytes>, BlockSpaceAllocator<BuildingProtocolTxBatch>) {
// TODO: This should not be hardcoded
let privkey =
<EllipticCurve as PairingEngine>::G2Affine::prime_subgroup_generator();

let txs = self
.storage
.tx_queue
.iter()
.map(|tx| {
Tx::from(match tx.decrypt(privkey) {
Ok(tx) => DecryptedTx::Decrypted(tx),
_ => DecryptedTx::Undecryptable(tx.clone()),
})
.to_bytes()
})
// TODO: make sure all decrypted txs are accepted
.take_while(|tx_bytes| {
alloc.try_alloc(&tx_bytes[..]).map_or_else(
|status| match status {
AllocFailure::Rejected { bin_space_left } => {
tracing::warn!(
?tx_bytes,
bin_space_left,
proposal_height =
?self.storage.get_current_decision_height(),
"Dropping decrypted tx from the current proposal",
);
false
}
AllocFailure::OverflowsBin { bin_size } => {
tracing::warn!(
?tx_bytes,
bin_size,
proposal_height =
?self.storage.get_current_decision_height(),
"Dropping large decrypted tx from the current proposal",
);
true
}
},
|()| true,
)
})
.collect();
let alloc = alloc.next_state();

(txs, alloc)
}

/// Builds a batch of vote extension transactions, comprised of Ethereum
/// events and, optionally, a validator set update.
#[cfg(feature = "abcipp")]
Expand Down Expand Up @@ -322,67 +381,6 @@ where
(txs, alloc)
}

/// Builds a batch of DKG decrypted transactions.
// NOTE: we won't have frontrunning protection until V2 of the
// Anoma protocol; Namada runs V1, therefore this method is
// essentially a NOOP
//
// sources:
// - https://specs.namada.net/main/releases/v2.html
// - https://github.com/anoma/ferveo
fn build_decrypted_txs(
&mut self,
mut alloc: BlockSpaceAllocator<BuildingDecryptedTxBatch>,
) -> (Vec<TxBytes>, BlockSpaceAllocator<BuildingProtocolTxBatch>) {
// TODO: This should not be hardcoded
let privkey =
<EllipticCurve as PairingEngine>::G2Affine::prime_subgroup_generator();

let txs = self
.storage
.tx_queue
.iter()
.map(|tx| {
Tx::from(match tx.decrypt(privkey) {
Ok(tx) => DecryptedTx::Decrypted(tx),
_ => DecryptedTx::Undecryptable(tx.clone()),
})
.to_bytes()
})
// TODO: make sure all decrypted txs are accepted
.take_while(|tx_bytes| {
alloc.try_alloc(&tx_bytes[..]).map_or_else(
|status| match status {
AllocFailure::Rejected { bin_space_left } => {
tracing::warn!(
?tx_bytes,
bin_space_left,
proposal_height =
?self.storage.get_current_decision_height(),
"Dropping decrypted tx from the current proposal",
);
false
}
AllocFailure::OverflowsBin { bin_size } => {
tracing::warn!(
?tx_bytes,
bin_size,
proposal_height =
?self.storage.get_current_decision_height(),
"Dropping large decrypted tx from the current proposal",
);
true
}
},
|()| true,
)
})
.collect();
let alloc = alloc.next_state();

(txs, alloc)
}

/// Builds a batch of transactions that can fit in the
/// remaining space of the [`BlockSpaceAllocator`].
#[cfg(feature = "abcipp")]
Expand Down
Loading

0 comments on commit a8f5abf

Please sign in to comment.