chore: Move fee logic out of primitives (#174)

This commit is contained in:
Santiago Carmuega 2022-08-13 15:45:16 -03:00 committed by GitHub
parent 9caa176785
commit 90fa3b02f0
6 changed files with 93 additions and 76 deletions

View file

@ -0,0 +1,63 @@
use pallas_codec::minicbor::to_vec;
use pallas_primitives::byron;
pub struct PolicyParams {
constant: u64,
size_coeficient: u64,
}
impl Default for PolicyParams {
fn default() -> Self {
Self {
constant: 155_381_000_000_000u64,
size_coeficient: 43_946_000_000u64,
}
}
}
pub fn compute_linear_fee_policy(tx_size: u64, params: &PolicyParams) -> u64 {
let nanos = params.constant + (tx_size * params.size_coeficient);
let loves = nanos / 1_000_000_000;
let rem = match nanos % 1_000_000_000 {
0 => 0u64,
_ => 1u64,
};
loves + rem
}
pub fn compute_byron_fee(tx: &byron::MintedTxPayload, params: Option<&PolicyParams>) -> u64 {
let tx_size = to_vec(&tx).unwrap().len();
match params {
Some(params) => compute_linear_fee_policy(tx_size as u64, params),
None => compute_linear_fee_policy(tx_size as u64, &PolicyParams::default()),
}
}
#[cfg(test)]
mod tests {
use super::compute_byron_fee;
#[test]
fn known_fee_matches() {
// TODO: expand this test to include more test blocks
let block_idx = 1;
let block_str = include_str!("../../test_data/byron4.block");
let block_bytes = hex::decode(block_str).expect(&format!("bad block file {}", block_idx));
let block = crate::MultiEraBlock::decode_byron(&block_bytes).unwrap();
let txs = block.txs();
// don't want to pass if we don't have tx in the block
assert!(txs.len() > 0);
for tx in txs.iter().take(1) {
let byron = tx.as_byron().unwrap();
let fee = compute_byron_fee(&byron, None);
assert_eq!(fee, 171070);
}
}
}

View file

@ -12,6 +12,7 @@ use pallas_primitives::{alonzo, babbage, byron};
pub mod block;
pub mod cert;
pub mod era;
pub mod fees;
pub mod hashes;
pub mod header;
pub mod input;

View file

@ -1,8 +1,10 @@
use crate::hashes::ToHash;
use std::{borrow::Cow, ops::Deref};
use pallas_codec::{minicbor, utils::KeepRaw};
use pallas_crypto::hash::Hash;
use pallas_primitives::{alonzo, babbage, byron};
use std::{borrow::Cow, ops::Deref};
use crate::hashes::ToHash;
use crate::{
Era, MultiEraCert, MultiEraInput, MultiEraMeta, MultiEraMint, MultiEraOutput, MultiEraSigners,
@ -232,6 +234,28 @@ impl<'b> MultiEraTx<'b> {
}
}
pub fn fee(&self) -> Option<u64> {
match self {
MultiEraTx::AlonzoCompatible(x, _) => Some(x.transaction_body.fee),
MultiEraTx::Babbage(x) => Some(x.transaction_body.fee),
MultiEraTx::Byron(_) => None,
}
}
/// Returns the fee or attempts to compute it
///
/// If the fee is available as part of the tx data (post-byron), this
/// function will return the existing value. For byron txs, this method
/// attempts to compute the value by using the linear fee policy.
#[cfg(feature = "unstable")]
pub fn fee_or_compute(&self) -> u64 {
match self {
MultiEraTx::AlonzoCompatible(x, _) => x.transaction_body.fee,
MultiEraTx::Babbage(x) => x.transaction_body.fee,
MultiEraTx::Byron(x) => crate::fees::compute_byron_fee(x, None),
}
}
fn aux_data(&self) -> Option<&KeepRaw<'_, alonzo::AuxiliaryData>> {
match self {
MultiEraTx::AlonzoCompatible(x, _) => match &x.auxiliary_data {