redgold_schema/
fee_validator.rs

1use crate::helpers::with_metadata_hashable::WithMetadataHashable;
2use crate::structs::{Address, SupportedCurrency, Transaction};
3use itertools::Itertools;
4
5pub const MIN_RDG_SATS_FEE: i64 = 1000;
6
7pub trait TransactionFeeValidator {
8    fn validate_fee(&self, addresses: &Vec<Address>) -> bool;
9    fn validate_fee_only(&self, addresses: &Vec<Address>) -> bool;
10}
11
12pub trait ResolvedTransactionFeeValidator {
13    fn validate_resolved_fee(&self, addresses: &Vec<Address>, max_parent_time: i64) -> bool;
14}
15
16impl ResolvedTransactionFeeValidator for Transaction {
17    fn validate_resolved_fee(&self, addresses: &Vec<Address>, max_parent_time: i64) -> bool {
18        let small_num_outputs = self.outputs.len() < 5;
19        let total_amount = self.output_amount_total().to_fractional();
20        let min_stake = total_amount >= 1.0;
21        let matches_zero_fee_condition = min_stake && small_num_outputs;
22        if self.validate_fee_only(addresses) {
23            return true;
24        }
25
26        if matches_zero_fee_condition {
27            let self_time = self.time().cloned().unwrap_or(0);
28            let delta = self_time - max_parent_time;
29            let mut min_expected_delta = 30 * 1000;
30            if !min_stake {
31                min_expected_delta = ((min_expected_delta as f64) / total_amount) as i64;
32            }
33
34            if delta > min_expected_delta {
35                return true;
36            }
37        }
38        false
39    }
40}
41
42
43impl TransactionFeeValidator for Transaction {
44    fn validate_fee(&self, addresses: &Vec<Address>) -> bool {
45
46        let small_num_outputs = self.outputs.len() < 5;
47        let matches_zero_fee_condition = self.output_amount_total().to_fractional() >= 1.0 && small_num_outputs;
48        matches_zero_fee_condition || self.validate_fee_only(addresses)
49    }
50
51    fn validate_fee_only(&self, addresses: &Vec<Address>) -> bool {
52        let value = self.output_address_amounts_opt()
53            .filter(|(address, amount)| {
54                addresses.contains(address) && amount.currency_or() == SupportedCurrency::Redgold
55            }).map(|(_, amount)| amount.amount).sum::<i64>();
56        let fee_condition = value >= MIN_RDG_SATS_FEE;
57        fee_condition
58    }
59}