From 25e75422a76e97c90922078f163ea7382ab105ba Mon Sep 17 00:00:00 2001 From: Piotr Stachyra Date: Mon, 14 Oct 2024 18:55:55 +0200 Subject: [PATCH 01/21] Initial implementation --- src/api/search_transactions.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/api/search_transactions.rs b/src/api/search_transactions.rs index 8babf40..e72675d 100644 --- a/src/api/search_transactions.rs +++ b/src/api/search_transactions.rs @@ -159,7 +159,6 @@ impl MinaMesh { } } -#[allow(dead_code)] #[derive(FromRow)] pub struct ZkAppCommand { pub id: Option, From 4b2860b940a8746aea2cfb8734a342c1d5237fb1 Mon Sep 17 00:00:00 2001 From: Piotr Stachyra Date: Tue, 15 Oct 2024 11:56:34 +0200 Subject: [PATCH 02/21] update metadata --- src/api/search_transactions.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/api/search_transactions.rs b/src/api/search_transactions.rs index e72675d..820191d 100644 --- a/src/api/search_transactions.rs +++ b/src/api/search_transactions.rs @@ -216,7 +216,7 @@ pub fn zkapp_commands_to_block_transactions(commands: Vec) -> Vec< sub_account: None, }, OperationType::ZkappFeePayerDec, - Some(&TransactionStatus::Applied), + Some(&command.status), None, None, )); From e519f674e1e491c721389577d5dc7cd3579b87bf Mon Sep 17 00:00:00 2001 From: Piotr Stachyra Date: Tue, 15 Oct 2024 14:10:25 +0200 Subject: [PATCH 03/21] mark fee status always Success (as in ocaml impl) --- src/api/search_transactions.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/api/search_transactions.rs b/src/api/search_transactions.rs index 820191d..e72675d 100644 --- a/src/api/search_transactions.rs +++ b/src/api/search_transactions.rs @@ -216,7 +216,7 @@ pub fn zkapp_commands_to_block_transactions(commands: Vec) -> Vec< sub_account: None, }, OperationType::ZkappFeePayerDec, - Some(&command.status), + Some(&TransactionStatus::Applied), None, None, )); From 627b1b45d9a1ce4ddb9a6e6cf0c3cc158862e31f Mon Sep 17 00:00:00 2001 From: Piotr Stachyra Date: Tue, 15 Oct 2024 15:13:07 +0200 Subject: [PATCH 04/21] tests --- ...ons__search_transactions_zkapp_failed.snap | 125 ++++++++++++++++++ 1 file changed, 125 insertions(+) diff --git a/tests/snapshots/search_transactions__search_transactions_zkapp_failed.snap b/tests/snapshots/search_transactions__search_transactions_zkapp_failed.snap index a35e65d..c72388a 100644 --- a/tests/snapshots/search_transactions__search_transactions_zkapp_failed.snap +++ b/tests/snapshots/search_transactions__search_transactions_zkapp_failed.snap @@ -125,8 +125,133 @@ Ok( metadata: None, }, }, +<<<<<<< HEAD ], total_count: 1, +======= + BlockTransaction { + block_identifier: BlockIdentifier { + index: 356949, + hash: "3NKL6D7kcvH28odK9QpCqvKuHjx2jm2BhfKjPVkvLLyAoKKMD3JF", + }, + transaction: Transaction { + transaction_identifier: TransactionIdentifier { + hash: "5JujBt8rnKheA7CHBnTwUDXrHtQxqPB9LL5Q8y4KwLjPBsBSJuSE", + }, + operations: [ + Operation { + operation_identifier: OperationIdentifier { + index: 0, + network_index: None, + }, + related_operations: None, + type: "zkapp_fee_payer_dec", + status: Some( + "Success", + ), + account: Some( + AccountIdentifier { + address: "B62qjGsPY47SMkTykivPBAU3riS9gvMMrGr7ve6ynoHJNBzAhQmtoBn", + sub_account: None, + metadata: Some( + Object { + "token_id": String("wSHV2S4qX9jFsLjQo8r1BsMLH2ZRKsZx6EJd1sbozGPieEC4Jf"), + }, + ), + }, + ), + amount: Some( + Amount { + value: "-100000000", + currency: Currency { + symbol: "MINA", + decimals: 9, + metadata: None, + }, + metadata: None, + }, + ), + coin_change: None, + metadata: None, + }, + Operation { + operation_identifier: OperationIdentifier { + index: 1, + network_index: None, + }, + related_operations: None, + type: "zkapp_balance_update", + status: Some( + "Failed", + ), + account: Some( + AccountIdentifier { + address: "B62qide3tEVFgzLFo72rhrF4p8Luv6R5NAmvwo83SnZGnwV9Q6fiVTK", + sub_account: None, + metadata: Some( + Object { + "token_id": String("wSHV2S4qX9jFsLjQo8r1BsMLH2ZRKsZx6EJd1sbozGPieEC4Jf"), + }, + ), + }, + ), + amount: Some( + Amount { + value: "0", + currency: Currency { + symbol: "MINA", + decimals: 9, + metadata: None, + }, + metadata: None, + }, + ), + coin_change: None, + metadata: None, + }, + Operation { + operation_identifier: OperationIdentifier { + index: 2, + network_index: None, + }, + related_operations: None, + type: "zkapp_balance_update", + status: Some( + "Failed", + ), + account: Some( + AccountIdentifier { + address: "B62qjGsPY47SMkTykivPBAU3riS9gvMMrGr7ve6ynoHJNBzAhQmtoBn", + sub_account: None, + metadata: Some( + Object { + "token_id": String("wSHV2S4qX9jFsLjQo8r1BsMLH2ZRKsZx6EJd1sbozGPieEC4Jf"), + }, + ), + }, + ), + amount: Some( + Amount { + value: "0", + currency: Currency { + symbol: "MINA", + decimals: 9, + metadata: None, + }, + metadata: None, + }, + ), + coin_change: None, + metadata: None, + }, + ], + related_transactions: None, + metadata: None, + }, + }, + ], + total_count: 2, +>>>>>>> bdc48f0 (tests) next_offset: None, }, ) From a38bce5b026f10069aab291f88f04f804d9b1146 Mon Sep 17 00:00:00 2001 From: Harry Solovay Date: Tue, 8 Oct 2024 11:56:11 -0400 Subject: [PATCH 05/21] fetch zkapp command metadata --- ...a050798f7561d56b432d3dceb6aea2830a16.json} | 24 ++++++++++++++++--- sql/zkapp_commands.sql | 5 +++- src/api/block.rs | 7 ++++++ 3 files changed, 32 insertions(+), 4 deletions(-) rename .sqlx/{query-de3ae438ab25d585ae49ed2bf4b0761b3fbb32f2ff125cfc557e41106bb7debd.json => query-42425d0763c334a282e699ed3a10a050798f7561d56b432d3dceb6aea2830a16.json} (56%) diff --git a/.sqlx/query-de3ae438ab25d585ae49ed2bf4b0761b3fbb32f2ff125cfc557e41106bb7debd.json b/.sqlx/query-42425d0763c334a282e699ed3a10a050798f7561d56b432d3dceb6aea2830a16.json similarity index 56% rename from .sqlx/query-de3ae438ab25d585ae49ed2bf4b0761b3fbb32f2ff125cfc557e41106bb7debd.json rename to .sqlx/query-42425d0763c334a282e699ed3a10a050798f7561d56b432d3dceb6aea2830a16.json index cd3e427..5f7dc7c 100644 --- a/.sqlx/query-de3ae438ab25d585ae49ed2bf4b0761b3fbb32f2ff125cfc557e41106bb7debd.json +++ b/.sqlx/query-42425d0763c334a282e699ed3a10a050798f7561d56b432d3dceb6aea2830a16.json @@ -1,6 +1,6 @@ { "db_name": "PostgreSQL", - "query": "SELECT\n zc.id,\n zc.memo,\n zc.hash,\n pk_fee_payer.value AS fee_payer,\n zfpb.fee,\n zfpb.valid_until,\n zfpb.nonce,\n bzc.sequence_no,\n bzc.status AS \"status: TransactionStatus\",\n ARRAY(\n SELECT\n unnest(zauf.failures)\n FROM\n zkapp_account_update_failures AS zauf\n WHERE\n zauf.id=ANY (bzc.failure_reasons_ids)\n ) AS failure_reasons\nFROM\n blocks_zkapp_commands AS bzc\n INNER JOIN zkapp_commands AS zc ON bzc.zkapp_command_id=zc.id\n INNER JOIN zkapp_fee_payer_body AS zfpb ON zc.zkapp_fee_payer_body_id=zfpb.id\n INNER JOIN public_keys AS pk_fee_payer ON zfpb.public_key_id=pk_fee_payer.id\n INNER JOIN blocks AS b ON bzc.block_id=b.id\n LEFT JOIN zkapp_account_update AS zau ON zau.id=ANY (zc.zkapp_account_updates_ids)\n LEFT JOIN zkapp_account_update_body AS zaub ON zau.body_id=zaub.id\n LEFT JOIN account_identifiers AS ai_update_body ON zaub.account_identifier_id=ai_update_body.id\n LEFT JOIN public_keys AS pk_update_body ON ai_update_body.public_key_id=pk_update_body.id\n LEFT JOIN tokens AS token_update_body ON ai_update_body.token_id=token_update_body.id\nWHERE\n bzc.block_id=$1\n AND (\n token_update_body.value=$2\n OR token_update_body.id IS NULL\n )\nORDER BY\n zc.id,\n bzc.sequence_no\n", + "query": "SELECT\n zc.id,\n zc.memo,\n zc.hash,\n pk_fee_payer.value AS fee_payer,\n zfpb.fee,\n zfpb.valid_until,\n zfpb.nonce,\n bzc.sequence_no,\n bzc.status AS \"status: TransactionStatus\",\n ARRAY(\n SELECT\n unnest(zauf.failures)\n FROM\n zkapp_account_update_failures AS zauf\n WHERE\n zauf.id=ANY (bzc.failure_reasons_ids)\n ) AS failure_reasons,\n zaub.balance_change,\n pk_update_body.value AS account,\n token_update_body.value AS token\nFROM\n blocks_zkapp_commands AS bzc\n INNER JOIN zkapp_commands AS zc ON bzc.zkapp_command_id=zc.id\n INNER JOIN zkapp_fee_payer_body AS zfpb ON zc.zkapp_fee_payer_body_id=zfpb.id\n INNER JOIN public_keys AS pk_fee_payer ON zfpb.public_key_id=pk_fee_payer.id\n INNER JOIN blocks AS b ON bzc.block_id=b.id\n LEFT JOIN zkapp_account_update AS zau ON zau.id=ANY (zc.zkapp_account_updates_ids)\n LEFT JOIN zkapp_account_update_body AS zaub ON zau.body_id=zaub.id\n LEFT JOIN account_identifiers AS ai_update_body ON zaub.account_identifier_id=ai_update_body.id\n LEFT JOIN public_keys AS pk_update_body ON ai_update_body.public_key_id=pk_update_body.id\n LEFT JOIN tokens AS token_update_body ON ai_update_body.token_id=token_update_body.id\nWHERE\n bzc.block_id=$1\n AND (\n token_update_body.value=$2\n OR token_update_body.id IS NULL\n )\nORDER BY\n zc.id,\n bzc.sequence_no\n", "describe": { "columns": [ { @@ -62,6 +62,21 @@ "ordinal": 9, "name": "failure_reasons", "type_info": "TextArray" + }, + { + "ordinal": 10, + "name": "balance_change", + "type_info": "Text" + }, + { + "ordinal": 11, + "name": "account", + "type_info": "Text" + }, + { + "ordinal": 12, + "name": "token", + "type_info": "Text" } ], "parameters": { @@ -80,8 +95,11 @@ false, false, false, - null + null, + false, + false, + false ] }, - "hash": "de3ae438ab25d585ae49ed2bf4b0761b3fbb32f2ff125cfc557e41106bb7debd" + "hash": "42425d0763c334a282e699ed3a10a050798f7561d56b432d3dceb6aea2830a16" } diff --git a/sql/zkapp_commands.sql b/sql/zkapp_commands.sql index 8c6d497..eed3c79 100644 --- a/sql/zkapp_commands.sql +++ b/sql/zkapp_commands.sql @@ -15,7 +15,10 @@ SELECT zkapp_account_update_failures AS zauf WHERE zauf.id=ANY (bzc.failure_reasons_ids) - ) AS failure_reasons + ) AS failure_reasons, + zaub.balance_change, + pk_update_body.value AS account, + 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 diff --git a/src/api/block.rs b/src/api/block.rs index 9f7cd49..a4b746a 100644 --- a/src/api/block.rs +++ b/src/api/block.rs @@ -182,6 +182,9 @@ pub struct ZkappCommandMetadata { sequence_no: i64, status: TransactionStatus, failure_reasons: Option>, + balance_change: String, + account: String, + token: String, } #[derive(Debug, PartialEq, Eq, FromRow, Serialize)] @@ -341,5 +344,9 @@ fn internal_command_metadata_to_operation(metadata: &InternalCommandMetadata) -> // TODO: implement fn zkapp_command_metadata_to_operation(_metadata: &ZkappCommandMetadata) -> Result, MinaMeshError> { + // Go through each zkapp command in the vector + + // Produce the final transaction response regarding this zkapp command + Ok(Vec::new()) } From 0858cb1be37e5826b9bdd487d731c41af0ef1ad8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Santos=20Reis?= Date: Tue, 8 Oct 2024 18:02:26 +0100 Subject: [PATCH 06/21] Implement block zkapp transaction handling --- src/api/block.rs | 44 ++++++++++++++++++++++++++++---------------- 1 file changed, 28 insertions(+), 16 deletions(-) diff --git a/src/api/block.rs b/src/api/block.rs index a4b746a..fac8f62 100644 --- a/src/api/block.rs +++ b/src/api/block.rs @@ -81,13 +81,34 @@ impl MinaMesh { let metadata = sqlx::query_file_as!(ZkappCommandMetadata, "sql/zkapp_commands.sql", metadata.id, DEFAULT_TOKEN_ID) .fetch_all(&self.pg_pool) .await?; - let transactions = metadata - .into_iter() - .map(|item| { - zkapp_command_metadata_to_operation(&item) - .map(|operation| Transaction::new(TransactionIdentifier::new(item.hash.clone()), operation)) - }) - .collect::, MinaMeshError>>()?; + let mut transactions = Vec::new(); + let mut operations = Vec::new(); + let mut current_txn_identifier = TransactionIdentifier::new(metadata[0].hash.clone()); + for item in metadata { + if current_txn_identifier.hash != item.hash { + transactions.push(Transaction::new(current_txn_identifier, operations)); + operations = Vec::new(); + current_txn_identifier = TransactionIdentifier::new(item.hash.clone()); + } + operations.push(operation( + operations.len() as i64, + Some(&item.fee), + &AccountIdentifier::new(item.fee_payer.clone()), + OperationType::ZkappFeePayerDec, + None, + None, + None, + )); + operations.push(operation( + operations.len() as i64, + Some(&item.balance_change), + &AccountIdentifier::new(item.account.clone()), + OperationType::ZkappBalanceUpdate, + None, + None, + None, + )); + } Ok(transactions) } @@ -341,12 +362,3 @@ fn internal_command_metadata_to_operation(metadata: &InternalCommandMetadata) -> } Ok(operations) } - -// TODO: implement -fn zkapp_command_metadata_to_operation(_metadata: &ZkappCommandMetadata) -> Result, MinaMeshError> { - // Go through each zkapp command in the vector - - // Produce the final transaction response regarding this zkapp command - - Ok(Vec::new()) -} From a4449d97347f33305b423cc8e78ec62cd93e6c01 Mon Sep 17 00:00:00 2001 From: Harry Solovay Date: Tue, 15 Oct 2024 12:03:47 -0400 Subject: [PATCH 07/21] previous pairing session --- src/api/block.rs | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/api/block.rs b/src/api/block.rs index fac8f62..e1fcc30 100644 --- a/src/api/block.rs +++ b/src/api/block.rs @@ -362,3 +362,18 @@ fn internal_command_metadata_to_operation(metadata: &InternalCommandMetadata) -> } Ok(operations) } + +// TODO: implement +fn zkapp_command_metadata_to_operation(metadata: Vec) -> Result, MinaMeshError> { + // Go through each zkapp command in the vector + + // If the command id is the same as the previous, create a new operation from it + // and join it with the remaining operations of this transaction + + // If the command id is different than the previous, wrap up the previous + // transaction and start producing a new one, starting with the operation from + // this entry + + // Return a vec with the produced txns + Ok(Vec::new()) +} From cc8eab533226d600d7e8fa47e810856161713304 Mon Sep 17 00:00:00 2001 From: Harry Solovay Date: Tue, 15 Oct 2024 13:06:14 -0400 Subject: [PATCH 08/21] more on block --- ...7005bb4515d21a064c1ad13ab9746e23763da.json | 156 +++++++++++ ...c2ff75a1d9b210b99eed6f14e8a17d05530b.json} | 36 ++- ...a13b35f3ec2f47bdccd481116f663d3a5c3bc.json | 262 ------------------ sql/indexer_zkapp_commands.sql | 16 +- sql/zkapp_commands.sql | 6 +- src/api/block.rs | 50 +--- src/api/search_transactions.rs | 43 +-- src/lib.rs | 1 + src/sql_to_mesh.rs | 67 +++++ src/types.rs | 24 +- 10 files changed, 291 insertions(+), 370 deletions(-) create mode 100644 .sqlx/query-411a992540d9c8a1eaa3461adc67005bb4515d21a064c1ad13ab9746e23763da.json rename .sqlx/{query-42425d0763c334a282e699ed3a10a050798f7561d56b432d3dceb6aea2830a16.json => query-52d18e4008bd0006fafee2f64d97c2ff75a1d9b210b99eed6f14e8a17d05530b.json} (51%) delete mode 100644 .sqlx/query-56485f1d902b775a7d9702dfe3da13b35f3ec2f47bdccd481116f663d3a5c3bc.json create mode 100644 src/sql_to_mesh.rs diff --git a/.sqlx/query-411a992540d9c8a1eaa3461adc67005bb4515d21a064c1ad13ab9746e23763da.json b/.sqlx/query-411a992540d9c8a1eaa3461adc67005bb4515d21a064c1ad13ab9746e23763da.json new file mode 100644 index 0000000..8bf03bd --- /dev/null +++ b/.sqlx/query-411a992540d9c8a1eaa3461adc67005bb4515d21a064c1ad13ab9746e23763da.json @@ -0,0 +1,156 @@ +{ + "db_name": "PostgreSQL", + "query": "WITH\n canonical_blocks AS (\n SELECT\n *\n FROM\n blocks\n WHERE\n chain_status='canonical'\n ),\n max_canonical_height AS (\n SELECT\n max(HEIGHT) AS max_height\n FROM\n canonical_blocks\n ),\n pending_blocks AS (\n SELECT\n b.*\n FROM\n blocks AS b,\n max_canonical_height AS m\n WHERE\n b.height>m.max_height\n AND b.chain_status='pending'\n ),\n blocks AS (\n SELECT\n *\n FROM\n canonical_blocks\n UNION ALL\n SELECT\n *\n FROM\n pending_blocks\n ),\n zkapp_commands_info AS (\n SELECT\n zc.id,\n zc.memo,\n zc.hash,\n pk_fee_payer.value AS fee_payer,\n pk_update_body.value AS pk_update_body,\n zfpb.fee,\n zfpb.valid_until,\n zfpb.nonce,\n bzc.sequence_no,\n bzc.status AS \"status: TransactionStatus\",\n zaub.balance_change,\n bzc.block_id,\n b.state_hash,\n b.height,\n token_update_body.value AS token,\n ARRAY(\n SELECT\n unnest(zauf.failures)\n FROM\n zkapp_account_update_failures AS zauf\n WHERE\n zauf.id=ANY (bzc.failure_reasons_ids)\n ) AS failure_reasons\n FROM\n zkapp_commands AS zc\n INNER JOIN blocks_zkapp_commands AS bzc ON zc.id=bzc.zkapp_command_id\n INNER JOIN zkapp_fee_payer_body AS zfpb ON zc.zkapp_fee_payer_body_id=zfpb.id\n INNER JOIN public_keys AS pk_fee_payer ON zfpb.public_key_id=pk_fee_payer.id\n INNER JOIN blocks AS b ON bzc.block_id=b.id\n LEFT JOIN zkapp_account_update AS zau ON zau.id=ANY (zc.zkapp_account_updates_ids)\n INNER JOIN zkapp_account_update_body AS zaub ON zau.body_id=zaub.id\n INNER JOIN account_identifiers AS ai_update_body ON zaub.account_identifier_id=ai_update_body.id\n INNER JOIN public_keys AS pk_update_body ON ai_update_body.public_key_id=pk_update_body.id\n INNER JOIN tokens AS token_update_body ON ai_update_body.token_id=token_update_body.id\n WHERE\n (\n $1>=b.height\n OR $1 IS NULL\n )\n AND (\n $2=zc.hash\n OR $2 IS NULL\n )\n AND (\n (\n (\n $3=pk_fee_payer.value\n AND $4=''\n )\n OR (\n $3=pk_update_body.value\n AND $4=token_update_body.value\n )\n )\n OR (\n $3 IS NULL\n AND $4 IS NULL\n )\n )\n AND (\n $5=bzc.status\n OR $5 IS NULL\n )\n AND (\n $6=bzc.status\n OR $6 IS NULL\n )\n AND (\n (\n $7=pk_fee_payer.value\n OR $7=pk_update_body.value\n )\n OR $7 IS NULL\n )\n ),\n zkapp_commands_ids AS (\n SELECT DISTINCT\n id,\n block_id,\n sequence_no\n FROM\n zkapp_commands_info\n ),\n id_count AS (\n SELECT\n count(*) AS total_count\n FROM\n zkapp_commands_ids\n )\nSELECT\n zc.*,\n id_count.total_count\nFROM\n id_count,\n (\n SELECT\n *\n FROM\n zkapp_commands_ids\n ORDER BY\n block_id,\n id,\n sequence_no\n LIMIT\n $8\n OFFSET\n $9\n ) AS ids\n INNER JOIN zkapp_commands_info AS zc ON ids.id=zc.id\n AND ids.block_id=zc.block_id\n AND ids.sequence_no=zc.sequence_no\nORDER BY\n ids.block_id,\n ids.id,\n ids.sequence_no\n", + "describe": { + "columns": [ + { + "ordinal": 0, + "name": "id", + "type_info": "Int4" + }, + { + "ordinal": 1, + "name": "memo", + "type_info": "Text" + }, + { + "ordinal": 2, + "name": "hash", + "type_info": "Text" + }, + { + "ordinal": 3, + "name": "fee_payer", + "type_info": "Text" + }, + { + "ordinal": 4, + "name": "pk_update_body", + "type_info": "Text" + }, + { + "ordinal": 5, + "name": "fee", + "type_info": "Text" + }, + { + "ordinal": 6, + "name": "valid_until", + "type_info": "Int8" + }, + { + "ordinal": 7, + "name": "nonce", + "type_info": "Int8" + }, + { + "ordinal": 8, + "name": "sequence_no", + "type_info": "Int4" + }, + { + "ordinal": 9, + "name": "status: TransactionStatus", + "type_info": { + "Custom": { + "name": "transaction_status", + "kind": { + "Enum": [ + "applied", + "failed" + ] + } + } + } + }, + { + "ordinal": 10, + "name": "balance_change", + "type_info": "Text" + }, + { + "ordinal": 11, + "name": "block_id", + "type_info": "Int4" + }, + { + "ordinal": 12, + "name": "state_hash", + "type_info": "Text" + }, + { + "ordinal": 13, + "name": "height", + "type_info": "Int8" + }, + { + "ordinal": 14, + "name": "token", + "type_info": "Text" + }, + { + "ordinal": 15, + "name": "failure_reasons", + "type_info": "TextArray" + }, + { + "ordinal": 16, + "name": "total_count", + "type_info": "Int8" + } + ], + "parameters": { + "Left": [ + "Int8", + "Text", + "Text", + "Text", + { + "Custom": { + "name": "transaction_status", + "kind": { + "Enum": [ + "applied", + "failed" + ] + } + } + }, + { + "Custom": { + "name": "transaction_status", + "kind": { + "Enum": [ + "applied", + "failed" + ] + } + } + }, + "Text", + "Int8", + "Int8" + ] + }, + "nullable": [ + false, + false, + false, + false, + false, + false, + true, + false, + false, + false, + false, + false, + null, + null, + false, + null, + null + ] + }, + "hash": "411a992540d9c8a1eaa3461adc67005bb4515d21a064c1ad13ab9746e23763da" +} diff --git a/.sqlx/query-42425d0763c334a282e699ed3a10a050798f7561d56b432d3dceb6aea2830a16.json b/.sqlx/query-52d18e4008bd0006fafee2f64d97c2ff75a1d9b210b99eed6f14e8a17d05530b.json similarity index 51% rename from .sqlx/query-42425d0763c334a282e699ed3a10a050798f7561d56b432d3dceb6aea2830a16.json rename to .sqlx/query-52d18e4008bd0006fafee2f64d97c2ff75a1d9b210b99eed6f14e8a17d05530b.json index 5f7dc7c..0dc5cfd 100644 --- a/.sqlx/query-42425d0763c334a282e699ed3a10a050798f7561d56b432d3dceb6aea2830a16.json +++ b/.sqlx/query-52d18e4008bd0006fafee2f64d97c2ff75a1d9b210b99eed6f14e8a17d05530b.json @@ -1,6 +1,6 @@ { "db_name": "PostgreSQL", - "query": "SELECT\n zc.id,\n zc.memo,\n zc.hash,\n pk_fee_payer.value AS fee_payer,\n zfpb.fee,\n zfpb.valid_until,\n zfpb.nonce,\n bzc.sequence_no,\n bzc.status AS \"status: TransactionStatus\",\n ARRAY(\n SELECT\n unnest(zauf.failures)\n FROM\n zkapp_account_update_failures AS zauf\n WHERE\n zauf.id=ANY (bzc.failure_reasons_ids)\n ) AS failure_reasons,\n zaub.balance_change,\n pk_update_body.value AS account,\n token_update_body.value AS token\nFROM\n blocks_zkapp_commands AS bzc\n INNER JOIN zkapp_commands AS zc ON bzc.zkapp_command_id=zc.id\n INNER JOIN zkapp_fee_payer_body AS zfpb ON zc.zkapp_fee_payer_body_id=zfpb.id\n INNER JOIN public_keys AS pk_fee_payer ON zfpb.public_key_id=pk_fee_payer.id\n INNER JOIN blocks AS b ON bzc.block_id=b.id\n LEFT JOIN zkapp_account_update AS zau ON zau.id=ANY (zc.zkapp_account_updates_ids)\n LEFT JOIN zkapp_account_update_body AS zaub ON zau.body_id=zaub.id\n LEFT JOIN account_identifiers AS ai_update_body ON zaub.account_identifier_id=ai_update_body.id\n LEFT JOIN public_keys AS pk_update_body ON ai_update_body.public_key_id=pk_update_body.id\n LEFT JOIN tokens AS token_update_body ON ai_update_body.token_id=token_update_body.id\nWHERE\n bzc.block_id=$1\n AND (\n token_update_body.value=$2\n OR token_update_body.id IS NULL\n )\nORDER BY\n zc.id,\n bzc.sequence_no\n", + "query": "SELECT\n zc.id,\n zc.memo,\n zc.hash,\n pk_fee_payer.value AS fee_payer,\n zfpb.fee,\n zfpb.valid_until,\n zfpb.nonce,\n bzc.sequence_no,\n bzc.status AS \"status: TransactionStatus\",\n b.state_hash,\n b.height,\n bzc.block_id,\n cast(0 AS BIGINT) AS total_count,\n ARRAY(\n SELECT\n unnest(zauf.failures)\n FROM\n zkapp_account_update_failures AS zauf\n WHERE\n zauf.id=ANY (bzc.failure_reasons_ids)\n ) AS failure_reasons,\n zaub.balance_change,\n pk_update_body.value AS pk_update_body,\n token_update_body.value AS token\nFROM\n blocks_zkapp_commands AS bzc\n INNER JOIN zkapp_commands AS zc ON bzc.zkapp_command_id=zc.id\n INNER JOIN zkapp_fee_payer_body AS zfpb ON zc.zkapp_fee_payer_body_id=zfpb.id\n INNER JOIN public_keys AS pk_fee_payer ON zfpb.public_key_id=pk_fee_payer.id\n INNER JOIN blocks AS b ON bzc.block_id=b.id\n LEFT JOIN zkapp_account_update AS zau ON zau.id=ANY (zc.zkapp_account_updates_ids)\n LEFT JOIN zkapp_account_update_body AS zaub ON zau.body_id=zaub.id\n LEFT JOIN account_identifiers AS ai_update_body ON zaub.account_identifier_id=ai_update_body.id\n LEFT JOIN public_keys AS pk_update_body ON ai_update_body.public_key_id=pk_update_body.id\n LEFT JOIN tokens AS token_update_body ON ai_update_body.token_id=token_update_body.id\nWHERE\n bzc.block_id=$1\n AND (\n token_update_body.value=$2\n OR token_update_body.id IS NULL\n )\nORDER BY\n zc.id,\n bzc.sequence_no\n", "describe": { "columns": [ { @@ -60,21 +60,41 @@ }, { "ordinal": 9, + "name": "state_hash", + "type_info": "Text" + }, + { + "ordinal": 10, + "name": "height", + "type_info": "Int8" + }, + { + "ordinal": 11, + "name": "block_id", + "type_info": "Int4" + }, + { + "ordinal": 12, + "name": "total_count", + "type_info": "Int8" + }, + { + "ordinal": 13, "name": "failure_reasons", "type_info": "TextArray" }, { - "ordinal": 10, + "ordinal": 14, "name": "balance_change", "type_info": "Text" }, { - "ordinal": 11, - "name": "account", + "ordinal": 15, + "name": "pk_update_body", "type_info": "Text" }, { - "ordinal": 12, + "ordinal": 16, "name": "token", "type_info": "Text" } @@ -95,11 +115,15 @@ false, false, false, + false, + false, + false, + null, null, false, false, false ] }, - "hash": "42425d0763c334a282e699ed3a10a050798f7561d56b432d3dceb6aea2830a16" + "hash": "52d18e4008bd0006fafee2f64d97c2ff75a1d9b210b99eed6f14e8a17d05530b" } diff --git a/.sqlx/query-56485f1d902b775a7d9702dfe3da13b35f3ec2f47bdccd481116f663d3a5c3bc.json b/.sqlx/query-56485f1d902b775a7d9702dfe3da13b35f3ec2f47bdccd481116f663d3a5c3bc.json deleted file mode 100644 index df58d5f..0000000 --- a/.sqlx/query-56485f1d902b775a7d9702dfe3da13b35f3ec2f47bdccd481116f663d3a5c3bc.json +++ /dev/null @@ -1,262 +0,0 @@ -{ - "db_name": "PostgreSQL", - "query": "WITH\n canonical_blocks AS (\n SELECT\n *\n FROM\n blocks\n WHERE\n chain_status='canonical'\n ),\n max_canonical_height AS (\n SELECT\n max(HEIGHT) AS max_height\n FROM\n canonical_blocks\n ),\n pending_blocks AS (\n SELECT\n b.*\n FROM\n blocks AS b,\n max_canonical_height AS m\n WHERE\n b.height>m.max_height\n AND b.chain_status='pending'\n ),\n blocks AS (\n SELECT\n *\n FROM\n canonical_blocks\n UNION ALL\n SELECT\n *\n FROM\n pending_blocks\n ),\n zkapp_commands_info AS (\n SELECT\n zc.id,\n zc.memo,\n zc.hash,\n pk_fee_payer.value AS fee_payer,\n pk_update_body.value AS pk_update_body,\n zfpb.fee,\n zfpb.valid_until,\n zfpb.nonce,\n bzc.sequence_no,\n bzc.status AS \"status: TransactionStatus\",\n zaub.account_identifier_id,\n zaub.update_id,\n zaub.balance_change,\n zaub.increment_nonce,\n zaub.events_id,\n zaub.actions_id,\n zaub.call_data_id,\n zaub.call_depth,\n zaub.zkapp_network_precondition_id,\n zaub.zkapp_account_precondition_id,\n zaub.zkapp_valid_while_precondition_id,\n zaub.use_full_commitment,\n zaub.implicit_account_creation_fee,\n zaub.may_use_token AS \"may_use_token: MayUseToken\",\n zaub.authorization_kind AS \"authorization_kind: AuthorizationKindType\",\n zaub.verification_key_hash_id,\n bzc.block_id,\n b.state_hash,\n b.height,\n ARRAY(\n SELECT\n unnest(zauf.failures)\n FROM\n zkapp_account_update_failures AS zauf\n WHERE\n zauf.id=ANY (bzc.failure_reasons_ids)\n ) AS failure_reasons\n FROM\n zkapp_commands AS zc\n INNER JOIN blocks_zkapp_commands AS bzc ON zc.id=bzc.zkapp_command_id\n INNER JOIN zkapp_fee_payer_body AS zfpb ON zc.zkapp_fee_payer_body_id=zfpb.id\n INNER JOIN public_keys AS pk_fee_payer ON zfpb.public_key_id=pk_fee_payer.id\n INNER JOIN blocks AS b ON bzc.block_id=b.id\n LEFT JOIN zkapp_account_update AS zau ON zau.id=ANY (zc.zkapp_account_updates_ids)\n INNER JOIN zkapp_account_update_body AS zaub ON zau.body_id=zaub.id\n INNER JOIN account_identifiers AS ai_update_body ON zaub.account_identifier_id=ai_update_body.id\n INNER JOIN public_keys AS pk_update_body ON ai_update_body.public_key_id=pk_update_body.id\n INNER JOIN tokens AS token_update_body ON ai_update_body.token_id=token_update_body.id\n WHERE\n (\n $1>=b.height\n OR $1 IS NULL\n )\n AND (\n $2=zc.hash\n OR $2 IS NULL\n )\n AND (\n (\n (\n $3=pk_fee_payer.value\n AND $4=''\n )\n OR (\n $3=pk_update_body.value\n AND $4=token_update_body.value\n )\n )\n OR (\n $3 IS NULL\n AND $4 IS NULL\n )\n )\n AND (\n $5=bzc.status\n OR $5 IS NULL\n )\n AND (\n $6=bzc.status\n OR $6 IS NULL\n )\n AND (\n (\n $7=pk_fee_payer.value\n OR $7=pk_update_body.value\n )\n OR $7 IS NULL\n )\n ),\n zkapp_commands_ids AS (\n SELECT DISTINCT\n id,\n block_id,\n sequence_no\n FROM\n zkapp_commands_info\n ),\n id_count AS (\n SELECT\n count(*) AS total_count\n FROM\n zkapp_commands_ids\n )\nSELECT\n zc.*,\n id_count.total_count\nFROM\n id_count,\n (\n SELECT\n *\n FROM\n zkapp_commands_ids\n ORDER BY\n block_id,\n id,\n sequence_no\n LIMIT\n $8\n OFFSET\n $9\n ) AS ids\n INNER JOIN zkapp_commands_info AS zc ON ids.id=zc.id\n AND ids.block_id=zc.block_id\n AND ids.sequence_no=zc.sequence_no\nORDER BY\n ids.block_id,\n ids.id,\n ids.sequence_no\n", - "describe": { - "columns": [ - { - "ordinal": 0, - "name": "id", - "type_info": "Int4" - }, - { - "ordinal": 1, - "name": "memo", - "type_info": "Text" - }, - { - "ordinal": 2, - "name": "hash", - "type_info": "Text" - }, - { - "ordinal": 3, - "name": "fee_payer", - "type_info": "Text" - }, - { - "ordinal": 4, - "name": "pk_update_body", - "type_info": "Text" - }, - { - "ordinal": 5, - "name": "fee", - "type_info": "Text" - }, - { - "ordinal": 6, - "name": "valid_until", - "type_info": "Int8" - }, - { - "ordinal": 7, - "name": "nonce", - "type_info": "Int8" - }, - { - "ordinal": 8, - "name": "sequence_no", - "type_info": "Int4" - }, - { - "ordinal": 9, - "name": "status: TransactionStatus", - "type_info": { - "Custom": { - "name": "transaction_status", - "kind": { - "Enum": [ - "applied", - "failed" - ] - } - } - } - }, - { - "ordinal": 10, - "name": "account_identifier_id", - "type_info": "Int4" - }, - { - "ordinal": 11, - "name": "update_id", - "type_info": "Int4" - }, - { - "ordinal": 12, - "name": "balance_change", - "type_info": "Text" - }, - { - "ordinal": 13, - "name": "increment_nonce", - "type_info": "Bool" - }, - { - "ordinal": 14, - "name": "events_id", - "type_info": "Int4" - }, - { - "ordinal": 15, - "name": "actions_id", - "type_info": "Int4" - }, - { - "ordinal": 16, - "name": "call_data_id", - "type_info": "Int4" - }, - { - "ordinal": 17, - "name": "call_depth", - "type_info": "Int4" - }, - { - "ordinal": 18, - "name": "zkapp_network_precondition_id", - "type_info": "Int4" - }, - { - "ordinal": 19, - "name": "zkapp_account_precondition_id", - "type_info": "Int4" - }, - { - "ordinal": 20, - "name": "zkapp_valid_while_precondition_id", - "type_info": "Int4" - }, - { - "ordinal": 21, - "name": "use_full_commitment", - "type_info": "Bool" - }, - { - "ordinal": 22, - "name": "implicit_account_creation_fee", - "type_info": "Bool" - }, - { - "ordinal": 23, - "name": "may_use_token: MayUseToken", - "type_info": { - "Custom": { - "name": "may_use_token", - "kind": { - "Enum": [ - "No", - "ParentsOwnToken", - "InheritFromParent" - ] - } - } - } - }, - { - "ordinal": 24, - "name": "authorization_kind: AuthorizationKindType", - "type_info": { - "Custom": { - "name": "authorization_kind_type", - "kind": { - "Enum": [ - "None_given", - "Signature", - "Proof" - ] - } - } - } - }, - { - "ordinal": 25, - "name": "verification_key_hash_id", - "type_info": "Int4" - }, - { - "ordinal": 26, - "name": "block_id", - "type_info": "Int4" - }, - { - "ordinal": 27, - "name": "state_hash", - "type_info": "Text" - }, - { - "ordinal": 28, - "name": "height", - "type_info": "Int8" - }, - { - "ordinal": 29, - "name": "failure_reasons", - "type_info": "TextArray" - }, - { - "ordinal": 30, - "name": "total_count", - "type_info": "Int8" - } - ], - "parameters": { - "Left": [ - "Int8", - "Text", - "Text", - "Text", - { - "Custom": { - "name": "transaction_status", - "kind": { - "Enum": [ - "applied", - "failed" - ] - } - } - }, - { - "Custom": { - "name": "transaction_status", - "kind": { - "Enum": [ - "applied", - "failed" - ] - } - } - }, - "Text", - "Int8", - "Int8" - ] - }, - "nullable": [ - false, - false, - false, - false, - false, - false, - true, - false, - false, - false, - false, - false, - false, - false, - false, - false, - false, - false, - false, - false, - true, - false, - false, - false, - false, - true, - false, - null, - null, - null, - null - ] - }, - "hash": "56485f1d902b775a7d9702dfe3da13b35f3ec2f47bdccd481116f663d3a5c3bc" -} diff --git a/sql/indexer_zkapp_commands.sql b/sql/indexer_zkapp_commands.sql index 9fd3d9e..05f89e8 100644 --- a/sql/indexer_zkapp_commands.sql +++ b/sql/indexer_zkapp_commands.sql @@ -46,25 +46,11 @@ WITH zfpb.nonce, bzc.sequence_no, bzc.status AS "status: TransactionStatus", - zaub.account_identifier_id, - zaub.update_id, zaub.balance_change, - zaub.increment_nonce, - zaub.events_id, - zaub.actions_id, - zaub.call_data_id, - zaub.call_depth, - zaub.zkapp_network_precondition_id, - zaub.zkapp_account_precondition_id, - zaub.zkapp_valid_while_precondition_id, - zaub.use_full_commitment, - zaub.implicit_account_creation_fee, - zaub.may_use_token AS "may_use_token: MayUseToken", - zaub.authorization_kind AS "authorization_kind: AuthorizationKindType", - zaub.verification_key_hash_id, bzc.block_id, b.state_hash, b.height, + token_update_body.value AS token, ARRAY( SELECT unnest(zauf.failures) diff --git a/sql/zkapp_commands.sql b/sql/zkapp_commands.sql index eed3c79..dc8d359 100644 --- a/sql/zkapp_commands.sql +++ b/sql/zkapp_commands.sql @@ -8,6 +8,10 @@ SELECT zfpb.nonce, bzc.sequence_no, bzc.status AS "status: TransactionStatus", + b.state_hash, + b.height, + bzc.block_id, + cast(0 AS BIGINT) AS total_count, ARRAY( SELECT unnest(zauf.failures) @@ -17,7 +21,7 @@ SELECT zauf.id=ANY (bzc.failure_reasons_ids) ) AS failure_reasons, zaub.balance_change, - pk_update_body.value AS account, + pk_update_body.value AS pk_update_body, token_update_body.value AS token FROM blocks_zkapp_commands AS bzc diff --git a/src/api/block.rs b/src/api/block.rs index e1fcc30..fa0cba1 100644 --- a/src/api/block.rs +++ b/src/api/block.rs @@ -7,8 +7,8 @@ use serde::Serialize; use sqlx::FromRow; use crate::{ - operation, util::DEFAULT_TOKEN_ID, ChainStatus, InternalCommandType, MinaMesh, MinaMeshError, OperationType, - TransactionStatus, UserCommandType, + operation, sql_to_mesh::zkapp_commands_to_transactions, util::DEFAULT_TOKEN_ID, ChainStatus, InternalCommandType, + MinaMesh, MinaMeshError, OperationType, TransactionStatus, UserCommandType, ZkAppCommand, }; /// https://github.com/MinaProtocol/mina/blob/985eda49bdfabc046ef9001d3c406e688bc7ec45/src/app/rosetta/lib/block.ml#L7 @@ -78,37 +78,10 @@ impl MinaMesh { } pub async fn zkapp_commands(&self, metadata: &BlockMetadata) -> Result, MinaMeshError> { - let metadata = sqlx::query_file_as!(ZkappCommandMetadata, "sql/zkapp_commands.sql", metadata.id, DEFAULT_TOKEN_ID) + let metadata = sqlx::query_file_as!(ZkAppCommand, "sql/zkapp_commands.sql", metadata.id, DEFAULT_TOKEN_ID) .fetch_all(&self.pg_pool) .await?; - let mut transactions = Vec::new(); - let mut operations = Vec::new(); - let mut current_txn_identifier = TransactionIdentifier::new(metadata[0].hash.clone()); - for item in metadata { - if current_txn_identifier.hash != item.hash { - transactions.push(Transaction::new(current_txn_identifier, operations)); - operations = Vec::new(); - current_txn_identifier = TransactionIdentifier::new(item.hash.clone()); - } - operations.push(operation( - operations.len() as i64, - Some(&item.fee), - &AccountIdentifier::new(item.fee_payer.clone()), - OperationType::ZkappFeePayerDec, - None, - None, - None, - )); - operations.push(operation( - operations.len() as i64, - Some(&item.balance_change), - &AccountIdentifier::new(item.account.clone()), - OperationType::ZkappBalanceUpdate, - None, - None, - None, - )); - } + let transactions = zkapp_commands_to_transactions(metadata); Ok(transactions) } @@ -362,18 +335,3 @@ fn internal_command_metadata_to_operation(metadata: &InternalCommandMetadata) -> } Ok(operations) } - -// TODO: implement -fn zkapp_command_metadata_to_operation(metadata: Vec) -> Result, MinaMeshError> { - // Go through each zkapp command in the vector - - // If the command id is the same as the previous, create a new operation from it - // and join it with the remaining operations of this transaction - - // If the command id is different than the previous, wrap up the previous - // transaction and start producing a new one, starting with the operation from - // this entry - - // Return a vec with the produced txns - Ok(Vec::new()) -} diff --git a/src/api/search_transactions.rs b/src/api/search_transactions.rs index e72675d..ed998d0 100644 --- a/src/api/search_transactions.rs +++ b/src/api/search_transactions.rs @@ -9,8 +9,8 @@ use serde_json::{json, Map, Value}; use sqlx::FromRow; use crate::{ - operation, util::DEFAULT_TOKEN_ID, AuthorizationKindType, ChainStatus, InternalCommandType, MayUseToken, MinaMesh, - MinaMeshError, OperationType, TransactionStatus, UserCommandType, + operation, util::DEFAULT_TOKEN_ID, ChainStatus, InternalCommandType, MinaMesh, MinaMeshError, OperationType, + TransactionStatus, UserCommandType, ZkAppCommand, }; impl MinaMesh { @@ -159,41 +159,6 @@ impl MinaMesh { } } -#[derive(FromRow)] -pub struct ZkAppCommand { - pub id: Option, - pub memo: Option, - pub hash: String, - pub fee_payer: String, - pub pk_update_body: String, - pub fee: Option, - pub valid_until: Option, - pub nonce: Option, - pub sequence_no: i32, - pub status: TransactionStatus, - pub account_identifier_id: Option, - pub update_id: Option, - pub balance_change: Option, - pub increment_nonce: bool, - pub events_id: Option, - pub actions_id: Option, - pub call_data_id: Option, - pub call_depth: Option, - pub zkapp_network_precondition_id: Option, - pub zkapp_account_precondition_id: Option, - pub zkapp_valid_while_precondition_id: Option, - pub use_full_commitment: bool, - pub implicit_account_creation_fee: bool, - pub may_use_token: MayUseToken, - pub authorization_kind: AuthorizationKindType, - pub verification_key_hash_id: Option, - pub block_id: Option, - pub state_hash: Option, - pub height: Option, - pub failure_reasons: Option>, - pub total_count: Option, -} - pub fn zkapp_commands_to_block_transactions(commands: Vec) -> Vec { let mut block_map: HashMap<(i64, String), HashMap>> = HashMap::new(); @@ -209,7 +174,7 @@ pub fn zkapp_commands_to_block_transactions(commands: Vec) -> Vec< if operations.is_empty() { operations.push(operation( 0, - Some(&format!("-{}", command.fee.unwrap_or("0".to_string()))), + Some(&format!("-{}", command.fee)), &AccountIdentifier { address: command.fee_payer.clone(), metadata: Some(json!({ "token_id": DEFAULT_TOKEN_ID })), @@ -225,7 +190,7 @@ pub fn zkapp_commands_to_block_transactions(commands: Vec) -> Vec< // Add zkapp balance update operation operations.push(operation( 0, - command.balance_change.as_ref(), + Some(&command.balance_change), &AccountIdentifier { address: command.pk_update_body.clone(), metadata: Some(json!({ "token_id": DEFAULT_TOKEN_ID })), diff --git a/src/lib.rs b/src/lib.rs index 017323c..dee15bb 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -5,6 +5,7 @@ mod error; mod graphql; mod operation; mod playground; +mod sql_to_mesh; mod types; mod util; diff --git a/src/sql_to_mesh.rs b/src/sql_to_mesh.rs new file mode 100644 index 0000000..39c0144 --- /dev/null +++ b/src/sql_to_mesh.rs @@ -0,0 +1,67 @@ +use std::collections::HashMap; + +use coinbase_mesh::models::{AccountIdentifier, Operation, Transaction, TransactionIdentifier}; +use serde_json::json; + +use crate::{operation, util::DEFAULT_TOKEN_ID, OperationType, TransactionStatus, ZkAppCommand}; + +pub fn zkapp_commands_to_transactions(commands: Vec) -> Vec { + let mut tx_map: HashMap> = HashMap::new(); + + for command in commands { + let tx_hash = command.hash.clone(); + + // Initialize or update the operation list for this transaction + let operations = tx_map.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, + )); + } + + // 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": DEFAULT_TOKEN_ID })), + sub_account: None, + }, + OperationType::ZkappBalanceUpdate, + Some(&command.status), + None, + None, + )); + } + + let mut result = Vec::new(); + 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 transaction = Transaction { + transaction_identifier: Box::new(TransactionIdentifier { hash: tx_hash.clone() }), + operations, + metadata: None, + related_transactions: None, + }; + result.push(transaction); + } + + result +} diff --git a/src/types.rs b/src/types.rs index 14a1d96..c9558fb 100644 --- a/src/types.rs +++ b/src/types.rs @@ -1,6 +1,6 @@ use derive_more::derive::Display; use serde::Serialize; -use sqlx::Type; +use sqlx::{FromRow, Type}; #[derive(Type, Debug, PartialEq, Eq, Serialize)] #[sqlx(type_name = "chain_status_type", rename_all = "lowercase")] @@ -83,3 +83,25 @@ pub enum AuthorizationKindType { #[sqlx(rename = "Proof")] Proof, } + +#[allow(dead_code)] +#[derive(FromRow)] +pub struct ZkAppCommand { + pub id: Option, + pub memo: Option, + pub hash: String, + pub fee_payer: String, + pub pk_update_body: String, + pub fee: String, + pub valid_until: Option, + pub nonce: Option, + pub sequence_no: i32, + pub status: TransactionStatus, + pub balance_change: String, + pub state_hash: Option, + pub failure_reasons: Option>, + pub token: Option, + pub height: Option, + pub total_count: Option, + pub block_id: Option, +} From f950047ee6dcbf2b0031ce5fa443d35e1ded0380 Mon Sep 17 00:00:00 2001 From: Harry Solovay Date: Fri, 18 Oct 2024 08:54:47 -0400 Subject: [PATCH 09/21] fix snap --- ...ons__search_transactions_zkapp_failed.snap | 125 ------------------ 1 file changed, 125 deletions(-) diff --git a/tests/snapshots/search_transactions__search_transactions_zkapp_failed.snap b/tests/snapshots/search_transactions__search_transactions_zkapp_failed.snap index c72388a..a35e65d 100644 --- a/tests/snapshots/search_transactions__search_transactions_zkapp_failed.snap +++ b/tests/snapshots/search_transactions__search_transactions_zkapp_failed.snap @@ -125,133 +125,8 @@ Ok( metadata: None, }, }, -<<<<<<< HEAD ], total_count: 1, -======= - BlockTransaction { - block_identifier: BlockIdentifier { - index: 356949, - hash: "3NKL6D7kcvH28odK9QpCqvKuHjx2jm2BhfKjPVkvLLyAoKKMD3JF", - }, - transaction: Transaction { - transaction_identifier: TransactionIdentifier { - hash: "5JujBt8rnKheA7CHBnTwUDXrHtQxqPB9LL5Q8y4KwLjPBsBSJuSE", - }, - operations: [ - Operation { - operation_identifier: OperationIdentifier { - index: 0, - network_index: None, - }, - related_operations: None, - type: "zkapp_fee_payer_dec", - status: Some( - "Success", - ), - account: Some( - AccountIdentifier { - address: "B62qjGsPY47SMkTykivPBAU3riS9gvMMrGr7ve6ynoHJNBzAhQmtoBn", - sub_account: None, - metadata: Some( - Object { - "token_id": String("wSHV2S4qX9jFsLjQo8r1BsMLH2ZRKsZx6EJd1sbozGPieEC4Jf"), - }, - ), - }, - ), - amount: Some( - Amount { - value: "-100000000", - currency: Currency { - symbol: "MINA", - decimals: 9, - metadata: None, - }, - metadata: None, - }, - ), - coin_change: None, - metadata: None, - }, - Operation { - operation_identifier: OperationIdentifier { - index: 1, - network_index: None, - }, - related_operations: None, - type: "zkapp_balance_update", - status: Some( - "Failed", - ), - account: Some( - AccountIdentifier { - address: "B62qide3tEVFgzLFo72rhrF4p8Luv6R5NAmvwo83SnZGnwV9Q6fiVTK", - sub_account: None, - metadata: Some( - Object { - "token_id": String("wSHV2S4qX9jFsLjQo8r1BsMLH2ZRKsZx6EJd1sbozGPieEC4Jf"), - }, - ), - }, - ), - amount: Some( - Amount { - value: "0", - currency: Currency { - symbol: "MINA", - decimals: 9, - metadata: None, - }, - metadata: None, - }, - ), - coin_change: None, - metadata: None, - }, - Operation { - operation_identifier: OperationIdentifier { - index: 2, - network_index: None, - }, - related_operations: None, - type: "zkapp_balance_update", - status: Some( - "Failed", - ), - account: Some( - AccountIdentifier { - address: "B62qjGsPY47SMkTykivPBAU3riS9gvMMrGr7ve6ynoHJNBzAhQmtoBn", - sub_account: None, - metadata: Some( - Object { - "token_id": String("wSHV2S4qX9jFsLjQo8r1BsMLH2ZRKsZx6EJd1sbozGPieEC4Jf"), - }, - ), - }, - ), - amount: Some( - Amount { - value: "0", - currency: Currency { - symbol: "MINA", - decimals: 9, - metadata: None, - }, - metadata: None, - }, - ), - coin_change: None, - metadata: None, - }, - ], - related_transactions: None, - metadata: None, - }, - }, - ], - total_count: 2, ->>>>>>> bdc48f0 (tests) next_offset: None, }, ) From d85c979a75d30acd37bfbe80c63226c4fa881dea Mon Sep 17 00:00:00 2001 From: Harry Solovay Date: Fri, 18 Oct 2024 10:49:09 -0400 Subject: [PATCH 10/21] remove just --- .env.example | 2 + .github/CODEOWNERS | 2 +- .github/workflows/checks.yaml | 3 +- .vscode/settings.json | 3 ++ CONTRIBUTING.md | 22 +++----- Justfile | 25 --------- deno.json | 52 ++++++++++++++++++ dprint.json | 8 ++- scripts/get_archive_db.sh | 36 ------------- tasks/dl.ts | 62 ++++++++++++++++++++++ {scripts => tasks}/enable_logging.sh | 4 +- scripts/wait_for_pg.sh => tasks/pg_wait.sh | 0 tasks/pg_wait.ts | 36 +++++++++++++ words.txt | 11 +++- 14 files changed, 183 insertions(+), 83 deletions(-) delete mode 100644 Justfile create mode 100644 deno.json delete mode 100755 scripts/get_archive_db.sh create mode 100644 tasks/dl.ts rename {scripts => tasks}/enable_logging.sh (81%) rename scripts/wait_for_pg.sh => tasks/pg_wait.sh (100%) create mode 100644 tasks/pg_wait.ts diff --git a/.env.example b/.env.example index c93adda..21a0e54 100644 --- a/.env.example +++ b/.env.example @@ -6,3 +6,5 @@ MINAMESH_GENESIS_BLOCK_IDENTIFIER_HEIGHT=359605 RUST_LOG=debug,error,mina_mesh=info RUST_ENV=production + +SNAP_CHECK=1 diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 1451f45..45bf5d2 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -1 +1 @@ -* @harrysolovay @joaosreis @johnmarcou +* @harrysolovay @joaosreis @johnmarcou @piotr-iohk diff --git a/.github/workflows/checks.yaml b/.github/workflows/checks.yaml index bbb0973..7a7311e 100644 --- a/.github/workflows/checks.yaml +++ b/.github/workflows/checks.yaml @@ -46,7 +46,6 @@ jobs: steps: - uses: actions/checkout@v4 - uses: dsherret/rust-toolchain-file@v1 - - uses: extractions/setup-just@v2 - uses: actions/cache@v4 with: path: | @@ -57,7 +56,7 @@ jobs: - name: Test run: | sed "s|postgres://mina:whatever@localhost:5432/archive|$MINAMESH_ARCHIVE_DATABASE_URL_DEVNET|g" .env.example.devnet > .env - just test + cargo test env: MINAMESH_ARCHIVE_DATABASE_URL_DEVNET: ${{ secrets.MINAMESH_ARCHIVE_DATABASE_URL_DEVNET }} diff --git a/.vscode/settings.json b/.vscode/settings.json index f7f84cb..7b92131 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -23,6 +23,9 @@ "[toml]": { "editor.defaultFormatter": "dprint.dprint" }, + "[typescript]": { + "editor.defaultFormatter": "dprint.dprint" + }, "[yaml]": { "editor.defaultFormatter": "dprint.dprint" }, diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index d84cbfa..575c78b 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -14,7 +14,7 @@ To develop on your machine, install the following (and please submit issues if e - [Rust](https://www.rust-lang.org/tools/install) - [Docker](https://docs.docker.com/get-docker/) - [dprint](https://dprint.dev/) -- [Just](https://github.com/casey/just) +- [Deno](https://github.com/denoland/deno?tab=readme-ov-file#installation) - [sql-formatter](https://github.com/sql-formatter-org/sql-formatter) - [insta](https://insta.rs/) @@ -84,29 +84,23 @@ changes by contributors where you believe you have something valuable to add or ### Ensure Test DB Accessible -- **Stop PostgreSQL**: To stop the PostgreSQL instance: +If you've already initialized the archive database, ensure it's running (potentially with a +`deno pg:up`). Otherwise, initialize the development archive database. - ```bash - just pg-down - ``` - -- **Restart PostgreSQL**: To restart without reinitializing the database (useful if the database is - already set up): - - ```bash - just pg-up - ``` +```sh +deno task dev:init +``` > You only need to reinitialize the database if you want the latest data dump. ### Run Tests -```bash +```sh cargo test ``` ### Update Snapshots -``` +```sh cargo insta review ``` diff --git a/Justfile b/Justfile deleted file mode 100644 index 784511e..0000000 --- a/Justfile +++ /dev/null @@ -1,25 +0,0 @@ -pg: - docker run -d --name mina-archive-db -p 5432:5432 -v $(pwd)/sql_scripts:/docker-entrypoint-initdb.d -e POSTGRES_PASSWORD=whatever -e POSTGRES_USER=mina postgres - -pg-up: - docker start mina-archive-db - -pg-down: - docker kill mina-archive-db - -pg-rm: - docker rm mina-archive-db - -get-mainnet-archive-db: - ./scripts/get_archive_db.sh mainnet - -wait-for-pg: - ./scripts/wait_for_pg.sh - -test: - SNAP_CHECK=1 cargo test - -setup-archive-db: - just get-mainnet-archive-db - just pg - just wait-for-pg \ No newline at end of file diff --git a/deno.json b/deno.json new file mode 100644 index 0000000..7bf7cda --- /dev/null +++ b/deno.json @@ -0,0 +1,52 @@ +{ + "exclude": ["target"], + "lock": false, + "tasks": { + "dl:devnet": "deno run -A tasks/dl.ts", + "dl:mainnet": "deno task dl:devnet --network mainnet", + "pg:init": "docker run -d --name mina-archive-db -p 5432:5432 -v $(pwd)/sql_scripts:/docker-entrypoint-initdb.d -e POSTGRES_PASSWORD=whatever -e POSTGRES_USER=mina postgres", + "pg:wait": "./tasks/pg_wait.sh", + "pg:up": "docker start mina-archive-db", + "pg:down": "docker kill mina-archive-db", + "pg:rm": "docker rm mina-archive-db", + "dev:init": "deno task dl:devnet && deno task pg:init && deno task pg:wait", + "dev": "cargo run serve --playground" + }, + "imports": { + "@qnighy/dedent": "jsr:@qnighy/dedent@^0.1.2", + "@std/assert": "jsr:@std/assert@1", + "@std/async": "jsr:@std/async@^1.0.6", + "@std/cache": "jsr:@std/cache@^0.1.3", + "@std/cli": "jsr:@std/cli@^1.0.6", + "@std/datetime": "jsr:@std/datetime@^0.225.2", + "@std/dotenv": "jsr:@std/dotenv@^0.225.2", + "@std/encoding": "jsr:@std/encoding@^1.0.5", + "@std/fs": "jsr:@std/fs@^1.0.4", + "@std/http": "jsr:@std/http@1", + "@std/path": "jsr:@std/path@^1.0.6", + "@std/tar": "jsr:@std/tar@^0.1.2", + "@std/text": "jsr:@std/text@^1.0.7", + "@types/json-schema": "npm:@types/json-schema@^7.0.15", + "@types/pg": "npm:@types/pg@^8.11.10", + "pg": "npm:pg@^8.13.0" + }, + "lint": { + "rules": { + "include": ["ban-untagged-todo", "guard-for-in"], + "exclude": [ + "ban-types", + "ban-untagged-todo", + "no-empty", + "no-explicit-any", + "no-inner-declarations", + "no-namespace" + ] + } + }, + "compilerOptions": { + "lib": ["deno.window"], + "noFallthroughCasesInSwitch": true, + "noPropertyAccessFromIndexSignature": false, + "noUncheckedIndexedAccess": true + } +} diff --git a/dprint.json b/dprint.json index 7100330..5e72e05 100644 --- a/dprint.json +++ b/dprint.json @@ -13,6 +13,11 @@ "markdown": { "textWrap": "always" }, + "typescript": { + "arrowFunction.useParentheses": "force", + "quoteProps": "asNeeded", + "semiColons": "asi" + }, "excludes": [".sqlx", "src/graphql/generated.rs"], "plugins": [ "https://plugins.dprint.dev/dockerfile-0.3.2.wasm", @@ -20,6 +25,7 @@ "https://plugins.dprint.dev/g-plane/pretty_yaml-v0.5.0.wasm", "https://plugins.dprint.dev/json-0.19.3.wasm", "https://plugins.dprint.dev/markdown-0.17.8.wasm", - "https://plugins.dprint.dev/toml-0.6.3.wasm" + "https://plugins.dprint.dev/toml-0.6.3.wasm", + "https://plugins.dprint.dev/typescript-0.93.0.wasm" ] } diff --git a/scripts/get_archive_db.sh b/scripts/get_archive_db.sh deleted file mode 100755 index 2cba484..0000000 --- a/scripts/get_archive_db.sh +++ /dev/null @@ -1,36 +0,0 @@ -#!/bin/bash - -# This script is used to download the archive dump from the mina-archive-dumps bucket -# and extract the archive dump to the sql_scripts directory -# The script will download the archive dump for the last 5 days and extract the first available archive dump -# Usage: ./scripts/get_archive_db.sh -# Example: ./scripts/get_archive_db.sh mainnet - -MINA_NETWORK=${1} -MINA_ARCHIVE_DUMP_URL=${MINA_ARCHIVE_DUMP_URL:=https://storage.googleapis.com/mina-archive-dumps} -DUMP_TIME=0000 -SQL_SCRIPT_PATH=$(pwd)/sql_scripts -TAR_FILE_PATH=${SQL_SCRIPT_PATH}/o1labs-archive-dump.tar.gz - -mkdir -p ${SQL_SCRIPT_PATH} - -MAX_DAYS_LOOKBACK=5 -i=0 -while [ $i -lt $MAX_DAYS_LOOKBACK ]; do - DATE=$(date -d "$i days ago" +%G-%m-%d)_${DUMP_TIME} - STATUS_CODE=$(curl -s -o /dev/null --head -w "%{http_code}" "${MINA_ARCHIVE_DUMP_URL}/${MINA_NETWORK}-archive-dump-${DATE}.sql.tar.gz") - if [[ ! $STATUS_CODE =~ 2[0-9]{2} ]]; then - i=$((i + 1)) - else - echo "Download ${MINA_NETWORK}-archive-dump-${DATE}.sql.tar.gz" - curl "${MINA_ARCHIVE_DUMP_URL}/${MINA_NETWORK}-archive-dump-${DATE}.sql.tar.gz" -o ${TAR_FILE_PATH} - break - fi -done - -[[ $STATUS_CODE =~ 2[0-9]{2} ]] || echo "[WARN] Unable to find archive dump for ${MINA_NETWORK}" - -tar -xvf ${SQL_SCRIPT_PATH}/o1labs-archive-dump.tar.gz -C ${SQL_SCRIPT_PATH} -rm -f ${TAR_FILE_PATH} - -echo "Extracted ${MINA_NETWORK}-archive-dump-${DATE}.sql.tar.gz to ${SQL_SCRIPT_PATH}/${MINA_NETWORK}-archive-dump-${DATE}.sql" diff --git a/tasks/dl.ts b/tasks/dl.ts new file mode 100644 index 0000000..a454823 --- /dev/null +++ b/tasks/dl.ts @@ -0,0 +1,62 @@ +import { dedent } from "@qnighy/dedent" +import { assert, assertExists } from "@std/assert" +import { parseArgs } from "@std/cli" +import { format } from "@std/datetime" +import * as fs from "@std/fs" +import * as path from "@std/path" + +const MINA_ARCHIVE_DUMP_URL = "https://storage.googleapis.com/mina-archive-dumps" + +const { network, "dump-time": dumpTime } = parseArgs(Deno.args, { + string: ["network", "dump-time"], + default: { + network: "devnet", + "dump-time": "0000", + }, +}) + +assert( + ({ + devnet: true, + mainnet: true, + } as Record)[network], +) + +const date = format( + (() => { // 3d ago + const d = new Date() + d.setDate(d.getDate() - 3) + return d + })(), + "yyyy-MM-dd", +) +const dumpUrl = `${MINA_ARCHIVE_DUMP_URL}/${network}-archive-dump-${date}_${dumpTime}.sql.tar.gz` +const destDir = path.join(Deno.cwd(), "sql_scripts") +const dest = path.join(destDir, "archive.tar") + +console.log(`Downloading ${dumpUrl} to ${dest}`) + +await fs.emptyDir(destDir) + +const dumpTarStream = await fetch(dumpUrl).then((v) => v.body) +assertExists(dumpTarStream) + +const file = await Deno.open(dest, { + createNew: true, + append: true, +}) +await dumpTarStream.pipeThrough(new DecompressionStream("gzip")).pipeTo(file.writable) + +// TODO: utilize `UntarStream` from `@std/tar` +await new Deno.Command("tar", { + args: ["-xf", "archive.tar"], + stdout: "inherit", + stderr: "inherit", + cwd: destDir, +}).output() + +// TODO: automatically enable? (thoughts piotr-iohk?) +// await Deno.copyFile( +// import.meta.resolve("./enable_logging.sh"), +// path.join(destDir, "enable_logging.sh"), +// ) diff --git a/scripts/enable_logging.sh b/tasks/enable_logging.sh similarity index 81% rename from scripts/enable_logging.sh rename to tasks/enable_logging.sh index f37439a..6c9056f 100755 --- a/scripts/enable_logging.sh +++ b/tasks/enable_logging.sh @@ -1,8 +1,8 @@ #!/bin/bash # This script enables logging of sql statements in the PostgreSQL database -# Put this script in the `../sql_scripts` directory and once you use `just pg` it will be executed automatically -# In order to follow the logs, you can use `docker mina-archive-db logs -f` +# Put this script in the `../sql_scripts` directory and once you use `deno task pg:init` or `deno task dev:init` it will be executed automatically +# In order to follow the logs, you can use `docker mina-archive-db logs -f` echo "Enabling logging settings..." diff --git a/scripts/wait_for_pg.sh b/tasks/pg_wait.sh similarity index 100% rename from scripts/wait_for_pg.sh rename to tasks/pg_wait.sh diff --git a/tasks/pg_wait.ts b/tasks/pg_wait.ts new file mode 100644 index 0000000..eaf49eb --- /dev/null +++ b/tasks/pg_wait.ts @@ -0,0 +1,36 @@ +// TODO: would we rather use a TypeScript equivalent? + +import pg from "pg" +import "@std/dotenv/load" +import { assertExists } from "@std/assert" + +const connectionString = Deno.env.get("DATABASE_URL") +assertExists(connectionString) +const client = new pg.Client({ connectionString }) + +const MAX_RETRIES = 200 +const RETRY_INTERVAL_MS = 10_000 + +let connected = false +let attempts = 0 + +while (!connected && attempts < MAX_RETRIES) { + try { + await client.connect() + connected = true + } catch (err: unknown) { + if (err instanceof Error && err.message.startsWith("Client has already been connected.")) { + connected = true + break + } + attempts++ + console.log("Waiting for database to be ready.") + console.error(err) + await new Promise((resolve) => setTimeout(resolve, RETRY_INTERVAL_MS)) + } +} + +if (connected) { + await client.end() + console.log("Database ready") +} else throw 0 diff --git a/words.txt b/words.txt index ff84354..4e41c6e 100644 --- a/words.txt +++ b/words.txt @@ -1,9 +1,9 @@ -MINAMESH -RUSTFLAGS codegen coinbases darklight +datetime deamon +deno devnet dotenv dprint @@ -17,6 +17,7 @@ harrysolovay indoc initdb insta +iohk isready joaosreis johnmarcou @@ -26,13 +27,17 @@ lookback microschemas mina minafoundation +MINAMESH navroot nocapture openapi +piotr preprocess +qnighy querygen reqwest retriable +RUSTFLAGS rustfmt schnorr secp @@ -40,6 +45,8 @@ snarked sqltools sqlx thiserror +untar +untarring urlencode utxo walkdir From 55e77da28cf6a49f25b2864ad21ef6de190684fc Mon Sep 17 00:00:00 2001 From: Harry Solovay Date: Fri, 18 Oct 2024 10:57:45 -0400 Subject: [PATCH 11/21] add to dprint --- dprint.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dprint.json b/dprint.json index 5e72e05..881c85f 100644 --- a/dprint.json +++ b/dprint.json @@ -18,7 +18,7 @@ "quoteProps": "asNeeded", "semiColons": "asi" }, - "excludes": [".sqlx", "src/graphql/generated.rs"], + "excludes": [".sqlx", "src/graphql/generated.rs", "target"], "plugins": [ "https://plugins.dprint.dev/dockerfile-0.3.2.wasm", "https://plugins.dprint.dev/exec-0.5.0.json@8d9972eee71fa1590e04873540421f3eda7674d0f1aae3d7c788615e7b7413d0", From 4b2359521680b4a0928d444765e82f3229c8e09e Mon Sep 17 00:00:00 2001 From: Harry Solovay Date: Fri, 18 Oct 2024 10:59:32 -0400 Subject: [PATCH 12/21] more --- dprint.json => dprint.jsonc | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) rename dprint.json => dprint.jsonc (83%) diff --git a/dprint.json b/dprint.jsonc similarity index 83% rename from dprint.json rename to dprint.jsonc index 881c85f..c1e7ade 100644 --- a/dprint.json +++ b/dprint.jsonc @@ -6,17 +6,17 @@ "commands": [ { "command": "sql-formatter -c sql_fmt.json -l postgresql", - "exts": ["sql"] - } - ] + "exts": ["sql"], + }, + ], }, "markdown": { - "textWrap": "always" + "textWrap": "always", }, "typescript": { "arrowFunction.useParentheses": "force", "quoteProps": "asNeeded", - "semiColons": "asi" + "semiColons": "asi", }, "excludes": [".sqlx", "src/graphql/generated.rs", "target"], "plugins": [ @@ -26,6 +26,6 @@ "https://plugins.dprint.dev/json-0.19.3.wasm", "https://plugins.dprint.dev/markdown-0.17.8.wasm", "https://plugins.dprint.dev/toml-0.6.3.wasm", - "https://plugins.dprint.dev/typescript-0.93.0.wasm" - ] + // "https://plugins.dprint.dev/typescript-0.93.0.wasm" + ], } From 15c539e10f1f7b7f53476ffc74d061a90c4e0177 Mon Sep 17 00:00:00 2001 From: Harry Solovay Date: Fri, 18 Oct 2024 11:00:28 -0400 Subject: [PATCH 13/21] more --- .vscode/settings.json | 3 --- dprint.jsonc => dprint.json | 15 +++++++-------- 2 files changed, 7 insertions(+), 11 deletions(-) rename dprint.jsonc => dprint.json (77%) diff --git a/.vscode/settings.json b/.vscode/settings.json index 7b92131..f7f84cb 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -23,9 +23,6 @@ "[toml]": { "editor.defaultFormatter": "dprint.dprint" }, - "[typescript]": { - "editor.defaultFormatter": "dprint.dprint" - }, "[yaml]": { "editor.defaultFormatter": "dprint.dprint" }, diff --git a/dprint.jsonc b/dprint.json similarity index 77% rename from dprint.jsonc rename to dprint.json index c1e7ade..467d37f 100644 --- a/dprint.jsonc +++ b/dprint.json @@ -6,17 +6,17 @@ "commands": [ { "command": "sql-formatter -c sql_fmt.json -l postgresql", - "exts": ["sql"], - }, - ], + "exts": ["sql"] + } + ] }, "markdown": { - "textWrap": "always", + "textWrap": "always" }, "typescript": { "arrowFunction.useParentheses": "force", "quoteProps": "asNeeded", - "semiColons": "asi", + "semiColons": "asi" }, "excludes": [".sqlx", "src/graphql/generated.rs", "target"], "plugins": [ @@ -25,7 +25,6 @@ "https://plugins.dprint.dev/g-plane/pretty_yaml-v0.5.0.wasm", "https://plugins.dprint.dev/json-0.19.3.wasm", "https://plugins.dprint.dev/markdown-0.17.8.wasm", - "https://plugins.dprint.dev/toml-0.6.3.wasm", - // "https://plugins.dprint.dev/typescript-0.93.0.wasm" - ], + "https://plugins.dprint.dev/toml-0.6.3.wasm" + ] } From e780ce13297f18af4a5ea6ee1f811b9d4d0f4a0c Mon Sep 17 00:00:00 2001 From: Harry Solovay Date: Fri, 18 Oct 2024 11:02:07 -0400 Subject: [PATCH 14/21] more --- .vscode/settings.json | 3 +++ dprint.json => dprint.jsonc | 23 ++++++++++++----------- 2 files changed, 15 insertions(+), 11 deletions(-) rename dprint.json => dprint.jsonc (65%) diff --git a/.vscode/settings.json b/.vscode/settings.json index f7f84cb..e16227c 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -23,6 +23,9 @@ "[toml]": { "editor.defaultFormatter": "dprint.dprint" }, + // "[typescript]": { + // "editor.defaultFormatter": "dprint.dprint" + // }, "[yaml]": { "editor.defaultFormatter": "dprint.dprint" }, diff --git a/dprint.json b/dprint.jsonc similarity index 65% rename from dprint.json rename to dprint.jsonc index 467d37f..101c1ec 100644 --- a/dprint.json +++ b/dprint.jsonc @@ -6,18 +6,18 @@ "commands": [ { "command": "sql-formatter -c sql_fmt.json -l postgresql", - "exts": ["sql"] - } - ] + "exts": ["sql"], + }, + ], }, "markdown": { - "textWrap": "always" - }, - "typescript": { - "arrowFunction.useParentheses": "force", - "quoteProps": "asNeeded", - "semiColons": "asi" + "textWrap": "always", }, + // "typescript": { + // "arrowFunction.useParentheses": "force", + // "quoteProps": "asNeeded", + // "semiColons": "asi", + // }, "excludes": [".sqlx", "src/graphql/generated.rs", "target"], "plugins": [ "https://plugins.dprint.dev/dockerfile-0.3.2.wasm", @@ -25,6 +25,7 @@ "https://plugins.dprint.dev/g-plane/pretty_yaml-v0.5.0.wasm", "https://plugins.dprint.dev/json-0.19.3.wasm", "https://plugins.dprint.dev/markdown-0.17.8.wasm", - "https://plugins.dprint.dev/toml-0.6.3.wasm" - ] + "https://plugins.dprint.dev/toml-0.6.3.wasm", + // "https://plugins.dprint.dev/typescript-0.93.0.wasm" + ], } From 2b39e567c6df8fbea24a3f46326da53fc31ce119 Mon Sep 17 00:00:00 2001 From: Harry Solovay Date: Fri, 18 Oct 2024 11:07:29 -0400 Subject: [PATCH 15/21] pretty assertions --- Cargo.lock | 17 +++++++++++++++++ Cargo.toml | 1 + tests/block.rs | 1 + 3 files changed, 19 insertions(+) diff --git a/Cargo.lock b/Cargo.lock index dca5c3c..408c6de 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -768,6 +768,12 @@ dependencies = [ "unicode-xid", ] +[[package]] +name = "diff" +version = "0.1.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56254986775e3233ffa9c4d7d3faaf6d36a2c09d30b20687e9f88bc8bafc16c8" + [[package]] name = "digest" version = "0.10.7" @@ -1553,6 +1559,7 @@ dependencies = [ "indoc", "insta", "paste", + "pretty_assertions", "reqwest", "serde", "serde_json", @@ -1894,6 +1901,16 @@ dependencies = [ "zerocopy", ] +[[package]] +name = "pretty_assertions" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ae130e2f271fbc2ac3a40fb1d07180839cdbbe443c7a27e1e3c13c5cac0116d" +dependencies = [ + "diff", + "yansi", +] + [[package]] name = "proc-macro-crate" version = "3.1.0" diff --git a/Cargo.toml b/Cargo.toml index eab4ae2..cc18fd3 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -26,6 +26,7 @@ dotenv = "0.15.0" envy = "0.4.2" futures = "0.3.30" paste = "1.0.15" +pretty_assertions = "1.4.1" reqwest = { version = "0.12.5", features = ["json", "blocking"] } serde = { version = "1.0.204", features = ["derive"] } serde_json = { version = "1.0.121" } diff --git a/tests/block.rs b/tests/block.rs index a64737f..1b8e39e 100644 --- a/tests/block.rs +++ b/tests/block.rs @@ -7,6 +7,7 @@ use mina_mesh::{ models::{BlockRequest, BlockResponse, NetworkIdentifier, PartialBlockIdentifier}, MinaMeshConfig, MinaMeshError, }; +use pretty_assertions::assert_eq; #[tokio::test] async fn specified() -> Result<()> { From 26ae980deec5d67dedfb8e519e332b38faf50c66 Mon Sep 17 00:00:00 2001 From: Harry Solovay Date: Mon, 21 Oct 2024 18:38:40 -0400 Subject: [PATCH 16/21] use btree --- src/sql_to_mesh.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sql_to_mesh.rs b/src/sql_to_mesh.rs index 39c0144..38c412f 100644 --- a/src/sql_to_mesh.rs +++ b/src/sql_to_mesh.rs @@ -1,4 +1,4 @@ -use std::collections::HashMap; +use std::collections::BTreeMap; use coinbase_mesh::models::{AccountIdentifier, Operation, Transaction, TransactionIdentifier}; use serde_json::json; @@ -6,7 +6,7 @@ use serde_json::json; use crate::{operation, util::DEFAULT_TOKEN_ID, OperationType, TransactionStatus, ZkAppCommand}; pub fn zkapp_commands_to_transactions(commands: Vec) -> Vec { - let mut tx_map: HashMap> = HashMap::new(); + let mut tx_map = BTreeMap::>::new(); for command in commands { let tx_hash = command.hash.clone(); From 471463f0f6b872d4d53ddbd2496a6fa32d17ddc8 Mon Sep 17 00:00:00 2001 From: Piotr Stachyra Date: Tue, 22 Oct 2024 07:55:51 +0200 Subject: [PATCH 17/21] update test snapshot --- tests/snapshots/block__specified.snap | 1764 ++++++++++++++++++++++--- 1 file changed, 1617 insertions(+), 147 deletions(-) diff --git a/tests/snapshots/block__specified.snap b/tests/snapshots/block__specified.snap index 9e4ed08..bb11316 100644 --- a/tests/snapshots/block__specified.snap +++ b/tests/snapshots/block__specified.snap @@ -558,15 +558,227 @@ Some( transaction_identifier: TransactionIdentifier { hash: "5JtpLNQBmjphWGnyntyqsF8DVX8TUxaYCdzHR4D3ZQGzAx2oJ1Ax", }, - operations: [], + operations: [ + Operation { + operation_identifier: OperationIdentifier { + index: 0, + network_index: None, + }, + related_operations: None, + type: "zkapp_fee_payer_dec", + status: Some( + "Success", + ), + account: Some( + AccountIdentifier { + address: "B62qrT8ycgyUiAEXA6chy2NaMthRhchbGueX3FrrdbnekjwUN4Bqq5C", + sub_account: None, + metadata: Some( + Object { + "token_id": String("wSHV2S4qX9jFsLjQo8r1BsMLH2ZRKsZx6EJd1sbozGPieEC4Jf"), + }, + ), + }, + ), + amount: Some( + Amount { + value: "-200000000", + currency: Currency { + symbol: "MINA", + decimals: 9, + metadata: None, + }, + metadata: None, + }, + ), + coin_change: None, + metadata: None, + }, + Operation { + operation_identifier: OperationIdentifier { + index: 1, + network_index: None, + }, + related_operations: None, + type: "zkapp_balance_update", + status: Some( + "Success", + ), + account: Some( + AccountIdentifier { + address: "B62qrT8ycgyUiAEXA6chy2NaMthRhchbGueX3FrrdbnekjwUN4Bqq5C", + sub_account: None, + metadata: Some( + Object { + "token_id": String("wSHV2S4qX9jFsLjQo8r1BsMLH2ZRKsZx6EJd1sbozGPieEC4Jf"), + }, + ), + }, + ), + amount: Some( + Amount { + value: "-298800000000", + currency: Currency { + symbol: "MINA", + decimals: 9, + metadata: None, + }, + metadata: None, + }, + ), + coin_change: None, + metadata: None, + }, + Operation { + operation_identifier: OperationIdentifier { + index: 2, + network_index: None, + }, + related_operations: None, + type: "zkapp_balance_update", + status: Some( + "Success", + ), + account: Some( + AccountIdentifier { + address: "B62qj78UaPdrHwUBTJwFc3tz8GzTLBgijU6MadCdFkY58Lg9gMpPRK8", + sub_account: None, + metadata: Some( + Object { + "token_id": String("wSHV2S4qX9jFsLjQo8r1BsMLH2ZRKsZx6EJd1sbozGPieEC4Jf"), + }, + ), + }, + ), + amount: Some( + Amount { + value: "298800000000", + currency: Currency { + symbol: "MINA", + decimals: 9, + metadata: None, + }, + metadata: None, + }, + ), + coin_change: None, + metadata: None, + }, + ], related_transactions: None, metadata: None, }, Transaction { transaction_identifier: TransactionIdentifier { - hash: "5JtpLNQBmjphWGnyntyqsF8DVX8TUxaYCdzHR4D3ZQGzAx2oJ1Ax", + hash: "5Ju64BwGA8tYN9F9NMcNKkNUtiAdbdvWWdsriDXCtS28kjwXJJwk", }, - operations: [], + operations: [ + Operation { + operation_identifier: OperationIdentifier { + index: 0, + network_index: None, + }, + related_operations: None, + type: "zkapp_fee_payer_dec", + status: Some( + "Success", + ), + account: Some( + AccountIdentifier { + address: "B62qpfgnUm7zVqi8MJHNB2m37rtgMNDbFNhC2DpMmmVpQt8x6gKv9Ww", + sub_account: None, + metadata: Some( + Object { + "token_id": String("wSHV2S4qX9jFsLjQo8r1BsMLH2ZRKsZx6EJd1sbozGPieEC4Jf"), + }, + ), + }, + ), + amount: Some( + Amount { + value: "-100000000", + currency: Currency { + symbol: "MINA", + decimals: 9, + metadata: None, + }, + metadata: None, + }, + ), + coin_change: None, + metadata: None, + }, + Operation { + operation_identifier: OperationIdentifier { + index: 1, + network_index: None, + }, + related_operations: None, + type: "zkapp_balance_update", + status: Some( + "Success", + ), + account: Some( + AccountIdentifier { + address: "B62qpfgnUm7zVqi8MJHNB2m37rtgMNDbFNhC2DpMmmVpQt8x6gKv9Ww", + sub_account: None, + metadata: Some( + Object { + "token_id": String("wSHV2S4qX9jFsLjQo8r1BsMLH2ZRKsZx6EJd1sbozGPieEC4Jf"), + }, + ), + }, + ), + amount: Some( + Amount { + value: "-2000000000", + currency: Currency { + symbol: "MINA", + decimals: 9, + metadata: None, + }, + metadata: None, + }, + ), + coin_change: None, + metadata: None, + }, + Operation { + operation_identifier: OperationIdentifier { + index: 2, + network_index: None, + }, + related_operations: None, + type: "zkapp_balance_update", + status: Some( + "Success", + ), + account: Some( + AccountIdentifier { + address: "B62qpYCQrD9qxKcQF2Ja2bPTtfJ2Zj3SsVsgaivT515NknHsimg63CX", + sub_account: None, + metadata: Some( + Object { + "token_id": String("wSHV2S4qX9jFsLjQo8r1BsMLH2ZRKsZx6EJd1sbozGPieEC4Jf"), + }, + ), + }, + ), + amount: Some( + Amount { + value: "2000000000", + currency: Currency { + symbol: "MINA", + decimals: 9, + metadata: None, + }, + metadata: None, + }, + ), + coin_change: None, + metadata: None, + }, + ], related_transactions: None, metadata: None, }, @@ -574,39 +786,227 @@ Some( transaction_identifier: TransactionIdentifier { hash: "5Ju6Z6aAiKvxNc5Tou87cedCj4tsdv83GzHtu1Jc2FrfwoMqZAwN", }, - operations: [], + operations: [ + Operation { + operation_identifier: OperationIdentifier { + index: 0, + network_index: None, + }, + related_operations: None, + type: "zkapp_fee_payer_dec", + status: Some( + "Success", + ), + account: Some( + AccountIdentifier { + address: "B62qioSuSzmajyqQK9uXHEfUtQ89aqe7BxGSmaUP6kCCkvSDC4LtuKA", + sub_account: None, + metadata: Some( + Object { + "token_id": String("wSHV2S4qX9jFsLjQo8r1BsMLH2ZRKsZx6EJd1sbozGPieEC4Jf"), + }, + ), + }, + ), + amount: Some( + Amount { + value: "-200000000", + currency: Currency { + symbol: "MINA", + decimals: 9, + metadata: None, + }, + metadata: None, + }, + ), + coin_change: None, + metadata: None, + }, + Operation { + operation_identifier: OperationIdentifier { + index: 1, + network_index: None, + }, + related_operations: None, + type: "zkapp_balance_update", + status: Some( + "Success", + ), + account: Some( + AccountIdentifier { + address: "B62qioSuSzmajyqQK9uXHEfUtQ89aqe7BxGSmaUP6kCCkvSDC4LtuKA", + sub_account: None, + metadata: Some( + Object { + "token_id": String("wSHV2S4qX9jFsLjQo8r1BsMLH2ZRKsZx6EJd1sbozGPieEC4Jf"), + }, + ), + }, + ), + amount: Some( + Amount { + value: "-298800000000", + currency: Currency { + symbol: "MINA", + decimals: 9, + metadata: None, + }, + metadata: None, + }, + ), + coin_change: None, + metadata: None, + }, + Operation { + operation_identifier: OperationIdentifier { + index: 2, + network_index: None, + }, + related_operations: None, + type: "zkapp_balance_update", + status: Some( + "Success", + ), + account: Some( + AccountIdentifier { + address: "B62qpbH52xLKoDASdm37v6V7fLrM4oyaQG3M3tibsPm1aQLagAfAS9r", + sub_account: None, + metadata: Some( + Object { + "token_id": String("wSHV2S4qX9jFsLjQo8r1BsMLH2ZRKsZx6EJd1sbozGPieEC4Jf"), + }, + ), + }, + ), + amount: Some( + Amount { + value: "298800000000", + currency: Currency { + symbol: "MINA", + decimals: 9, + metadata: None, + }, + metadata: None, + }, + ), + coin_change: None, + metadata: None, + }, + ], related_transactions: None, metadata: None, }, Transaction { transaction_identifier: TransactionIdentifier { - hash: "5Ju6Z6aAiKvxNc5Tou87cedCj4tsdv83GzHtu1Jc2FrfwoMqZAwN", + hash: "5JuJsuLr6BpWyVQh436qUq4VBnChLDawS8VAX29w8CpZiVSF6VzE", }, - operations: [], - related_transactions: None, - metadata: None, - }, - Transaction { - transaction_identifier: TransactionIdentifier { - hash: "5JuJsuLr6BpWyVQh436qUq4VBnChLDawS8VAX29w8CpZiVSF6VzE", - }, - operations: [], - related_transactions: None, - metadata: None, - }, - Transaction { - transaction_identifier: TransactionIdentifier { - hash: "5JuJsuLr6BpWyVQh436qUq4VBnChLDawS8VAX29w8CpZiVSF6VzE", - }, - operations: [], - related_transactions: None, - metadata: None, - }, - Transaction { - transaction_identifier: TransactionIdentifier { - hash: "5JuVUZairQhcerYaTFT2oDyY2vaXYnKaXAxAQ24SGp1oEP4XqPFX", - }, - operations: [], + operations: [ + Operation { + operation_identifier: OperationIdentifier { + index: 0, + network_index: None, + }, + related_operations: None, + type: "zkapp_fee_payer_dec", + status: Some( + "Success", + ), + account: Some( + AccountIdentifier { + address: "B62qinuoio4g2CsE6t9YMZZ1r36PttDFDVjs6heZie7Yu1foSBrTbdP", + sub_account: None, + metadata: Some( + Object { + "token_id": String("wSHV2S4qX9jFsLjQo8r1BsMLH2ZRKsZx6EJd1sbozGPieEC4Jf"), + }, + ), + }, + ), + amount: Some( + Amount { + value: "-200000000", + currency: Currency { + symbol: "MINA", + decimals: 9, + metadata: None, + }, + metadata: None, + }, + ), + coin_change: None, + metadata: None, + }, + Operation { + operation_identifier: OperationIdentifier { + index: 1, + network_index: None, + }, + related_operations: None, + type: "zkapp_balance_update", + status: Some( + "Success", + ), + account: Some( + AccountIdentifier { + address: "B62qinuoio4g2CsE6t9YMZZ1r36PttDFDVjs6heZie7Yu1foSBrTbdP", + sub_account: None, + metadata: Some( + Object { + "token_id": String("wSHV2S4qX9jFsLjQo8r1BsMLH2ZRKsZx6EJd1sbozGPieEC4Jf"), + }, + ), + }, + ), + amount: Some( + Amount { + value: "-298800000000", + currency: Currency { + symbol: "MINA", + decimals: 9, + metadata: None, + }, + metadata: None, + }, + ), + coin_change: None, + metadata: None, + }, + Operation { + operation_identifier: OperationIdentifier { + index: 2, + network_index: None, + }, + related_operations: None, + type: "zkapp_balance_update", + status: Some( + "Success", + ), + account: Some( + AccountIdentifier { + address: "B62qjR4EMKydFpQFzN9uGWHpir8nMXS75dDRkFfDeWpLpZhTecnZCHq", + sub_account: None, + metadata: Some( + Object { + "token_id": String("wSHV2S4qX9jFsLjQo8r1BsMLH2ZRKsZx6EJd1sbozGPieEC4Jf"), + }, + ), + }, + ), + amount: Some( + Amount { + value: "298800000000", + currency: Currency { + symbol: "MINA", + decimals: 9, + metadata: None, + }, + metadata: None, + }, + ), + coin_change: None, + metadata: None, + }, + ], related_transactions: None, metadata: None, }, @@ -614,183 +1014,1253 @@ Some( transaction_identifier: TransactionIdentifier { hash: "5JuVUZairQhcerYaTFT2oDyY2vaXYnKaXAxAQ24SGp1oEP4XqPFX", }, - operations: [], - related_transactions: None, - metadata: None, - }, - Transaction { - transaction_identifier: TransactionIdentifier { - hash: "5JuvrqLZ3EwXGPqyHUdP1R7rv3yknzihAGaGgWdMh9iUuTyekLWh", - }, - operations: [], - related_transactions: None, - metadata: None, - }, - Transaction { - transaction_identifier: TransactionIdentifier { - hash: "5JuvrqLZ3EwXGPqyHUdP1R7rv3yknzihAGaGgWdMh9iUuTyekLWh", - }, - operations: [], - related_transactions: None, - metadata: None, - }, - Transaction { - transaction_identifier: TransactionIdentifier { - hash: "5Juy3zMDwCBAsaR1rVRFyydkD1WyGt7xPbB3kYSXmAizcsGRE7vJ", - }, - operations: [], - related_transactions: None, - metadata: None, - }, - Transaction { - transaction_identifier: TransactionIdentifier { - hash: "5Juy3zMDwCBAsaR1rVRFyydkD1WyGt7xPbB3kYSXmAizcsGRE7vJ", - }, - operations: [], - related_transactions: None, - metadata: None, - }, - Transaction { - transaction_identifier: TransactionIdentifier { - hash: "5Jv3nsCJYRbw2m7rUmN4tqrf4w35o9Xe38MM1PX7UV7marJuCfoD", - }, - operations: [], - related_transactions: None, - metadata: None, - }, - Transaction { - transaction_identifier: TransactionIdentifier { - hash: "5Jv3nsCJYRbw2m7rUmN4tqrf4w35o9Xe38MM1PX7UV7marJuCfoD", - }, - operations: [], - related_transactions: None, - metadata: None, - }, - Transaction { - transaction_identifier: TransactionIdentifier { - hash: "5Jv43b5zzb8ZJD36K8Qj1n2W56hABvCDHVbjBTnrRa5XSAfYoNJJ", - }, - operations: [], - related_transactions: None, - metadata: None, - }, - Transaction { - transaction_identifier: TransactionIdentifier { - hash: "5Jv43b5zzb8ZJD36K8Qj1n2W56hABvCDHVbjBTnrRa5XSAfYoNJJ", - }, - operations: [], - related_transactions: None, - metadata: None, - }, - Transaction { - transaction_identifier: TransactionIdentifier { - hash: "5JvAJNhQLnqEjkWdVEAoKWhS72ZPZGTBP1wecQNZe2mkwBq5uY67", - }, - operations: [], - related_transactions: None, - metadata: None, - }, - Transaction { - transaction_identifier: TransactionIdentifier { - hash: "5JvAJNhQLnqEjkWdVEAoKWhS72ZPZGTBP1wecQNZe2mkwBq5uY67", - }, - operations: [], - related_transactions: None, - metadata: None, - }, - Transaction { - transaction_identifier: TransactionIdentifier { - hash: "5JvFr3amqo38C5UTScdTrWX2Uh9zEBJMfJ46VkPEBikcy1BzK2uq", - }, - operations: [], - related_transactions: None, - metadata: None, - }, - Transaction { - transaction_identifier: TransactionIdentifier { - hash: "5JvFr3amqo38C5UTScdTrWX2Uh9zEBJMfJ46VkPEBikcy1BzK2uq", - }, - operations: [], + operations: [ + Operation { + operation_identifier: OperationIdentifier { + index: 0, + network_index: None, + }, + related_operations: None, + type: "zkapp_fee_payer_dec", + status: Some( + "Success", + ), + account: Some( + AccountIdentifier { + address: "B62qmgdWmgLod7Hr1WAUMLts9vKJ54m9CeWWmgucYTKJHc8Mqt3Wc3k", + sub_account: None, + metadata: Some( + Object { + "token_id": String("wSHV2S4qX9jFsLjQo8r1BsMLH2ZRKsZx6EJd1sbozGPieEC4Jf"), + }, + ), + }, + ), + amount: Some( + Amount { + value: "-200000000", + currency: Currency { + symbol: "MINA", + decimals: 9, + metadata: None, + }, + metadata: None, + }, + ), + coin_change: None, + metadata: None, + }, + Operation { + operation_identifier: OperationIdentifier { + index: 1, + network_index: None, + }, + related_operations: None, + type: "zkapp_balance_update", + status: Some( + "Success", + ), + account: Some( + AccountIdentifier { + address: "B62qmgdWmgLod7Hr1WAUMLts9vKJ54m9CeWWmgucYTKJHc8Mqt3Wc3k", + sub_account: None, + metadata: Some( + Object { + "token_id": String("wSHV2S4qX9jFsLjQo8r1BsMLH2ZRKsZx6EJd1sbozGPieEC4Jf"), + }, + ), + }, + ), + amount: Some( + Amount { + value: "-298800000000", + currency: Currency { + symbol: "MINA", + decimals: 9, + metadata: None, + }, + metadata: None, + }, + ), + coin_change: None, + metadata: None, + }, + Operation { + operation_identifier: OperationIdentifier { + index: 2, + network_index: None, + }, + related_operations: None, + type: "zkapp_balance_update", + status: Some( + "Success", + ), + account: Some( + AccountIdentifier { + address: "B62qp6GUuQF1V1gftAX77McarE8fyEfQscJDHj77DALNS2b681z6GYL", + sub_account: None, + metadata: Some( + Object { + "token_id": String("wSHV2S4qX9jFsLjQo8r1BsMLH2ZRKsZx6EJd1sbozGPieEC4Jf"), + }, + ), + }, + ), + amount: Some( + Amount { + value: "298800000000", + currency: Currency { + symbol: "MINA", + decimals: 9, + metadata: None, + }, + metadata: None, + }, + ), + coin_change: None, + metadata: None, + }, + ], related_transactions: None, metadata: None, }, Transaction { transaction_identifier: TransactionIdentifier { - hash: "5JvHyQmPVJUyF4puURRu92hJLVmNy6qpLjjKa6bbHcLeuao6WZ4u", + hash: "5JufsTkU6MYo2QsQh4WiU8F3ssM7TQtx3bdjncLuvxGCPSLZ5mTe", }, - operations: [], + operations: [ + Operation { + operation_identifier: OperationIdentifier { + index: 0, + network_index: None, + }, + related_operations: None, + type: "zkapp_fee_payer_dec", + status: Some( + "Success", + ), + account: Some( + AccountIdentifier { + address: "B62qpfgnUm7zVqi8MJHNB2m37rtgMNDbFNhC2DpMmmVpQt8x6gKv9Ww", + sub_account: None, + metadata: Some( + Object { + "token_id": String("wSHV2S4qX9jFsLjQo8r1BsMLH2ZRKsZx6EJd1sbozGPieEC4Jf"), + }, + ), + }, + ), + amount: Some( + Amount { + value: "-100000000", + currency: Currency { + symbol: "MINA", + decimals: 9, + metadata: None, + }, + metadata: None, + }, + ), + coin_change: None, + metadata: None, + }, + Operation { + operation_identifier: OperationIdentifier { + index: 1, + network_index: None, + }, + related_operations: None, + type: "zkapp_balance_update", + status: Some( + "Success", + ), + account: Some( + AccountIdentifier { + address: "B62qpfgnUm7zVqi8MJHNB2m37rtgMNDbFNhC2DpMmmVpQt8x6gKv9Ww", + sub_account: None, + metadata: Some( + Object { + "token_id": String("wSHV2S4qX9jFsLjQo8r1BsMLH2ZRKsZx6EJd1sbozGPieEC4Jf"), + }, + ), + }, + ), + amount: Some( + Amount { + value: "-2000000000", + currency: Currency { + symbol: "MINA", + decimals: 9, + metadata: None, + }, + metadata: None, + }, + ), + coin_change: None, + metadata: None, + }, + Operation { + operation_identifier: OperationIdentifier { + index: 2, + network_index: None, + }, + related_operations: None, + type: "zkapp_balance_update", + status: Some( + "Success", + ), + account: Some( + AccountIdentifier { + address: "B62qpYCQrD9qxKcQF2Ja2bPTtfJ2Zj3SsVsgaivT515NknHsimg63CX", + sub_account: None, + metadata: Some( + Object { + "token_id": String("wSHV2S4qX9jFsLjQo8r1BsMLH2ZRKsZx6EJd1sbozGPieEC4Jf"), + }, + ), + }, + ), + amount: Some( + Amount { + value: "2000000000", + currency: Currency { + symbol: "MINA", + decimals: 9, + metadata: None, + }, + metadata: None, + }, + ), + coin_change: None, + metadata: None, + }, + ], related_transactions: None, metadata: None, }, Transaction { transaction_identifier: TransactionIdentifier { - hash: "5JvHyQmPVJUyF4puURRu92hJLVmNy6qpLjjKa6bbHcLeuao6WZ4u", + hash: "5JuoQgsBxJSrwaRNBnDL8eiz5EbT5kEehepDL5KTamKc2i5v1kaB", }, - operations: [], + operations: [ + Operation { + operation_identifier: OperationIdentifier { + index: 0, + network_index: None, + }, + related_operations: None, + type: "zkapp_fee_payer_dec", + status: Some( + "Success", + ), + account: Some( + AccountIdentifier { + address: "B62qpfgnUm7zVqi8MJHNB2m37rtgMNDbFNhC2DpMmmVpQt8x6gKv9Ww", + sub_account: None, + metadata: Some( + Object { + "token_id": String("wSHV2S4qX9jFsLjQo8r1BsMLH2ZRKsZx6EJd1sbozGPieEC4Jf"), + }, + ), + }, + ), + amount: Some( + Amount { + value: "-100000000", + currency: Currency { + symbol: "MINA", + decimals: 9, + metadata: None, + }, + metadata: None, + }, + ), + coin_change: None, + metadata: None, + }, + Operation { + operation_identifier: OperationIdentifier { + index: 1, + network_index: None, + }, + related_operations: None, + type: "zkapp_balance_update", + status: Some( + "Success", + ), + account: Some( + AccountIdentifier { + address: "B62qpfgnUm7zVqi8MJHNB2m37rtgMNDbFNhC2DpMmmVpQt8x6gKv9Ww", + sub_account: None, + metadata: Some( + Object { + "token_id": String("wSHV2S4qX9jFsLjQo8r1BsMLH2ZRKsZx6EJd1sbozGPieEC4Jf"), + }, + ), + }, + ), + amount: Some( + Amount { + value: "-2000000000", + currency: Currency { + symbol: "MINA", + decimals: 9, + metadata: None, + }, + metadata: None, + }, + ), + coin_change: None, + metadata: None, + }, + Operation { + operation_identifier: OperationIdentifier { + index: 2, + network_index: None, + }, + related_operations: None, + type: "zkapp_balance_update", + status: Some( + "Success", + ), + account: Some( + AccountIdentifier { + address: "B62qrsaLKgMey9Y6aZjdL5FVFa1dkYC4u4qr69Mw1vp54QRt5KVk98o", + sub_account: None, + metadata: Some( + Object { + "token_id": String("wSHV2S4qX9jFsLjQo8r1BsMLH2ZRKsZx6EJd1sbozGPieEC4Jf"), + }, + ), + }, + ), + amount: Some( + Amount { + value: "2000000000", + currency: Currency { + symbol: "MINA", + decimals: 9, + metadata: None, + }, + metadata: None, + }, + ), + coin_change: None, + metadata: None, + }, + ], related_transactions: None, metadata: None, }, Transaction { transaction_identifier: TransactionIdentifier { - hash: "5JvPGvbjz6Kdf9Uiif7RSDFbJRnCfN4mrwK4YuJjQWBUyZKvG6KA", + hash: "5JuvrqLZ3EwXGPqyHUdP1R7rv3yknzihAGaGgWdMh9iUuTyekLWh", }, - operations: [], + operations: [ + Operation { + operation_identifier: OperationIdentifier { + index: 0, + network_index: None, + }, + related_operations: None, + type: "zkapp_fee_payer_dec", + status: Some( + "Success", + ), + account: Some( + AccountIdentifier { + address: "B62qiU1dVcW2Yw4F4ik82Wjy8W32a8gP3GYzTW6HJEdb2UCmhim8kDu", + sub_account: None, + metadata: Some( + Object { + "token_id": String("wSHV2S4qX9jFsLjQo8r1BsMLH2ZRKsZx6EJd1sbozGPieEC4Jf"), + }, + ), + }, + ), + amount: Some( + Amount { + value: "-200000000", + currency: Currency { + symbol: "MINA", + decimals: 9, + metadata: None, + }, + metadata: None, + }, + ), + coin_change: None, + metadata: None, + }, + Operation { + operation_identifier: OperationIdentifier { + index: 1, + network_index: None, + }, + related_operations: None, + type: "zkapp_balance_update", + status: Some( + "Success", + ), + account: Some( + AccountIdentifier { + address: "B62qiU1dVcW2Yw4F4ik82Wjy8W32a8gP3GYzTW6HJEdb2UCmhim8kDu", + sub_account: None, + metadata: Some( + Object { + "token_id": String("wSHV2S4qX9jFsLjQo8r1BsMLH2ZRKsZx6EJd1sbozGPieEC4Jf"), + }, + ), + }, + ), + amount: Some( + Amount { + value: "-298800000000", + currency: Currency { + symbol: "MINA", + decimals: 9, + metadata: None, + }, + metadata: None, + }, + ), + coin_change: None, + metadata: None, + }, + Operation { + operation_identifier: OperationIdentifier { + index: 2, + network_index: None, + }, + related_operations: None, + type: "zkapp_balance_update", + status: Some( + "Success", + ), + account: Some( + AccountIdentifier { + address: "B62qphnorEVHZffvCb7BwaP4o6HfumksHyKpf5on9VqbJVPkSBw3ruw", + sub_account: None, + metadata: Some( + Object { + "token_id": String("wSHV2S4qX9jFsLjQo8r1BsMLH2ZRKsZx6EJd1sbozGPieEC4Jf"), + }, + ), + }, + ), + amount: Some( + Amount { + value: "298800000000", + currency: Currency { + symbol: "MINA", + decimals: 9, + metadata: None, + }, + metadata: None, + }, + ), + coin_change: None, + metadata: None, + }, + ], related_transactions: None, metadata: None, }, Transaction { transaction_identifier: TransactionIdentifier { - hash: "5JvPGvbjz6Kdf9Uiif7RSDFbJRnCfN4mrwK4YuJjQWBUyZKvG6KA", + hash: "5Juy3zMDwCBAsaR1rVRFyydkD1WyGt7xPbB3kYSXmAizcsGRE7vJ", }, - operations: [], + operations: [ + Operation { + operation_identifier: OperationIdentifier { + index: 0, + network_index: None, + }, + related_operations: None, + type: "zkapp_fee_payer_dec", + status: Some( + "Success", + ), + account: Some( + AccountIdentifier { + address: "B62qo5zQdnJkbjCn8Uu64ukbuSB24PgeaqZSPtErFKnugiT3gygcZop", + sub_account: None, + metadata: Some( + Object { + "token_id": String("wSHV2S4qX9jFsLjQo8r1BsMLH2ZRKsZx6EJd1sbozGPieEC4Jf"), + }, + ), + }, + ), + amount: Some( + Amount { + value: "-200000000", + currency: Currency { + symbol: "MINA", + decimals: 9, + metadata: None, + }, + metadata: None, + }, + ), + coin_change: None, + metadata: None, + }, + Operation { + operation_identifier: OperationIdentifier { + index: 1, + network_index: None, + }, + related_operations: None, + type: "zkapp_balance_update", + status: Some( + "Success", + ), + account: Some( + AccountIdentifier { + address: "B62qo5zQdnJkbjCn8Uu64ukbuSB24PgeaqZSPtErFKnugiT3gygcZop", + sub_account: None, + metadata: Some( + Object { + "token_id": String("wSHV2S4qX9jFsLjQo8r1BsMLH2ZRKsZx6EJd1sbozGPieEC4Jf"), + }, + ), + }, + ), + amount: Some( + Amount { + value: "-298800000000", + currency: Currency { + symbol: "MINA", + decimals: 9, + metadata: None, + }, + metadata: None, + }, + ), + coin_change: None, + metadata: None, + }, + Operation { + operation_identifier: OperationIdentifier { + index: 2, + network_index: None, + }, + related_operations: None, + type: "zkapp_balance_update", + status: Some( + "Success", + ), + account: Some( + AccountIdentifier { + address: "B62qma6ZCiVp6w4fpMJ5XNKkN9viMvup3HdvxQ1sSfPWuinujVByMzP", + sub_account: None, + metadata: Some( + Object { + "token_id": String("wSHV2S4qX9jFsLjQo8r1BsMLH2ZRKsZx6EJd1sbozGPieEC4Jf"), + }, + ), + }, + ), + amount: Some( + Amount { + value: "298800000000", + currency: Currency { + symbol: "MINA", + decimals: 9, + metadata: None, + }, + metadata: None, + }, + ), + coin_change: None, + metadata: None, + }, + ], related_transactions: None, metadata: None, }, Transaction { transaction_identifier: TransactionIdentifier { - hash: "5JufsTkU6MYo2QsQh4WiU8F3ssM7TQtx3bdjncLuvxGCPSLZ5mTe", + hash: "5Jv3nsCJYRbw2m7rUmN4tqrf4w35o9Xe38MM1PX7UV7marJuCfoD", }, - operations: [], + operations: [ + Operation { + operation_identifier: OperationIdentifier { + index: 0, + network_index: None, + }, + related_operations: None, + type: "zkapp_fee_payer_dec", + status: Some( + "Success", + ), + account: Some( + AccountIdentifier { + address: "B62qoVjmoZuWykm6yVTJ7e9zA8q7kVvboK4Jyh4X7KcMjK3hDqYCxbK", + sub_account: None, + metadata: Some( + Object { + "token_id": String("wSHV2S4qX9jFsLjQo8r1BsMLH2ZRKsZx6EJd1sbozGPieEC4Jf"), + }, + ), + }, + ), + amount: Some( + Amount { + value: "-200000000", + currency: Currency { + symbol: "MINA", + decimals: 9, + metadata: None, + }, + metadata: None, + }, + ), + coin_change: None, + metadata: None, + }, + Operation { + operation_identifier: OperationIdentifier { + index: 1, + network_index: None, + }, + related_operations: None, + type: "zkapp_balance_update", + status: Some( + "Success", + ), + account: Some( + AccountIdentifier { + address: "B62qoVjmoZuWykm6yVTJ7e9zA8q7kVvboK4Jyh4X7KcMjK3hDqYCxbK", + sub_account: None, + metadata: Some( + Object { + "token_id": String("wSHV2S4qX9jFsLjQo8r1BsMLH2ZRKsZx6EJd1sbozGPieEC4Jf"), + }, + ), + }, + ), + amount: Some( + Amount { + value: "-298800000000", + currency: Currency { + symbol: "MINA", + decimals: 9, + metadata: None, + }, + metadata: None, + }, + ), + coin_change: None, + metadata: None, + }, + Operation { + operation_identifier: OperationIdentifier { + index: 2, + network_index: None, + }, + related_operations: None, + type: "zkapp_balance_update", + status: Some( + "Success", + ), + account: Some( + AccountIdentifier { + address: "B62qmLqa3gYiioRho7AaBUQhT1m1yCnaKF8S3sCSXPbJmG98puUHSmp", + sub_account: None, + metadata: Some( + Object { + "token_id": String("wSHV2S4qX9jFsLjQo8r1BsMLH2ZRKsZx6EJd1sbozGPieEC4Jf"), + }, + ), + }, + ), + amount: Some( + Amount { + value: "298800000000", + currency: Currency { + symbol: "MINA", + decimals: 9, + metadata: None, + }, + metadata: None, + }, + ), + coin_change: None, + metadata: None, + }, + ], related_transactions: None, metadata: None, }, Transaction { transaction_identifier: TransactionIdentifier { - hash: "5JufsTkU6MYo2QsQh4WiU8F3ssM7TQtx3bdjncLuvxGCPSLZ5mTe", + hash: "5Jv43b5zzb8ZJD36K8Qj1n2W56hABvCDHVbjBTnrRa5XSAfYoNJJ", }, - operations: [], + operations: [ + Operation { + operation_identifier: OperationIdentifier { + index: 0, + network_index: None, + }, + related_operations: None, + type: "zkapp_fee_payer_dec", + status: Some( + "Success", + ), + account: Some( + AccountIdentifier { + address: "B62qnihwg6W1XQhgKqhgkPdQCrvgUguvWE5vBmSAU2Y53nzgJjhk4Bs", + sub_account: None, + metadata: Some( + Object { + "token_id": String("wSHV2S4qX9jFsLjQo8r1BsMLH2ZRKsZx6EJd1sbozGPieEC4Jf"), + }, + ), + }, + ), + amount: Some( + Amount { + value: "-200000000", + currency: Currency { + symbol: "MINA", + decimals: 9, + metadata: None, + }, + metadata: None, + }, + ), + coin_change: None, + metadata: None, + }, + Operation { + operation_identifier: OperationIdentifier { + index: 1, + network_index: None, + }, + related_operations: None, + type: "zkapp_balance_update", + status: Some( + "Success", + ), + account: Some( + AccountIdentifier { + address: "B62qnihwg6W1XQhgKqhgkPdQCrvgUguvWE5vBmSAU2Y53nzgJjhk4Bs", + sub_account: None, + metadata: Some( + Object { + "token_id": String("wSHV2S4qX9jFsLjQo8r1BsMLH2ZRKsZx6EJd1sbozGPieEC4Jf"), + }, + ), + }, + ), + amount: Some( + Amount { + value: "-298800000000", + currency: Currency { + symbol: "MINA", + decimals: 9, + metadata: None, + }, + metadata: None, + }, + ), + coin_change: None, + metadata: None, + }, + Operation { + operation_identifier: OperationIdentifier { + index: 2, + network_index: None, + }, + related_operations: None, + type: "zkapp_balance_update", + status: Some( + "Success", + ), + account: Some( + AccountIdentifier { + address: "B62qkW4KGRBWn3tDU1PYWqXHbrdf7LWPN3FrZWztEYpGm6e8wUyBjp9", + sub_account: None, + metadata: Some( + Object { + "token_id": String("wSHV2S4qX9jFsLjQo8r1BsMLH2ZRKsZx6EJd1sbozGPieEC4Jf"), + }, + ), + }, + ), + amount: Some( + Amount { + value: "298800000000", + currency: Currency { + symbol: "MINA", + decimals: 9, + metadata: None, + }, + metadata: None, + }, + ), + coin_change: None, + metadata: None, + }, + ], related_transactions: None, metadata: None, }, Transaction { transaction_identifier: TransactionIdentifier { - hash: "5Ju64BwGA8tYN9F9NMcNKkNUtiAdbdvWWdsriDXCtS28kjwXJJwk", + hash: "5JvAJNhQLnqEjkWdVEAoKWhS72ZPZGTBP1wecQNZe2mkwBq5uY67", }, - operations: [], + operations: [ + Operation { + operation_identifier: OperationIdentifier { + index: 0, + network_index: None, + }, + related_operations: None, + type: "zkapp_fee_payer_dec", + status: Some( + "Success", + ), + account: Some( + AccountIdentifier { + address: "B62qnSNPFStU7kdA3gKiHCYouKkYmrzU5NFvu18hbTpUFmZzVjZp6he", + sub_account: None, + metadata: Some( + Object { + "token_id": String("wSHV2S4qX9jFsLjQo8r1BsMLH2ZRKsZx6EJd1sbozGPieEC4Jf"), + }, + ), + }, + ), + amount: Some( + Amount { + value: "-200000000", + currency: Currency { + symbol: "MINA", + decimals: 9, + metadata: None, + }, + metadata: None, + }, + ), + coin_change: None, + metadata: None, + }, + Operation { + operation_identifier: OperationIdentifier { + index: 1, + network_index: None, + }, + related_operations: None, + type: "zkapp_balance_update", + status: Some( + "Success", + ), + account: Some( + AccountIdentifier { + address: "B62qnSNPFStU7kdA3gKiHCYouKkYmrzU5NFvu18hbTpUFmZzVjZp6he", + sub_account: None, + metadata: Some( + Object { + "token_id": String("wSHV2S4qX9jFsLjQo8r1BsMLH2ZRKsZx6EJd1sbozGPieEC4Jf"), + }, + ), + }, + ), + amount: Some( + Amount { + value: "-298800000000", + currency: Currency { + symbol: "MINA", + decimals: 9, + metadata: None, + }, + metadata: None, + }, + ), + coin_change: None, + metadata: None, + }, + Operation { + operation_identifier: OperationIdentifier { + index: 2, + network_index: None, + }, + related_operations: None, + type: "zkapp_balance_update", + status: Some( + "Success", + ), + account: Some( + AccountIdentifier { + address: "B62qieq72y5Negna1XUQTBSX726LLJ5oAhsFUNZaWAqJJJdamGhGFhv", + sub_account: None, + metadata: Some( + Object { + "token_id": String("wSHV2S4qX9jFsLjQo8r1BsMLH2ZRKsZx6EJd1sbozGPieEC4Jf"), + }, + ), + }, + ), + amount: Some( + Amount { + value: "298800000000", + currency: Currency { + symbol: "MINA", + decimals: 9, + metadata: None, + }, + metadata: None, + }, + ), + coin_change: None, + metadata: None, + }, + ], related_transactions: None, metadata: None, }, Transaction { transaction_identifier: TransactionIdentifier { - hash: "5Ju64BwGA8tYN9F9NMcNKkNUtiAdbdvWWdsriDXCtS28kjwXJJwk", + hash: "5JvFr3amqo38C5UTScdTrWX2Uh9zEBJMfJ46VkPEBikcy1BzK2uq", }, - operations: [], + operations: [ + Operation { + operation_identifier: OperationIdentifier { + index: 0, + network_index: None, + }, + related_operations: None, + type: "zkapp_fee_payer_dec", + status: Some( + "Success", + ), + account: Some( + AccountIdentifier { + address: "B62qjCLySG219LysX9j6U8gpTfLS6JScd2nuMfWPtzQzFZQnemxb1MQ", + sub_account: None, + metadata: Some( + Object { + "token_id": String("wSHV2S4qX9jFsLjQo8r1BsMLH2ZRKsZx6EJd1sbozGPieEC4Jf"), + }, + ), + }, + ), + amount: Some( + Amount { + value: "-200000000", + currency: Currency { + symbol: "MINA", + decimals: 9, + metadata: None, + }, + metadata: None, + }, + ), + coin_change: None, + metadata: None, + }, + Operation { + operation_identifier: OperationIdentifier { + index: 1, + network_index: None, + }, + related_operations: None, + type: "zkapp_balance_update", + status: Some( + "Success", + ), + account: Some( + AccountIdentifier { + address: "B62qjCLySG219LysX9j6U8gpTfLS6JScd2nuMfWPtzQzFZQnemxb1MQ", + sub_account: None, + metadata: Some( + Object { + "token_id": String("wSHV2S4qX9jFsLjQo8r1BsMLH2ZRKsZx6EJd1sbozGPieEC4Jf"), + }, + ), + }, + ), + amount: Some( + Amount { + value: "-298800000000", + currency: Currency { + symbol: "MINA", + decimals: 9, + metadata: None, + }, + metadata: None, + }, + ), + coin_change: None, + metadata: None, + }, + Operation { + operation_identifier: OperationIdentifier { + index: 2, + network_index: None, + }, + related_operations: None, + type: "zkapp_balance_update", + status: Some( + "Success", + ), + account: Some( + AccountIdentifier { + address: "B62qqRKxgG1cA5hkVs8cYUDoHdsvpW1M8AMgSURwtNpNqXa21Cd9dpQ", + sub_account: None, + metadata: Some( + Object { + "token_id": String("wSHV2S4qX9jFsLjQo8r1BsMLH2ZRKsZx6EJd1sbozGPieEC4Jf"), + }, + ), + }, + ), + amount: Some( + Amount { + value: "298800000000", + currency: Currency { + symbol: "MINA", + decimals: 9, + metadata: None, + }, + metadata: None, + }, + ), + coin_change: None, + metadata: None, + }, + ], related_transactions: None, metadata: None, }, Transaction { transaction_identifier: TransactionIdentifier { - hash: "5JuoQgsBxJSrwaRNBnDL8eiz5EbT5kEehepDL5KTamKc2i5v1kaB", + hash: "5JvHyQmPVJUyF4puURRu92hJLVmNy6qpLjjKa6bbHcLeuao6WZ4u", }, - operations: [], + operations: [ + Operation { + operation_identifier: OperationIdentifier { + index: 0, + network_index: None, + }, + related_operations: None, + type: "zkapp_fee_payer_dec", + status: Some( + "Success", + ), + account: Some( + AccountIdentifier { + address: "B62qn8f9eE2ux3LoXvXrpiREF3X9nyHBXajGLeTPyJhq2MPnieV3tbg", + sub_account: None, + metadata: Some( + Object { + "token_id": String("wSHV2S4qX9jFsLjQo8r1BsMLH2ZRKsZx6EJd1sbozGPieEC4Jf"), + }, + ), + }, + ), + amount: Some( + Amount { + value: "-200000000", + currency: Currency { + symbol: "MINA", + decimals: 9, + metadata: None, + }, + metadata: None, + }, + ), + coin_change: None, + metadata: None, + }, + Operation { + operation_identifier: OperationIdentifier { + index: 1, + network_index: None, + }, + related_operations: None, + type: "zkapp_balance_update", + status: Some( + "Success", + ), + account: Some( + AccountIdentifier { + address: "B62qn8f9eE2ux3LoXvXrpiREF3X9nyHBXajGLeTPyJhq2MPnieV3tbg", + sub_account: None, + metadata: Some( + Object { + "token_id": String("wSHV2S4qX9jFsLjQo8r1BsMLH2ZRKsZx6EJd1sbozGPieEC4Jf"), + }, + ), + }, + ), + amount: Some( + Amount { + value: "-298800000000", + currency: Currency { + symbol: "MINA", + decimals: 9, + metadata: None, + }, + metadata: None, + }, + ), + coin_change: None, + metadata: None, + }, + Operation { + operation_identifier: OperationIdentifier { + index: 2, + network_index: None, + }, + related_operations: None, + type: "zkapp_balance_update", + status: Some( + "Success", + ), + account: Some( + AccountIdentifier { + address: "B62qp4LJX3bwWdxmVJE8csx6CkzjSEZRNQGUiV7S39mcRngsjtygXbg", + sub_account: None, + metadata: Some( + Object { + "token_id": String("wSHV2S4qX9jFsLjQo8r1BsMLH2ZRKsZx6EJd1sbozGPieEC4Jf"), + }, + ), + }, + ), + amount: Some( + Amount { + value: "298800000000", + currency: Currency { + symbol: "MINA", + decimals: 9, + metadata: None, + }, + metadata: None, + }, + ), + coin_change: None, + metadata: None, + }, + ], related_transactions: None, metadata: None, }, Transaction { transaction_identifier: TransactionIdentifier { - hash: "5JuoQgsBxJSrwaRNBnDL8eiz5EbT5kEehepDL5KTamKc2i5v1kaB", + hash: "5JvPGvbjz6Kdf9Uiif7RSDFbJRnCfN4mrwK4YuJjQWBUyZKvG6KA", }, - operations: [], + operations: [ + Operation { + operation_identifier: OperationIdentifier { + index: 0, + network_index: None, + }, + related_operations: None, + type: "zkapp_fee_payer_dec", + status: Some( + "Success", + ), + account: Some( + AccountIdentifier { + address: "B62qkZjTMxUwTTumLd5E35DHCos75hjo3jVZdMpo9D73x6vgvY2hoxs", + sub_account: None, + metadata: Some( + Object { + "token_id": String("wSHV2S4qX9jFsLjQo8r1BsMLH2ZRKsZx6EJd1sbozGPieEC4Jf"), + }, + ), + }, + ), + amount: Some( + Amount { + value: "-200000000", + currency: Currency { + symbol: "MINA", + decimals: 9, + metadata: None, + }, + metadata: None, + }, + ), + coin_change: None, + metadata: None, + }, + Operation { + operation_identifier: OperationIdentifier { + index: 1, + network_index: None, + }, + related_operations: None, + type: "zkapp_balance_update", + status: Some( + "Success", + ), + account: Some( + AccountIdentifier { + address: "B62qkZjTMxUwTTumLd5E35DHCos75hjo3jVZdMpo9D73x6vgvY2hoxs", + sub_account: None, + metadata: Some( + Object { + "token_id": String("wSHV2S4qX9jFsLjQo8r1BsMLH2ZRKsZx6EJd1sbozGPieEC4Jf"), + }, + ), + }, + ), + amount: Some( + Amount { + value: "-298800000000", + currency: Currency { + symbol: "MINA", + decimals: 9, + metadata: None, + }, + metadata: None, + }, + ), + coin_change: None, + metadata: None, + }, + Operation { + operation_identifier: OperationIdentifier { + index: 2, + network_index: None, + }, + related_operations: None, + type: "zkapp_balance_update", + status: Some( + "Success", + ), + account: Some( + AccountIdentifier { + address: "B62qpuN14M3vKvrfecc5k5Skqns4STnq54E2nvDnjvaWYduMPkT2xzs", + sub_account: None, + metadata: Some( + Object { + "token_id": String("wSHV2S4qX9jFsLjQo8r1BsMLH2ZRKsZx6EJd1sbozGPieEC4Jf"), + }, + ), + }, + ), + amount: Some( + Amount { + value: "298800000000", + currency: Currency { + symbol: "MINA", + decimals: 9, + metadata: None, + }, + metadata: None, + }, + ), + coin_change: None, + metadata: None, + }, + ], related_transactions: None, metadata: None, }, From 1ab2dd529ee5dba75b32b4f572a5e5639276b48e Mon Sep 17 00:00:00 2001 From: Piotr Stachyra Date: Tue, 22 Oct 2024 10:06:34 +0200 Subject: [PATCH 18/21] use pg_wait.ts --- deno.json | 2 +- tasks/pg_wait.sh | 17 ----------------- tasks/pg_wait.ts | 2 +- 3 files changed, 2 insertions(+), 19 deletions(-) delete mode 100755 tasks/pg_wait.sh diff --git a/deno.json b/deno.json index 7bf7cda..379ae70 100644 --- a/deno.json +++ b/deno.json @@ -5,7 +5,7 @@ "dl:devnet": "deno run -A tasks/dl.ts", "dl:mainnet": "deno task dl:devnet --network mainnet", "pg:init": "docker run -d --name mina-archive-db -p 5432:5432 -v $(pwd)/sql_scripts:/docker-entrypoint-initdb.d -e POSTGRES_PASSWORD=whatever -e POSTGRES_USER=mina postgres", - "pg:wait": "./tasks/pg_wait.sh", + "pg:wait": "deno run -A ./tasks/pg_wait.ts", "pg:up": "docker start mina-archive-db", "pg:down": "docker kill mina-archive-db", "pg:rm": "docker rm mina-archive-db", diff --git a/tasks/pg_wait.sh b/tasks/pg_wait.sh deleted file mode 100755 index 8930d15..0000000 --- a/tasks/pg_wait.sh +++ /dev/null @@ -1,17 +0,0 @@ -#!/bin/bash - -# This script is used to check if PostgreSQL is available -# Usage: ./scripts/pg_ready.sh -# Example: ./scripts/pg_ready.sh localhost 5432 - -# Parameters -PG_HOST="${1:-localhost}" -PG_PORT="${2:-5432}" - -# Wait for PostgreSQL to become available -until pg_isready -h "$PG_HOST" -p "$PG_PORT"; do - echo "Waiting for PostgreSQL to become available at ${PG_HOST}:${PG_PORT}..." - sleep 1 -done - -echo "PostgreSQL is available at ${PG_HOST}:${PG_PORT}" diff --git a/tasks/pg_wait.ts b/tasks/pg_wait.ts index eaf49eb..fb67769 100644 --- a/tasks/pg_wait.ts +++ b/tasks/pg_wait.ts @@ -32,5 +32,5 @@ while (!connected && attempts < MAX_RETRIES) { if (connected) { await client.end() - console.log("Database ready") + console.log("Database ready at", connectionString) } else throw 0 From b4b4610de1a0ed1ebce4e9b49ef68f05ed4f7c63 Mon Sep 17 00:00:00 2001 From: Piotr Stachyra Date: Tue, 22 Oct 2024 11:32:28 +0200 Subject: [PATCH 19/21] adjust pg_wait.ts --- tasks/pg_wait.ts | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/tasks/pg_wait.ts b/tasks/pg_wait.ts index fb67769..42d450f 100644 --- a/tasks/pg_wait.ts +++ b/tasks/pg_wait.ts @@ -6,7 +6,6 @@ import { assertExists } from "@std/assert" const connectionString = Deno.env.get("DATABASE_URL") assertExists(connectionString) -const client = new pg.Client({ connectionString }) const MAX_RETRIES = 200 const RETRY_INTERVAL_MS = 10_000 @@ -16,21 +15,29 @@ let attempts = 0 while (!connected && attempts < MAX_RETRIES) { try { + const client = new pg.Client({ connectionString }) await client.connect() connected = true + await client.end() } catch (err: unknown) { if (err instanceof Error && err.message.startsWith("Client has already been connected.")) { connected = true break } + attempts++ - console.log("Waiting for database to be ready.") - console.error(err) + console.log(`Attempt ${attempts} failed. Waiting for database to be ready...`) + + if (attempts >= MAX_RETRIES) { + console.error("Max retries reached. Could not connect to the database.") + } + await new Promise((resolve) => setTimeout(resolve, RETRY_INTERVAL_MS)) } } if (connected) { - await client.end() console.log("Database ready at", connectionString) -} else throw 0 +} else { + Deno.exit(1) +} From 3375290ed8eed1d7b157d44b90e275a332535e43 Mon Sep 17 00:00:00 2001 From: Piotr Stachyra Date: Tue, 22 Oct 2024 11:32:42 +0200 Subject: [PATCH 20/21] enable_logging on pg --- deno.json | 3 ++- tasks/dl.ts | 5 ----- tasks/enable_logging.ts | 12 ++++++++++++ 3 files changed, 14 insertions(+), 6 deletions(-) create mode 100644 tasks/enable_logging.ts diff --git a/deno.json b/deno.json index 379ae70..c94c259 100644 --- a/deno.json +++ b/deno.json @@ -6,10 +6,11 @@ "dl:mainnet": "deno task dl:devnet --network mainnet", "pg:init": "docker run -d --name mina-archive-db -p 5432:5432 -v $(pwd)/sql_scripts:/docker-entrypoint-initdb.d -e POSTGRES_PASSWORD=whatever -e POSTGRES_USER=mina postgres", "pg:wait": "deno run -A ./tasks/pg_wait.ts", + "pg:enable_logging": "deno run -A ./tasks/enable_logging.ts", "pg:up": "docker start mina-archive-db", "pg:down": "docker kill mina-archive-db", "pg:rm": "docker rm mina-archive-db", - "dev:init": "deno task dl:devnet && deno task pg:init && deno task pg:wait", + "dev:init": "deno task dl:devnet && deno task pg:enable_logging && deno task pg:init && deno task pg:wait", "dev": "cargo run serve --playground" }, "imports": { diff --git a/tasks/dl.ts b/tasks/dl.ts index a454823..54cc534 100644 --- a/tasks/dl.ts +++ b/tasks/dl.ts @@ -55,8 +55,3 @@ await new Deno.Command("tar", { cwd: destDir, }).output() -// TODO: automatically enable? (thoughts piotr-iohk?) -// await Deno.copyFile( -// import.meta.resolve("./enable_logging.sh"), -// path.join(destDir, "enable_logging.sh"), -// ) diff --git a/tasks/enable_logging.ts b/tasks/enable_logging.ts new file mode 100644 index 0000000..c22db3f --- /dev/null +++ b/tasks/enable_logging.ts @@ -0,0 +1,12 @@ + +import * as path from "@std/path" + +const destDir = path.join(Deno.cwd(), "sql_scripts") + +await Deno.copyFile( + path.join(path.dirname(path.fromFileUrl(import.meta.url)), "enable_logging.sh"), + path.join(destDir, "enable_logging.sh"), +) + +console.log("Copied enable_logging.sh to", destDir) +console.log("In order to apply the changes, restart the Postgres server. (deno task pg:init)") \ No newline at end of file From 18b75de5199b6ee1fbd84219c3b7239d8e0eaf9d Mon Sep 17 00:00:00 2001 From: Piotr Stachyra Date: Tue, 22 Oct 2024 13:34:53 +0200 Subject: [PATCH 21/21] use btree for tx_map in zkapp_commands_to_block_transactions too --- src/api/search_transactions.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/api/search_transactions.rs b/src/api/search_transactions.rs index ed998d0..71d5d40 100644 --- a/src/api/search_transactions.rs +++ b/src/api/search_transactions.rs @@ -1,4 +1,4 @@ -use std::collections::HashMap; +use std::collections::{BTreeMap, HashMap}; use coinbase_mesh::models::{ AccountIdentifier, BlockIdentifier, BlockTransaction, Operation, SearchTransactionsRequest, @@ -160,7 +160,7 @@ impl MinaMesh { } pub fn zkapp_commands_to_block_transactions(commands: Vec) -> Vec { - let mut block_map: HashMap<(i64, String), HashMap>> = HashMap::new(); + let mut block_map: HashMap<(i64, String), BTreeMap>> = HashMap::new(); for command in commands { // Group by block identifier (block index and block hash)