Skip to content

Commit

Permalink
adjust into_block_transaction to comply with Ocaml implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
piotr-iohk committed Oct 2, 2024
1 parent 33651c6 commit d1395c0
Show file tree
Hide file tree
Showing 2 changed files with 160 additions and 18 deletions.
2 changes: 1 addition & 1 deletion sql/indexer_user_commands.sql
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ SELECT
pk_payer.value AS fee_payer,
pk_source.value AS source,
pk_receiver.value AS receiver,
COALESCE(ac.creation_fee, '0') AS creation_fee
ac.creation_fee AS "creation_fee?"
FROM id_count,
(
SELECT *
Expand Down
176 changes: 159 additions & 17 deletions src/api/search_transactions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ pub enum ChainStatus {
Orphaned,
}

// implement Display for ChainStatus
impl std::fmt::Display for ChainStatus {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Expand All @@ -33,7 +32,6 @@ pub enum UserCommandType {
Delegation,
}

// implement Display for UserCommandType
impl std::fmt::Display for UserCommandType {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Expand All @@ -50,7 +48,6 @@ pub enum TransactionStatus {
Failed,
}

// implement Display for TransactionStatus
impl std::fmt::Display for TransactionStatus {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Expand All @@ -60,6 +57,15 @@ impl std::fmt::Display for TransactionStatus {
}
}

impl TransactionStatus {
pub fn to_status(&self) -> String {
match self {
TransactionStatus::Applied => "Success".to_string(),
TransactionStatus::Failed => "Failed".to_string(),
}
}
}

#[derive(Debug, FromRow)]
pub struct UserCommand {
pub id: Option<i32>,
Expand Down Expand Up @@ -87,6 +93,41 @@ pub struct UserCommand {
pub creation_fee: Option<String>,
}

#[derive(Debug)]
pub enum OperationType {
FeePayment,
PaymentSourceDecrement,
PaymentReceiverIncrement,
DelegateChange,
FeePayerDecrement,
AccountCreationFeeViaPayment,
AccountCreationFeeViaFeeReceiver,
ZkappFeePayerDecrement,
ZkappBalanceUpdate,
FeeReceiverIncrement,
CoinbaseIncrement,
}

impl std::fmt::Display for OperationType {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
OperationType::FeePayment => write!(f, "fee_payment"),
OperationType::AccountCreationFeeViaPayment => write!(f, "account_creation_fee_via_payment"),
OperationType::PaymentSourceDecrement => write!(f, "payment_source_dec"),
OperationType::PaymentReceiverIncrement => write!(f, "payment_receiver_inc"),
OperationType::DelegateChange => write!(f, "delegate_change"),
OperationType::FeePayerDecrement => write!(f, "fee_payer_dec"),
OperationType::AccountCreationFeeViaFeeReceiver => write!(f, "account_creation_fee_via_fee_receiver"),
OperationType::ZkappFeePayerDecrement => write!(f, "zkapp_fee_payer_dec"),
OperationType::ZkappBalanceUpdate => write!(f, "zkapp_balance_update"),
OperationType::FeeReceiverIncrement => write!(f, "fee_receiver_inc"),
OperationType::CoinbaseIncrement => write!(f, "coinbase_inc"),
}
}
}

const MINA_DEFAULT_TOKEN_ID: &str = "wSHV2S4qX9jFsLjQo8r1BsMLH2ZRKsZx6EJd1sbozGPieEC4Jf";

Check warning on line 129 in src/api/search_transactions.rs

View workflow job for this annotation

GitHub Actions / cspell

Unknown word (ZRKs)

Check warning on line 129 in src/api/search_transactions.rs

View workflow job for this annotation

GitHub Actions / cspell

Unknown word (sboz)

impl UserCommand {
pub fn into_block_transaction(self) -> BlockTransaction {
// Construct BlockIdentifier from UserCommand
Expand All @@ -96,26 +137,127 @@ impl UserCommand {
// Construct TransactionIdentifier from UserCommand hash
let transaction_identifier = TransactionIdentifier { hash: self.hash.clone() };

// Construct Operations based on UserCommand
let operations = vec![Operation {
operation_identifier: Box::new(OperationIdentifier { index: 0, network_index: None }),
r#type: self.command_type.to_string(),
status: Some(self.status.to_string()),
account: Some(Box::new(AccountIdentifier { address: self.source.clone(), metadata: None, sub_account: None })),
// Create a series of operations for the transaction
let mut operations = Vec::new();

// Index for operations
let mut operation_index = 0;

let amt = self.amount.clone().unwrap_or_else(|| "0".to_string());

// Operation 1: Fee Payment
operations.push(Operation {
operation_identifier: Box::new(OperationIdentifier { index: operation_index, network_index: None }),
r#type: OperationType::FeePayment.to_string(),
status: Some(self.status.to_status()),
account: Some(Box::new(AccountIdentifier {
address: self.fee_payer.clone(),
metadata: Some(json!({ "token_id": MINA_DEFAULT_TOKEN_ID })),
sub_account: None,
})),
amount: Some(Box::new(Amount {
value: self.amount.unwrap_or_else(|| "0".to_string()),
value: format!("-{}", self.fee.unwrap_or_else(|| "0".to_string())), // Negative value for fee
metadata: None,
currency: Box::new(Currency { symbol: "MINA".to_string(), decimals: 9, metadata: None }),
})),
coin_change: None,
metadata: Some(json!({
"fee_payer": self.fee_payer,
"receiver": self.receiver,
"fee": self.fee.unwrap_or_else(|| "0".to_string()),
"creation_fee": self.creation_fee.unwrap_or_else(|| "0".to_string()),
})),
metadata: None,
related_operations: None,
}];
});

operation_index += 1;

// Operation 2: Account Creation Fee (if applicable)
if let Some(creation_fee) = &self.creation_fee {
if let Ok(fee_value) = creation_fee.parse::<i64>() {
if fee_value > 0 {
operations.push(Operation {
operation_identifier: Box::new(OperationIdentifier { index: operation_index, network_index: None }),
r#type: OperationType::AccountCreationFeeViaPayment.to_string(),
status: Some(self.status.to_status()),
account: Some(Box::new(AccountIdentifier {
address: self.receiver.clone(),
metadata: Some(json!({ "token_id": MINA_DEFAULT_TOKEN_ID })),
sub_account: None,
})),
amount: Some(Box::new(Amount {
value: format!("-{}", creation_fee),
metadata: None,
currency: Box::new(Currency { symbol: "MINA".to_string(), decimals: 9, metadata: None }),
})),
coin_change: None,
metadata: None,
related_operations: None,
});

operation_index += 1;
}
}
}

// Decide on the type of operation based on command type
match self.command_type {
UserCommandType::Payment => {
// Operation 3: Payment Source Decrement
operations.push(Operation {
operation_identifier: Box::new(OperationIdentifier { index: operation_index, network_index: None }),
r#type: OperationType::PaymentSourceDecrement.to_string(),
status: Some(self.status.to_status()),
account: Some(Box::new(AccountIdentifier {
address: self.source.clone(),
metadata: Some(json!({ "token_id": MINA_DEFAULT_TOKEN_ID })),
sub_account: None,
})),
amount: Some(Box::new(Amount {
value: format!("-{}", amt), // Negative value for the payment amount
metadata: None,
currency: Box::new(Currency { symbol: "MINA".to_string(), decimals: 9, metadata: None }),
})),
coin_change: None,
metadata: None,
related_operations: None,
});

operation_index += 1;

// Operation 4: Payment Receiver Increment
operations.push(Operation {
operation_identifier: Box::new(OperationIdentifier { index: operation_index, network_index: None }),
r#type: OperationType::PaymentReceiverIncrement.to_string(),
status: Some(self.status.to_status()),
account: Some(Box::new(AccountIdentifier {
address: self.receiver.clone(),
metadata: Some(json!({ "token_id": MINA_DEFAULT_TOKEN_ID })),
sub_account: None,
})),
amount: Some(Box::new(Amount {
value: amt, // Positive value for the payment amount
metadata: None,
currency: Box::new(Currency { symbol: "MINA".to_string(), decimals: 9, metadata: None }),
})),
coin_change: None,
metadata: None,
related_operations: Some(vec![OperationIdentifier { index: operation_index - 1, network_index: None }]), // Relate to the previous source decrement
});
}
UserCommandType::Delegation => {
// Operation 3: Delegate Change
operations.push(Operation {
operation_identifier: Box::new(OperationIdentifier { index: operation_index, network_index: None }),
r#type: OperationType::DelegateChange.to_string(),
status: Some(self.status.to_status()),
account: Some(Box::new(AccountIdentifier {
address: self.source.clone(),
metadata: Some(json!({ "token_id": MINA_DEFAULT_TOKEN_ID })),
sub_account: None,
})),
amount: None,
coin_change: None,
metadata: Some(json!({ "delegate_change_target": self.receiver.clone() })),
related_operations: None,
});
}
}

// Construct Transaction
let transaction = Transaction {
Expand Down

0 comments on commit d1395c0

Please sign in to comment.