Skip to content

Commit

Permalink
feat: tx weight takes tariscript and output features into account [ig…
Browse files Browse the repository at this point in the history
…or] (#3411)

Description
---
- adds consensus encoding for tari script and output features
- igor: tx weight takes TariScript and OutputFeatures metadata into
  account as per #3368
- igor: weights updated as per #3368
- add `TransactionWeight` parameters for `weatherwax` and `igor` networks
  and set them in consensus constants
- set max block weight for `igor` (+95% adjust to allow similar number of
  max inputs/outputs/kernels ~2Mb)
- decouple chain_storage from `consensus_contstants` module to allow
  wallet to use it
- wallet: minor simplification/dedup code of coin split logic
- wallet: default fee per gram depending on network
- wallet and base node tests updated as needed

Motivation and Context
---
See #3368

How Has This Been Tested?
---
Existing tests updated, manually checked normal and one-sided transaction sending between console wallets/mobile on watherwax and igor
  • Loading branch information
sdbondi committed Oct 19, 2021
1 parent 81f01d2 commit 5bef3fd
Show file tree
Hide file tree
Showing 120 changed files with 2,106 additions and 1,247 deletions.
9 changes: 8 additions & 1 deletion Cargo.lock

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

Expand Up @@ -22,14 +22,12 @@

use crate::tari_rpc as grpc;
use std::convert::TryFrom;
use tari_core::{
consensus::{ConsensusConstants, KERNEL_WEIGHT, WEIGHT_PER_INPUT, WEIGHT_PER_OUTPUT},
proof_of_work::PowAlgorithm,
};
use tari_core::{consensus::ConsensusConstants, proof_of_work::PowAlgorithm};

impl From<ConsensusConstants> for grpc::ConsensusConstants {
fn from(cc: ConsensusConstants) -> Self {
let (emission_initial, emission_decay, emission_tail) = cc.emission_amounts();
let weight_params = cc.transaction_weight().params();
Self {
coinbase_lock_height: cc.coinbase_lock_height(),
blockchain_version: cc.blockchain_version().into(),
Expand All @@ -43,9 +41,9 @@ impl From<ConsensusConstants> for grpc::ConsensusConstants {
emission_decay: emission_decay.to_vec(),
emission_tail: emission_tail.into(),
min_blake_pow_difficulty: cc.min_pow_difficulty(PowAlgorithm::Sha3).into(),
block_weight_inputs: WEIGHT_PER_INPUT,
block_weight_outputs: WEIGHT_PER_OUTPUT,
block_weight_kernels: KERNEL_WEIGHT,
block_weight_inputs: weight_params.input_weight,
block_weight_outputs: weight_params.output_weight,
block_weight_kernels: weight_params.kernel_weight,
}
}
}
Expand Up @@ -22,7 +22,7 @@

use crate::tari_rpc as grpc;
use std::convert::TryFrom;
use tari_core::chain_storage::{ChainStorageError, HistoricalBlock};
use tari_core::{blocks::HistoricalBlock, chain_storage::ChainStorageError};

impl TryFrom<HistoricalBlock> for grpc::HistoricalBlock {
type Error = ChainStorageError;
Expand Down
2 changes: 1 addition & 1 deletion applications/tari_base_node/src/builder.rs
Expand Up @@ -250,7 +250,7 @@ async fn build_node_context(
Box::new(TxInputAndMaturityValidator::new(blockchain_db.clone())),
Box::new(TxConsensusValidator::new(blockchain_db.clone())),
]);
let mempool = Mempool::new(MempoolConfig::default(), Arc::new(mempool_validator));
let mempool = Mempool::new(MempoolConfig::default(), rules.clone(), Arc::new(mempool_validator));

//---------------------------------- Base Node --------------------------------------------//
debug!(target: LOG_TARGET, "Creating base node state machine.");
Expand Down
13 changes: 8 additions & 5 deletions applications/tari_base_node/src/command_handler.rs
Expand Up @@ -51,8 +51,8 @@ use tari_core::{
state_machine_service::states::{PeerMetadata, StatusInfo},
LocalNodeCommsInterface,
},
blocks::BlockHeader,
chain_storage::{async_db::AsyncBlockchainDb, ChainHeader, LMDBDatabase},
blocks::{BlockHeader, ChainHeader},
chain_storage::{async_db::AsyncBlockchainDb, LMDBDatabase},
consensus::ConsensusManager,
mempool::service::LocalMempoolService,
proof_of_work::PowAlgorithm,
Expand All @@ -77,6 +77,7 @@ pub enum StatusOutput {
pub struct CommandHandler {
executor: runtime::Handle,
config: Arc<GlobalConfig>,
consensus_rules: ConsensusManager,
blockchain_db: AsyncBlockchainDb<LMDBDatabase>,
discovery_service: DhtDiscoveryRequester,
dht_metrics_collector: MetricsCollectorHandle,
Expand All @@ -96,6 +97,7 @@ impl CommandHandler {
Self {
executor,
config: ctx.config(),
consensus_rules: ctx.consensus_rules().clone(),
blockchain_db: ctx.blockchain_db().into(),
discovery_service: ctx.base_node_dht().discovery_service_requester(),
dht_metrics_collector: ctx.base_node_dht().metrics_collector(),
Expand All @@ -120,6 +122,7 @@ impl CommandHandler {
let mut metrics = self.dht_metrics_collector.clone();
let mut rpc_server = self.rpc_server.clone();
let config = self.config.clone();
let consensus_rules = self.consensus_rules.clone();

self.executor.spawn(async move {
let mut status_line = StatusLine::new();
Expand All @@ -145,6 +148,7 @@ impl CommandHandler {
),
);

let constants = consensus_rules.consensus_constants(metadata.height_of_longest_chain());
let mempool_stats = mempool.get_mempool_stats().await.unwrap();
status_line.add_field(
"Mempool",
Expand All @@ -155,7 +159,7 @@ impl CommandHandler {
if mempool_stats.total_weight == 0 {
0
} else {
1 + mempool_stats.total_weight / 19500
1 + mempool_stats.total_weight / constants.get_max_block_transaction_weight()
},
),
);
Expand Down Expand Up @@ -1000,7 +1004,7 @@ impl CommandHandler {
pow_algo: Option<PowAlgorithm>,
) {
let db = self.blockchain_db.clone();
let network = self.config.network;
let consensus_rules = self.consensus_rules.clone();
self.executor.spawn(async move {
let mut output = try_or_print!(File::create(&filename));

Expand All @@ -1016,7 +1020,6 @@ impl CommandHandler {

let start_height = cmp::max(start_height, 1);
let mut prev_header = try_or_print!(db.fetch_chain_header(start_height - 1).await);
let consensus_rules = ConsensusManager::builder(network).build();

writeln!(
output,
Expand Down
5 changes: 4 additions & 1 deletion applications/tari_base_node/src/grpc/blocks.rs
Expand Up @@ -21,7 +21,10 @@
// USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

use std::cmp;
use tari_core::{base_node::LocalNodeCommsInterface, blocks::BlockHeader, chain_storage::HistoricalBlock};
use tari_core::{
base_node::LocalNodeCommsInterface,
blocks::{BlockHeader, HistoricalBlock},
};
use tonic::Status;

// The maximum number of blocks that can be requested at a time. These will be streamed to the
Expand Down
2 changes: 1 addition & 1 deletion applications/tari_console_wallet/src/ui/app.rs
Expand Up @@ -85,7 +85,7 @@ impl<B: Backend> App<B> {

let tabs = TabsContainer::<B>::new(title.clone())
.add("Transactions".into(), Box::new(TransactionsTab::new()))
.add("Send".into(), Box::new(SendTab::new()))
.add("Send".into(), Box::new(SendTab::new(&app_state)))
.add("Receive".into(), Box::new(ReceiveTab::new()))
.add("Network".into(), Box::new(NetworkTab::new(base_node_selected)))
.add("Log".into(), Box::new(LogTab::new()))
Expand Down
17 changes: 8 additions & 9 deletions applications/tari_console_wallet/src/ui/components/send_tab.rs
Expand Up @@ -8,7 +8,6 @@ use crate::{
utils::formatting::display_compressed_string,
};
use tari_core::transactions::tari_amount::MicroTari;
use tari_wallet::types::DEFAULT_FEE_PER_GRAM;
use tokio::{runtime::Handle, sync::watch};
use tui::{
backend::Backend,
Expand Down Expand Up @@ -40,19 +39,19 @@ pub struct SendTab {
}

impl SendTab {
pub fn new() -> Self {
pub fn new(app_state: &AppState) -> Self {
Self {
balance: Balance::new(),
send_input_mode: SendInputMode::None,
edit_contact_mode: ContactInputMode::None,
show_contacts: false,
show_edit_contact: false,
to_field: "".to_string(),
amount_field: "".to_string(),
fee_field: u64::from(DEFAULT_FEE_PER_GRAM).to_string(),
message_field: "".to_string(),
alias_field: "".to_string(),
public_key_field: "".to_string(),
to_field: String::new(),
amount_field: String::new(),
fee_field: app_state.get_default_fee_per_gram().as_u64().to_string(),
message_field: String::new(),
alias_field: String::new(),
public_key_field: String::new(),
error_message: None,
success_message: None,
contacts_list_state: WindowedListState::new(),
Expand Down Expand Up @@ -368,7 +367,7 @@ impl SendTab {
if reset_fields {
self.to_field = "".to_string();
self.amount_field = "".to_string();
self.fee_field = u64::from(DEFAULT_FEE_PER_GRAM).to_string();
self.fee_field = app_state.get_default_fee_per_gram().as_u64().to_string();
self.message_field = "".to_string();
self.send_input_mode = SendInputMode::None;
self.send_result_watch = Some(rx);
Expand Down
93 changes: 60 additions & 33 deletions applications/tari_console_wallet/src/ui/state/app_state.rs
Expand Up @@ -50,7 +50,10 @@ use tari_comms::{
types::CommsPublicKey,
NodeIdentity,
};
use tari_core::transactions::tari_amount::{uT, MicroTari};
use tari_core::transactions::{
tari_amount::{uT, MicroTari},
weight::TransactionWeight,
};
use tari_shutdown::ShutdownSignal;
use tari_wallet::{
base_node_service::{handle::BaseNodeEventReceiver, service::BaseNodeState},
Expand Down Expand Up @@ -460,6 +463,19 @@ impl AppState {
self.update_cache().await;
}
}

pub fn get_default_fee_per_gram(&self) -> MicroTari {
use Network::*;
// TODO: TBD
match self.node_config.network {
MainNet => MicroTari(5),
LocalNet => MicroTari(5),
Ridcully => MicroTari(25),
Stibbons => MicroTari(25),
Weatherwax => MicroTari(25),
Igor => MicroTari(5),
}
}
}
pub struct AppStateInner {
updated: bool,
Expand Down Expand Up @@ -495,6 +511,16 @@ impl AppStateInner {
}
}

pub fn get_transaction_weight(&self) -> TransactionWeight {
*self
.wallet
.network
.create_consensus_constants()
.last()
.unwrap()
.transaction_weight()
}

pub async fn refresh_full_transaction_state(&mut self) -> Result<(), UiError> {
let mut pending_transactions: Vec<CompletedTransaction> = Vec::new();
pending_transactions.extend(
Expand All @@ -521,7 +547,7 @@ impl AppStateInner {
});
self.data.pending_txs = pending_transactions
.iter()
.map(|tx| CompletedTransactionInfo::from(tx.clone()))
.map(|tx| CompletedTransactionInfo::from_completed_transaction(tx.clone(), &self.get_transaction_weight()))
.collect();

let mut completed_transactions: Vec<CompletedTransaction> = Vec::new();
Expand Down Expand Up @@ -553,7 +579,7 @@ impl AppStateInner {

self.data.completed_txs = completed_transactions
.iter()
.map(|tx| CompletedTransactionInfo::from(tx.clone()))
.map(|tx| CompletedTransactionInfo::from_completed_transaction(tx.clone(), &self.get_transaction_weight()))
.collect();
self.updated = true;
Ok(())
Expand Down Expand Up @@ -596,7 +622,8 @@ impl AppStateInner {
});
},
Some(tx) => {
let tx = CompletedTransactionInfo::from(CompletedTransaction::from(tx));
let tx =
CompletedTransactionInfo::from_completed_transaction(tx.into(), &self.get_transaction_weight());
if let Some(index) = self.data.pending_txs.iter().position(|i| i.tx_id == tx_id) {
if tx.status == TransactionStatus::Pending && !tx.cancelled {
self.data.pending_txs[index] = tx;
Expand Down Expand Up @@ -860,42 +887,42 @@ pub struct CompletedTransactionInfo {
pub outputs_count: usize,
}

impl From<CompletedTransaction> for CompletedTransactionInfo {
fn from(completed_transaction: CompletedTransaction) -> Self {
let excess_signature = if completed_transaction.transaction.body.kernels().is_empty() {
"".to_string()
} else {
completed_transaction.transaction.body.kernels()[0]
.excess_sig
.get_signature()
.to_hex()
};

impl CompletedTransactionInfo {
pub fn from_completed_transaction(tx: CompletedTransaction, transaction_weighting: &TransactionWeight) -> Self {
let excess_signature = tx
.transaction
.first_kernel_excess_sig()
.map(|s| s.get_signature().to_hex())
.unwrap_or_default();
let is_coinbase = tx.is_coinbase();
let weight = tx.transaction.calculate_weight(transaction_weighting);
let inputs_count = tx.transaction.body.inputs().len();
let outputs_count = tx.transaction.body.outputs().len();
Self {
tx_id: completed_transaction.tx_id,
source_public_key: completed_transaction.source_public_key.clone(),
destination_public_key: completed_transaction.destination_public_key.clone(),
amount: completed_transaction.amount,
fee: completed_transaction.fee,
tx_id: tx.tx_id,
source_public_key: tx.source_public_key.clone(),
destination_public_key: tx.destination_public_key.clone(),
amount: tx.amount,
fee: tx.fee,
excess_signature,
maturity: completed_transaction
maturity: tx
.transaction
.body
.outputs()
.first()
.map(|o| o.features.maturity)
.unwrap_or_else(|| 0),
status: completed_transaction.status.clone(),
message: completed_transaction.message.clone(),
timestamp: completed_transaction.timestamp,
cancelled: completed_transaction.cancelled,
direction: completed_transaction.direction.clone(),
valid: completed_transaction.valid,
mined_height: completed_transaction.mined_height,
is_coinbase: completed_transaction.is_coinbase(),
weight: completed_transaction.transaction.calculate_weight(),
inputs_count: completed_transaction.transaction.body.inputs().len(),
outputs_count: completed_transaction.transaction.body.outputs().len(),
.unwrap_or(0),
status: tx.status,
message: tx.message,
timestamp: tx.timestamp,
cancelled: tx.cancelled,
direction: tx.direction,
valid: tx.valid,
mined_height: tx.mined_height,
is_coinbase,
weight,
inputs_count,
outputs_count,
}
}
}
Expand Down
6 changes: 3 additions & 3 deletions applications/test_faucet/src/main.rs
Expand Up @@ -14,8 +14,8 @@ use tokio::{sync::mpsc, task};

use tari_common_types::types::{Commitment, PrivateKey};
use tari_core::transactions::{
helpers,
tari_amount::{MicroTari, T},
test_helpers,
transaction::{KernelFeatures, OutputFeatures, TransactionKernel, TransactionOutput},
CryptoFactories,
};
Expand Down Expand Up @@ -65,7 +65,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
task::spawn(async move {
let result = task::spawn_blocking(move || {
let script = script!(Nop);
let (utxo, key, _) = helpers::create_utxo(value, &fc, feature, &script);
let (utxo, key, _) = test_helpers::create_utxo(value, &fc, feature, &script);
print!(".");
(utxo, key, value)
})
Expand Down Expand Up @@ -110,7 +110,7 @@ async fn write_keys(mut rx: mpsc::Receiver<(TransactionOutput, PrivateKey, Micro
Err(e) => println!("{}", e.to_string()),
}
}
let (pk, sig) = helpers::create_random_signature_from_s_key(key_sum, 0.into(), 0);
let (pk, sig) = test_helpers::create_random_signature_from_s_key(key_sum, 0.into(), 0);
let excess = Commitment::from_public_key(&pk);
let kernel = TransactionKernel {
features: KernelFeatures::empty(),
Expand Down

0 comments on commit 5bef3fd

Please sign in to comment.