Skip to content

Commit

Permalink
feat: validations design and connection with napi validation calls
Browse files Browse the repository at this point in the history
  • Loading branch information
mikarasv committed Apr 15, 2024
1 parent 3d70eea commit c17c69a
Show file tree
Hide file tree
Showing 13 changed files with 618 additions and 119 deletions.
95 changes: 65 additions & 30 deletions napi-pallas/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,47 +4,82 @@
/* auto-generated by NAPI-RS */

export interface ShelleyPart {
isScript: boolean;
hash?: string;
pointer?: string;
isScript: boolean
hash?: string
pointer?: string
}
export interface AddressDiagnostic {
kind: string;
network?: string;
paymentPart?: ShelleyPart;
delegationPart?: ShelleyPart;
byronCbor?: string;
kind: string
network?: string
paymentPart?: ShelleyPart
delegationPart?: ShelleyPart
byronCbor?: string
}
export interface Output {
error?: string;
bytes?: string;
address?: AddressDiagnostic;
error?: string
bytes?: string
address?: AddressDiagnostic
}
export interface ValidationContext {
epoch: number
minFeeA: number
minFeeB: number
maxBlockSize: number
maxTxSize: number
maxBlockHeaderSize: number
keyDeposit: number
poolDeposit: number
eMax: number
nOpt: number
a0: number
rho: number
tau: number
decentralisationParam: number
extraEntropy: number
protocolMajorVer: number
protocolMinorVer: number
minUtxo: number
minPoolCost: number
priceMem: number
priceStep: number
maxTxExMem: number
maxTxExSteps: number
maxBlockExMem: number
maxBlockExSteps: number
maxValSize: number
collateralPercent: number
maxCollateralInputs: number
coinsPerUtxoSize: number
coinsPerUtxoWord: number
network: string
era: string
blockSlot: number
}
export interface Attribute {
topic?: string;
value?: string;
topic?: string
value?: string
}
export interface Section {
topic?: string;
identity?: string;
error?: string;
attributes: Array<Attribute>;
bytes?: string;
children: Array<Section>;
}
export function parseAddress(raw: string): Output;
topic?: string
identity?: string
error?: string
attributes: Array<Attribute>
bytes?: string
children: Array<Section>
}
export function parseAddress(raw: string): Output
export interface SectionValidation {
section: Section;
validations: Validations;
section: Section
validations: Validations
}
export function safeParseTx(raw: string): SectionValidation;
export function safeParseBlock(raw: string): Section;
export function safeParseTx(raw: string, context: ValidationContext): SectionValidation
export function safeParseBlock(raw: string): Section
export interface Validation {
name: string;
value: boolean;
description: string;
name: string
value: boolean
description: string
}
export interface Validations {
validations: Array<Validation>;
era: string;
validations: Array<Validation>
era: string
}
43 changes: 41 additions & 2 deletions napi-pallas/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,45 @@ mod block;
mod tx;
mod validations;

#[derive(Default)]
#[napi(object)]
pub struct ValidationContext {
pub epoch: i64,
pub min_fee_a: i64,
pub min_fee_b: i64,
pub max_block_size: i64,
pub max_tx_size: i64,
pub max_block_header_size: i64,
pub key_deposit: i64,
pub pool_deposit: i64,
pub e_max: i64,
pub n_opt: i64,
pub a0: i64,
pub rho: i64,
pub tau: i64,
pub decentralisation_param: i64,
pub extra_entropy: i64,
pub protocol_major_ver: i64,
pub protocol_minor_ver: i64,
pub min_utxo: i64,
pub min_pool_cost: i64,
pub price_mem: i64,
pub price_step: i64,
pub max_tx_ex_mem: u32,
pub max_tx_ex_steps: i64,
pub max_block_ex_mem: i64,
pub max_block_ex_steps: i64,
pub max_val_size: i64,
pub collateral_percent: i64,
pub max_collateral_inputs: i64,
pub coins_per_utxo_size: i64,
pub coins_per_utxo_word: i64,

pub network: String,
pub era: String,
pub block_slot: i64,
}

