Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Block adjustments (zkapps) #82

Merged
merged 7 commits into from
Dec 11, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 3 additions & 3 deletions sql/queries/zkapp_commands.sql
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,9 @@ SELECT
WHERE
zauf.id=ANY (bzc.failure_reasons_ids)
) AS failure_reasons,
zaub.balance_change,
pk_update_body.value AS pk_update_body,
token_update_body.value AS token
zaub.balance_change AS "balance_change?",
pk_update_body.value AS "pk_update_body?",
token_update_body.value AS "token?"
FROM
blocks_zkapp_commands AS bzc
INNER JOIN zkapp_commands AS zc ON bzc.zkapp_command_id=zc.id
Expand Down
2 changes: 1 addition & 1 deletion src/api/account_balance.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ impl MinaMesh {
let block = sqlx::query_file!("sql/queries/maybe_block.sql", index)
.fetch_optional(&self.pg_pool)
.await?
.ok_or(MinaMeshError::BlockMissing(index.unwrap().to_string()))?;
.ok_or(MinaMeshError::BlockMissing(index, None))?;
// has canonical height / do we really need to do a different query?
let maybe_account_balance_info = sqlx::query_file!(
"sql/queries/maybe_account_balance_info.sql",
Expand Down
58 changes: 19 additions & 39 deletions src/api/block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use sqlx::FromRow;

use crate::{
generate_internal_command_transaction_identifier, generate_operations_internal_command,
generate_operations_user_command, generate_transaction_metadata, sql_to_mesh::zkapp_commands_to_transactions,
generate_operations_user_command, generate_operations_zkapp_command, generate_transaction_metadata,
util::DEFAULT_TOKEN_ID, ChainStatus, InternalCommandMetadata, InternalCommandType, MinaMesh, MinaMeshError,
TransactionStatus, UserCommandMetadata, UserCommandType, ZkAppCommand,
};
Expand All @@ -20,7 +20,7 @@ impl MinaMesh {
let partial_block_identifier = *request.block_identifier;
let metadata = match self.block_metadata(&partial_block_identifier).await? {
Some(metadata) => metadata,
None => return Err(MinaMeshError::BlockMissing(serde_json::to_string(&partial_block_identifier)?)),
None => return Err(MinaMeshError::BlockMissing(partial_block_identifier.index, partial_block_identifier.hash)),
};
let parent_block_metadata = match &metadata.parent_id {
Some(parent_id) => {
Expand Down Expand Up @@ -149,7 +149,7 @@ pub struct BlockMetadata {
state_hash: String,
sub_window_densities: Vec<i64>,
timestamp: String,
total_currency: String,
total_currency: Option<String>,
parent_hash: String,
parent_id: Option<i32>,
proposed_protocol_version_id: Option<i32>,
Expand All @@ -160,41 +160,21 @@ pub struct BlockMetadata {
winner: String,
}

#[derive(Debug, PartialEq, Eq, FromRow, Serialize)]
pub struct ZkappCommandMetadata {
id: i64,
memo: Option<String>,
hash: String,
fee_payer: String,
fee: String,
valid_until: Option<i64>,
nonce: i64,
sequence_no: i64,
status: TransactionStatus,
failure_reasons: Option<Vec<String>>,
balance_change: String,
account: String,
token: String,
}
pub fn zkapp_commands_to_transactions(commands: Vec<ZkAppCommand>) -> Vec<Transaction> {
let block_map = generate_operations_zkapp_command(commands);

#[derive(Debug, PartialEq, Eq, FromRow, Serialize)]
pub struct ZkappAccountUpdateMetadata {
account_identifier_id: i32,
update_id: i32,
balance_change: String,
increment_nonce: bool,
events_id: i32,
actions_id: i32,
call_data_id: i32,
call_depth: i32,
zkapp_network_precondition_id: i32,
zkapp_account_precondition_id: i32,
zkapp_valid_while_precondition_id: Option<i32>,
use_full_commitment: bool,
implicit_account_creation_fee: bool,
may_use_token: String,
authorization_kind: String,
verification_key_hash_id: Option<i32>,
account: String,
token: String,
let mut result = Vec::new();
for (_, tx_map) in block_map {
for (tx_hash, operations) in tx_map {
let transaction = Transaction {
transaction_identifier: Box::new(TransactionIdentifier { hash: tx_hash }),
operations,
metadata: None,
related_transactions: None,
};
result.push(transaction);
}
}

result
}
69 changes: 10 additions & 59 deletions src/api/search_transactions.rs
Original file line number Diff line number Diff line change
@@ -1,16 +1,13 @@
use std::collections::BTreeMap;

use coinbase_mesh::models::{
AccountIdentifier, BlockIdentifier, BlockTransaction, Operation, SearchTransactionsRequest,
SearchTransactionsResponse, Transaction, TransactionIdentifier,
BlockIdentifier, BlockTransaction, SearchTransactionsRequest, SearchTransactionsResponse, Transaction,
TransactionIdentifier,
};
use serde_json::json;

use crate::{
generate_internal_command_transaction_identifier, generate_operations_internal_command,
generate_operations_user_command, generate_transaction_metadata, operation, util::DEFAULT_TOKEN_ID, ChainStatus,
InternalCommand, InternalCommandType, MinaMesh, MinaMeshError, OperationType, TransactionStatus, UserCommand,
UserCommandType, ZkAppCommand,
generate_operations_user_command, generate_operations_zkapp_command, generate_transaction_metadata, ChainStatus,
InternalCommand, InternalCommandType, MinaMesh, MinaMeshError, TransactionStatus, UserCommand, UserCommandType,
ZkAppCommand,
};

impl MinaMesh {
Expand Down Expand Up @@ -220,63 +217,17 @@ impl MinaMesh {
}

pub fn zkapp_commands_to_block_transactions(commands: Vec<ZkAppCommand>) -> Vec<BlockTransaction> {
let mut block_map: BTreeMap<(i64, String), BTreeMap<String, Vec<Operation>>> = BTreeMap::new();

for command in commands {
// Group by block identifier (block index and block hash)
let block_key = (command.height.unwrap_or(0), command.state_hash.clone().unwrap_or_default());
let tx_hash = command.hash;

// Initialize or update the operation list for this transaction
let operations = block_map.entry(block_key).or_default().entry(tx_hash.clone()).or_default();

// Add fee operation (zkapp_fee_payer_dec)
if operations.is_empty() {
operations.push(operation(
0,
Some(&format!("-{}", command.fee)),
&AccountIdentifier {
address: command.fee_payer.clone(),
metadata: Some(json!({ "token_id": DEFAULT_TOKEN_ID })),
sub_account: None,
},
OperationType::ZkappFeePayerDec,
Some(&TransactionStatus::Applied),
None,
None,
None,
));
}

// Add zkapp balance update operation
operations.push(operation(
0,
Some(&command.balance_change),
&AccountIdentifier {
address: command.pk_update_body.clone(),
metadata: Some(json!({ "token_id": command.token })),
sub_account: None,
},
OperationType::ZkappBalanceUpdate,
Some(&command.status),
None,
None,
command.token.as_ref(),
));
}
let block_map = generate_operations_zkapp_command(commands);

let mut result = Vec::new();
for ((block_index, block_hash), tx_map) in block_map {
for (tx_hash, mut operations) in tx_map {
// Ensure the operations are correctly indexed
for (i, operation) in operations.iter_mut().enumerate() {
operation.operation_identifier.index = i as i64;
}

let block_index = block_index.unwrap_or(0);
let block_hash = block_hash.unwrap_or_default();
for (tx_hash, operations) in tx_map {
let transaction = BlockTransaction {
block_identifier: Box::new(BlockIdentifier { index: block_index, hash: block_hash.clone() }),
transaction: Box::new(Transaction {
transaction_identifier: Box::new(TransactionIdentifier { hash: tx_hash.clone() }),
transaction_identifier: Box::new(TransactionIdentifier { hash: tx_hash }),
operations,
metadata: None,
related_transactions: None,
Expand Down
31 changes: 25 additions & 6 deletions src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ pub enum MinaMeshError {
TransactionNotFound(String),

#[error("Block not found")]
BlockMissing(String),
BlockMissing(Option<i64>, Option<String>),

#[error("Malformed public key")]
MalformedPublicKey,
Expand Down Expand Up @@ -118,7 +118,7 @@ impl MinaMeshError {
MinaMeshError::AccountNotFound("Account ID".to_string()),
MinaMeshError::InvariantViolation,
MinaMeshError::TransactionNotFound("Transaction ID".to_string()),
MinaMeshError::BlockMissing("Block ID".to_string()),
MinaMeshError::BlockMissing(Some(-1), Some("test_hash".to_string())),
MinaMeshError::MalformedPublicKey,
MinaMeshError::OperationsNotValid(vec![]),
MinaMeshError::UnsupportedOperationForConstruction,
Expand Down Expand Up @@ -150,7 +150,7 @@ impl MinaMeshError {
MinaMeshError::AccountNotFound(_) => 6,
MinaMeshError::InvariantViolation => 7,
MinaMeshError::TransactionNotFound(_) => 8,
MinaMeshError::BlockMissing(_) => 9,
MinaMeshError::BlockMissing(_, _) => 9,
MinaMeshError::MalformedPublicKey => 10,
MinaMeshError::OperationsNotValid(_) => 11,
MinaMeshError::UnsupportedOperationForConstruction => 12,
Expand Down Expand Up @@ -179,7 +179,7 @@ impl MinaMeshError {
| MinaMeshError::TransactionSubmitNoSender
| MinaMeshError::AccountNotFound(_)
| MinaMeshError::TransactionNotFound(_)
| MinaMeshError::BlockMissing(_)
| MinaMeshError::BlockMissing(_, _)
| MinaMeshError::ChainInfoMissing
)
}
Expand Down Expand Up @@ -218,6 +218,25 @@ impl MinaMeshError {
),
"transaction": tx,
}),
MinaMeshError::BlockMissing(index, hash) => {
let block_identifier = match (index, hash) {
(Some(idx), Some(hsh)) => format!("index={}, hash={}", idx, hsh),
(Some(idx), None) => format!("index={}", idx),
(None, Some(hsh)) => format!("hash={}", hsh),
(None, None) => "no identifying information (index or hash)".to_string(),
};

let error_message =
format!("We couldn't find the block in the archive node, specified by {}.", block_identifier);
json!({
"error": error_message,
"block": {
"index": index,
"hash": hash,
},
})
}

_ => json!(""),
}
}
Expand All @@ -244,7 +263,7 @@ impl MinaMeshError {
MinaMeshError::AccountNotFound(_) => "The specified account could not be found.".to_string(),
MinaMeshError::InvariantViolation => "An internal invariant was violated.".to_string(),
MinaMeshError::TransactionNotFound(_) => "The specified transaction could not be found.".to_string(),
MinaMeshError::BlockMissing(_) => "The specified block could not be found.".to_string(),
MinaMeshError::BlockMissing(_, _) => "The specified block could not be found.".to_string(),
MinaMeshError::MalformedPublicKey => "The provided public key is malformed.".to_string(),
MinaMeshError::OperationsNotValid(_) => {
"We could not convert those operations to a valid transaction.".to_string()
Expand Down Expand Up @@ -290,7 +309,7 @@ impl IntoResponse for MinaMeshError {
MinaMeshError::AccountNotFound(_) => StatusCode::NOT_FOUND,
MinaMeshError::InvariantViolation => StatusCode::INTERNAL_SERVER_ERROR,
MinaMeshError::TransactionNotFound(_) => StatusCode::NOT_FOUND,
MinaMeshError::BlockMissing(_) => StatusCode::NOT_FOUND,
MinaMeshError::BlockMissing(_, _) => StatusCode::NOT_FOUND,
MinaMeshError::MalformedPublicKey => StatusCode::BAD_REQUEST,
MinaMeshError::OperationsNotValid(_) => StatusCode::BAD_REQUEST,
MinaMeshError::UnsupportedOperationForConstruction => StatusCode::BAD_REQUEST,
Expand Down
1 change: 0 additions & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ mod create_router;
mod error;
mod graphql;
mod playground;
mod sql_to_mesh;
pub mod test;
mod transaction_operations;
mod types;
Expand Down
69 changes: 0 additions & 69 deletions src/sql_to_mesh.rs

This file was deleted.

Loading
Loading