use crate::builders::batch_tools::cbor_calculator::CborCalculator;
use crate::serialization::map_names::WitnessSetNames;
use crate::*;
use std::collections::HashSet;
use crate::builders::fakes::{fake_raw_key_public, fake_raw_key_sig};
use crate::fakes::fake_bootstrap_witness;
#[derive(Clone)]
pub(super) struct WitnessesCalculator {
adresses: BTreeSet<Address>,
vkeys_count: u64,
boostrap_count: u64,
bootsraps: Vec<ByronAddress>,
used_fields: HashSet<WitnessSetNames>,
total_size: usize,
}
impl WitnessesCalculator {
pub(super) fn new() -> Self {
Self {
adresses: BTreeSet::new(),
vkeys_count: 0,
boostrap_count: 0,
bootsraps: Vec::new(),
used_fields: HashSet::new(),
total_size: 0,
}
}
pub(super) fn add_address(&mut self, address: &Address) -> Result<(), JsError> {
if self.adresses.contains(address) {
return Ok(());
}
self.adresses.insert(address.clone());
match &BaseAddress::from_address(address) {
Some(addr) => {
match &addr.payment_cred().to_keyhash() {
Some(_) => self.add_vkey(),
None => (),
}
match &addr.payment_cred().to_scripthash() {
Some(_) => {
return Err(JsError::from_str(
"Script input is not supported for send all",
))
}
None => (),
}
}
None => (),
}
match &EnterpriseAddress::from_address(address) {
Some(addr) => {
match &addr.payment_cred().to_keyhash() {
Some(_) => self.add_vkey(),
None => (),
}
match &addr.payment_cred().to_scripthash() {
Some(_) => {
return Err(JsError::from_str(
"Script input is not supported for send all",
))
}
None => (),
}
}
None => (),
}
match &PointerAddress::from_address(address) {
Some(addr) => {
match &addr.payment_cred().to_keyhash() {
Some(_) => self.add_vkey(),
None => (),
}
match &addr.payment_cred().to_scripthash() {
Some(_) => {
return Err(JsError::from_str(
"Script input is not supported for send all",
))
}
None => (),
}
}
None => (),
}
match &ByronAddress::from_address(address) {
Some(addr) => self.add_boostrap(addr),
None => (),
}
Ok(())
}
pub(super) fn get_full_size(&self) -> usize {
self.total_size
}
pub(super) fn create_mock_witnesses_set(&self) -> TransactionWitnessSet {
let fake_sig = fake_raw_key_sig();
let vkeys = match self.vkeys_count {
0 => None,
x => {
let mut result = Vkeywitnesses::new();
for i in 0..x {
let raw_key_public = fake_raw_key_public(i);
let fake_vkey_witness = Vkeywitness::new(&Vkey::new(&raw_key_public), &fake_sig);
result.add(&fake_vkey_witness.clone());
}
Some(result)
}
};
let bootstrap_keys = match self.boostrap_count {
0 => None,
_x => {
let mut result = BootstrapWitnesses::new();
let mut number = 0;
for boostrap_address in &self.bootsraps {
number += 1;
result.add(&fake_bootstrap_witness(number, boostrap_address));
}
Some(result)
}
};
TransactionWitnessSet::new_with_partial_dedup(
vkeys,
None,
bootstrap_keys,
None,
None,
None,
)
}
fn add_vkey(&mut self) {
if self.vkeys_count == 0 {
if self.used_fields.len() > 0 {
self.total_size -=
CborCalculator::get_witnesses_set_struct_size(&self.used_fields);
}
self.used_fields.insert(WitnessSetNames::Vkeys);
self.total_size += CborCalculator::get_witnesses_set_struct_size(&self.used_fields);
}
if self.vkeys_count != 0 {
self.total_size -= CborCalculator::get_wrapped_struct_size(self.vkeys_count);
}
self.vkeys_count += 1;
self.total_size += CborCalculator::get_wrapped_struct_size(self.vkeys_count);
self.total_size += CborCalculator::get_fake_vkey_size();
}
fn add_boostrap(&mut self, address: &ByronAddress) {
self.bootsraps.push(address.clone());
if self.boostrap_count == 0 {
if self.used_fields.len() > 0 {
self.total_size -=
CborCalculator::get_witnesses_set_struct_size(&self.used_fields);
}
self.used_fields.insert(WitnessSetNames::Bootstraps);
self.total_size += CborCalculator::get_witnesses_set_struct_size(&self.used_fields);
}
if self.boostrap_count != 0 {
self.total_size -= CborCalculator::get_wrapped_struct_size(self.boostrap_count);
}
self.boostrap_count += 1;
self.total_size += CborCalculator::get_wrapped_struct_size(self.boostrap_count);
self.total_size += CborCalculator::get_boostrap_witness_size(address);
}
}