#[derive(Default)]
#[napi(object)]
pub struct Attribute {
Expand Down Expand Up @@ -152,8 +191,8 @@ pub struct SectionValidation {
}

#[napi]
pub fn safe_parse_tx(raw: String) -> SectionValidation {
match tx::parse(raw) {
pub fn safe_parse_tx(raw: String, context: ValidationContext) -> SectionValidation {
match tx::parse(raw, context) {
Ok(x) => {
let (section, validations) = x;
SectionValidation {
Expand Down
19 changes: 15 additions & 4 deletions napi-pallas/src/tx.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
use crate::validations::validate::validate;
use crate::Validations;
use crate::{validations::validate::validate, ValidationContext};

use super::Section;
use pallas::ledger::traverse::Era;
use pallas::{
codec::utils::KeepRaw,
crypto::hash::Hasher,
Expand Down Expand Up @@ -235,13 +236,23 @@ pub fn create_cbor_structure(tx: &MultiEraTx<'_>) -> Section {
out
}

pub fn parse(raw: String) -> Result<(Section, Validations), Section> {
pub fn parse(raw: String, context: ValidationContext) -> Result<(Section, Validations), Section> {
let res_cbor = hex::decode(raw);
let mut era_decode = Era::Babbage;
match context.era.as_str() {
"Alonzo" => era_decode = Era::Alonzo,
"Babbage" => era_decode = Era::Babbage,
"Byron" => era_decode = Era::Byron,
"Conway" => era_decode = Era::Conway,
"Shelley MA" => era_decode = Era::Shelley,
// This case should never happen
_ => {}
}
match res_cbor {
Ok(cbor) => {
let res_mtx = MultiEraTx::decode(&cbor);
let res_mtx = MultiEraTx::decode_for_era(era_decode, &cbor);
match res_mtx {
Ok(mtx) => Ok((create_cbor_structure(&mtx), validate(&mtx))),
Ok(mtx) => Ok((create_cbor_structure(&mtx), validate(&mtx, context))),
Err(e) => {
let mut err = Section::new();
err.error = Some(e.to_string());
Expand Down
44 changes: 28 additions & 16 deletions napi-pallas/src/validations/alonzo.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ use pallas::{
ledger::primitives::alonzo::{MintedTx, TransactionBody},
};

use crate::{Validation, Validations};
use crate::{Validation, ValidationContext, Validations};

use super::validate::set_description;

Expand Down Expand Up @@ -229,30 +229,42 @@ fn validate_alonzo_fee(mtx_a: &MintedTx, utxos: &UTxOs, prot_pps: &AlonzoProtPar
}
}

pub fn validate_alonzo(mtx_a: &MintedTx) -> Validations {
pub fn validate_alonzo(mtx_a: &MintedTx, context: ValidationContext) -> Validations {
let tx_body: &TransactionBody = &mtx_a.transaction_body;
let size: &Option<u64> = &get_alonzo_comp_tx_size(tx_body);
let prot_params = AlonzoProtParams {
fee_policy: FeePolicy {
summand: 155381,
multiplier: 44,
summand: context.min_fee_b as u64,
multiplier: context.min_fee_a as u64,
},
max_tx_size: 16384,
max_block_ex_mem: 62000000,
max_block_ex_steps: 20000000000,
max_tx_ex_mem: 14000000,
max_tx_ex_steps: 10000000000,
max_val_size: 5000,
collateral_percent: 150,
max_collateral_inputs: 3,
coins_per_utxo_word: 4310,
max_tx_size: context.max_tx_size as u64,
max_block_ex_mem: context.max_block_ex_mem as u64,
max_block_ex_steps: context.max_block_ex_steps as u64,
max_tx_ex_mem: context.max_tx_ex_mem,
max_tx_ex_steps: context.max_tx_ex_steps as u64,
max_val_size: context.max_val_size as u64,
collateral_percent: context.collateral_percent as u64,
max_collateral_inputs: context.max_collateral_inputs as u64,
coins_per_utxo_word: context.coins_per_utxo_word as u64,
};

let mut magic = 764824073; // For mainnet
if context.network == "Preprod" {
magic = 1;
} else if context.network == "Preview" {
magic = 2;
}

let mut net_id = 1; // For mainnet
if context.network == "Preprod" || context.network == "Preview" {
net_id = 0;
}

let env: Environment = Environment {
prot_params: MultiEraProtParams::Alonzo(prot_params.clone()),
prot_magic: 764824073, // Mainnet. For preprod: 1. For preview: 2
block_slot: 72316896, // TODO: Must be an input
network_id: 1, // Mainnet. For preprod: 0. For preview: 0
prot_magic: magic,
block_slot: context.block_slot as u64,
network_id: net_id,
};
let out = Validations::new()
.with_era("Alonzo".to_string())
Expand Down
46 changes: 29 additions & 17 deletions napi-pallas/src/validations/babbage.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::{Validation, Validations};
use crate::{Validation, ValidationContext, Validations};
use pallas::{
applying::{
babbage::{
Expand Down Expand Up @@ -280,34 +280,46 @@ fn validate_babbage_network_id(mtx: &BabbageMintedTx, network_id: u8) -> Validat
.with_description(description);
}

pub fn validate_babbage(mtx_b: &BabbageMintedTx) -> Validations {
pub fn validate_babbage(mtx_b: &BabbageMintedTx, context: ValidationContext) -> Validations {
let tx_body: &MintedTransactionBody = &mtx_b.transaction_body.clone();
let size: &Option<u64> = &get_babbage_tx_size(tx_body);
let prot_params = BabbageProtParams {
fee_policy: FeePolicy {
summand: 155381,
multiplier: 44,
summand: context.min_fee_b as u64,
multiplier: context.min_fee_a as u64,
},
max_tx_size: 16384,
max_block_ex_mem: 62000000,
max_block_ex_steps: 20000000000,
max_tx_ex_mem: 14000000,
max_tx_ex_steps: 10000000000,
max_val_size: 5000,
collateral_percent: 150,
max_collateral_inputs: 3,
coins_per_utxo_word: 4310,
max_tx_size: context.max_tx_size as u64,
max_block_ex_mem: context.max_block_ex_mem as u64,
max_block_ex_steps: context.max_block_ex_steps as u64,
max_tx_ex_mem: context.max_tx_ex_mem,
max_tx_ex_steps: context.max_tx_ex_steps as u64,
max_val_size: context.max_val_size as u64,
collateral_percent: context.collateral_percent as u64,
max_collateral_inputs: context.max_collateral_inputs as u64,
coins_per_utxo_word: context.coins_per_utxo_word as u64,
};

let mut magic = 764824073; // For mainnet
if context.network == "Preprod" {
magic = 1;
} else if context.network == "Preview" {
magic = 2;
}

let mut net_id = 1; // For mainnet
if context.network == "Preprod" || context.network == "Preview" {
net_id = 0;
}

let env: Environment = Environment {
prot_params: MultiEraProtParams::Babbage(prot_params.clone()),
prot_magic: 764824073, // Mainnet. For preprod: 1. For preview: 2
block_slot: 72316896, // TODO: Must be an input
network_id: 1, // Mainnet. For preprod: 0. For preview: 0
prot_magic: magic,
block_slot: context.block_slot as u64,
network_id: net_id,
};

let out = Validations::new()
.with_era("Babbage".to_string())
.with_era(context.era.to_string())
.add_new_validation(validate_babbage_ins_not_empty(&mtx_b))
.add_new_validation(validate_babbage_minting(&mtx_b))
.add_new_validation(validate_babbage_well_formed(&mtx_b))
Expand Down
10 changes: 5 additions & 5 deletions napi-pallas/src/validations/byron.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::{Validation, Validations};
use crate::{Validation, ValidationContext, Validations};
use pallas::{
applying::{
byron::{
Expand Down Expand Up @@ -120,15 +120,15 @@ fn validate_byron_fees(
.with_description(description);
}

pub fn validate_byron(mtxp: &MintedTxPayload) -> Validations {
pub fn validate_byron(mtxp: &MintedTxPayload, context: ValidationContext) -> Validations {
let tx: &Tx = &mtxp.transaction;
let size: &u64 = &get_tx_size(&tx);
let prot_pps: ByronProtParams = ByronProtParams {
fee_policy: FeePolicy {
summand: 155381,
multiplier: 44,
summand: context.min_fee_b as u64,
multiplier: context.min_fee_a as u64,
},
max_tx_size: 16384,
max_tx_size: context.max_tx_size as u64,
};

let out = Validations::new()
Expand Down
8 changes: 7 additions & 1 deletion napi-pallas/src/validations/conway.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,12 @@ use pallas::ledger::primitives::conway::MintedTx;

use crate::Validations;
pub fn validate_conway(mtx_c: &MintedTx) -> Validations {
let out = Validations::new().with_era("Conway".to_string());
let out = Validations::new()
.with_era("Conway".to_string())
.add_new_validation(crate::Validation {
name: "Coming soon...".to_string(),
value: true,
description: "Coming soon...".to_string(),
});
out
}
Loading

0 comments on commit c17c69a

Please sign in to comment.