diff --git a/CHANGELOG.md b/CHANGELOG.md index d870d637..8341fb3f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ ## 0.10.35 * Upgrade Indexer Framework to be based on [`nearcore` version `1.32.2`](https://github.com/near/nearcore/releases/tag/1.32.2) +* Add support of [Meta Transactions](https://github.com/near/NEPs/pull/366) ## 0.10.34 diff --git a/migrations/2023-02-28-160000_meta_tx/down.sql b/migrations/2023-02-28-160000_meta_tx/down.sql new file mode 100644 index 00000000..dad5a586 --- /dev/null +++ b/migrations/2023-02-28-160000_meta_tx/down.sql @@ -0,0 +1,12 @@ +-- We do not drop `DELEGATE_ACTION` here because we can't remove items from enum in Postgres. +-- To be honest, it does not sound as a big problem. `IF_NOT_EXISTS` will prevent re-adding it. + +ALTER TABLE transaction_actions + DROP COLUMN is_delegate_action, + DROP COLUMN delegate_parameters, + DROP COLUMN delegate_parent_index_in_transaction; + +ALTER TABLE action_receipt_actions + DROP COLUMN is_delegate_action, + DROP COLUMN delegate_parameters, + DROP COLUMN delegate_parent_index_in_action_receipt; \ No newline at end of file diff --git a/migrations/2023-02-28-160000_meta_tx/up.sql b/migrations/2023-02-28-160000_meta_tx/up.sql new file mode 100644 index 00000000..ef34bf45 --- /dev/null +++ b/migrations/2023-02-28-160000_meta_tx/up.sql @@ -0,0 +1,17 @@ +-- If your DB is not empty, you need to turn off the Indexer, then apply the migration, then switch to 0.12.0 + +ALTER TYPE action_kind ADD VALUE IF NOT EXISTS 'DELEGATE_ACTION'; + +-- For all happy users of Postgres 11+, this should run fast +ALTER TABLE transaction_actions + ADD COLUMN is_delegate_action BOOLEAN NOT NULL DEFAULT FALSE, + ADD COLUMN delegate_parameters JSONB, + ADD COLUMN delegate_parent_index_in_transaction INTEGER; + +ALTER TABLE action_receipt_actions + ADD COLUMN is_delegate_action BOOLEAN NOT NULL DEFAULT FALSE, + ADD COLUMN delegate_parameters JSONB, + ADD COLUMN delegate_parent_index_in_action_receipt INTEGER; + +ALTER TABLE transaction_actions ALTER COLUMN is_delegate_action DROP DEFAULT; +ALTER TABLE action_receipt_actions ALTER COLUMN is_delegate_action DROP DEFAULT; \ No newline at end of file diff --git a/src/db_adapters/assets/fungible_token_events.rs b/src/db_adapters/assets/fungible_token_events.rs index c78b8a87..ac298a84 100644 --- a/src/db_adapters/assets/fungible_token_events.rs +++ b/src/db_adapters/assets/fungible_token_events.rs @@ -75,7 +75,7 @@ fn compose_ft_db_events( event_memo: mint_event .memo .clone() - .unwrap_or_else(|| "".to_string()) + .unwrap_or_default() .escape_default() .to_string(), }); @@ -102,7 +102,7 @@ fn compose_ft_db_events( event_memo: transfer_event .memo .clone() - .unwrap_or_else(|| "".to_string()) + .unwrap_or_default() .escape_default() .to_string(), }); @@ -126,7 +126,7 @@ fn compose_ft_db_events( event_memo: burn_event .memo .clone() - .unwrap_or_else(|| "".to_string()) + .unwrap_or_default() .escape_default() .to_string(), }); diff --git a/src/db_adapters/assets/non_fungible_token_events.rs b/src/db_adapters/assets/non_fungible_token_events.rs index b5c41f27..e9757309 100644 --- a/src/db_adapters/assets/non_fungible_token_events.rs +++ b/src/db_adapters/assets/non_fungible_token_events.rs @@ -59,7 +59,7 @@ fn compose_nft_db_events( match &event.event_kind { event_types::Nep171EventKind::NftMint(mint_events) => { for mint_event in mint_events { - let memo = mint_event.memo.clone().unwrap_or_else(|| "".to_string()); + let memo = mint_event.memo.clone().unwrap_or_default(); for token_id in &mint_event.token_ids { nft_events.push( models::assets::non_fungible_token_events::NonFungibleTokenEvent { @@ -84,14 +84,8 @@ fn compose_nft_db_events( } event_types::Nep171EventKind::NftTransfer(transfer_events) => { for transfer_event in transfer_events { - let authorized_id = transfer_event - .authorized_id - .clone() - .unwrap_or_else(|| "".to_string()); - let memo = transfer_event - .memo - .clone() - .unwrap_or_else(|| "".to_string()); + let authorized_id = transfer_event.authorized_id.clone().unwrap_or_default(); + let memo = transfer_event.memo.clone().unwrap_or_default(); for token_id in &transfer_event.token_ids { nft_events.push( models::assets::non_fungible_token_events::NonFungibleTokenEvent { @@ -121,11 +115,8 @@ fn compose_nft_db_events( } event_types::Nep171EventKind::NftBurn(burn_events) => { for burn_event in burn_events { - let authorized_id = &burn_event - .authorized_id - .clone() - .unwrap_or_else(|| "".to_string()); - let memo = burn_event.memo.clone().unwrap_or_else(|| "".to_string()); + let authorized_id = &burn_event.authorized_id.clone().unwrap_or_default(); + let memo = burn_event.memo.clone().unwrap_or_default(); for token_id in &burn_event.token_ids { nft_events.push( models::assets::non_fungible_token_events::NonFungibleTokenEvent { diff --git a/src/db_adapters/receipts.rs b/src/db_adapters/receipts.rs index 6f823a84..067474ad 100644 --- a/src/db_adapters/receipts.rs +++ b/src/db_adapters/receipts.rs @@ -10,7 +10,8 @@ use diesel::pg::expression::array_comparison::any; use diesel::{ExpressionMethods, JoinOnDsl, PgConnection, QueryDsl}; use futures::future::try_join_all; use futures::try_join; -use num_traits::cast::FromPrimitive; +use near_primitives::transaction::Action; +use near_primitives::views::ActionView; use tracing::{error, warn}; use crate::schema; @@ -526,36 +527,90 @@ async fn store_action_receipt_actions( receipts: &[&near_indexer::near_primitives::views::ReceiptView], block_timestamp: u64, ) -> anyhow::Result<()> { - let receipt_action_actions: Vec = receipts - .iter() - .filter_map(|receipt| { - if let near_indexer::near_primitives::views::ReceiptEnumView::Action { actions, .. } = - &receipt.receipt - { - Some(actions.iter().enumerate().map(move |(index, action)| { - models::ActionReceiptAction::from_action_view( - receipt.receipt_id.to_string(), - i32::from_usize(index).expect("We expect usize to not overflow i32 here"), - action, - receipt.predecessor_id.to_string(), - receipt.receiver_id.to_string(), - block_timestamp, - ) - })) - } else { - None + let mut action_receipt_actions: Vec = vec![]; + for receipt in receipts { + if let near_primitives::views::ReceiptEnumView::Action { actions, .. } = + &receipt.receipt + { + let mut index = 0; + for action in actions { + let (action_kind, args) = + models::extract_action_type_and_value_from_action_view(action); + match action { + ActionView::Delegate { + delegate_action, + signature, + } => { + let parent_index = index; + let delegate_parameters = serde_json::json!({ + "signature": signature, + "sender_id": delegate_action.sender_id, + "receiver_id": delegate_action.receiver_id, + "nonce": delegate_action.nonce, + "max_block_height": delegate_action.max_block_height, + "public_key": delegate_action.public_key, + }); + action_receipt_actions.push(models::ActionReceiptAction { + receipt_id: receipt.receipt_id.to_string(), + index_in_action_receipt: index, + action_kind, + args, + receipt_predecessor_account_id: receipt.predecessor_id.to_string(), + receipt_receiver_account_id: receipt.receiver_id.to_string(), + receipt_included_in_block_timestamp: block_timestamp.into(), + is_delegate_action: true, + delegate_parameters: Some(delegate_parameters.clone()), + delegate_parent_index_in_action_receipt: None, + }); + index += 1; + for non_delegate_action in &delegate_action.actions { + let (action_kind, args) = + models::extract_action_type_and_value_from_action_view( + &ActionView::from(Action::from(non_delegate_action.clone())), + ); + action_receipt_actions.push(models::ActionReceiptAction { + receipt_id: receipt.receipt_id.to_string(), + index_in_action_receipt: index, + action_kind, + args, + receipt_predecessor_account_id: receipt.predecessor_id.to_string(), + receipt_receiver_account_id: receipt.receiver_id.to_string(), + receipt_included_in_block_timestamp: block_timestamp.into(), + is_delegate_action: true, + delegate_parameters: Some(delegate_parameters.clone()), + delegate_parent_index_in_action_receipt: Some(parent_index), + }); + index += 1; + } + } + _ => { + action_receipt_actions.push(models::ActionReceiptAction { + receipt_id: receipt.receipt_id.to_string(), + index_in_action_receipt: index, + action_kind, + args, + receipt_predecessor_account_id: receipt.predecessor_id.to_string(), + receipt_receiver_account_id: receipt.receiver_id.to_string(), + receipt_included_in_block_timestamp: block_timestamp.into(), + is_delegate_action: false, + delegate_parameters: None, + delegate_parent_index_in_action_receipt: None, + }); + index += 1; + } + } } - }) - .flatten() - .collect(); + } + } + crate::await_retry_or_panic!( diesel::insert_into(schema::action_receipt_actions::table) - .values(receipt_action_actions.clone()) + .values(action_receipt_actions.clone()) .on_conflict_do_nothing() .execute_async(pool), 10, - "ReceiptActionActions were stored in database".to_string(), - &receipt_action_actions + "ActionReceiptActions were stored in database".to_string(), + &action_receipt_actions ); Ok(()) } diff --git a/src/db_adapters/transactions.rs b/src/db_adapters/transactions.rs index bc97dbb8..5c5ad3dc 100644 --- a/src/db_adapters/transactions.rs +++ b/src/db_adapters/transactions.rs @@ -5,6 +5,8 @@ use diesel::{ExpressionMethods, PgConnection, QueryDsl}; use futures::future::try_join_all; use near_indexer::near_primitives; +use near_primitives::transaction::Action; +use near_primitives::views::ActionView; use crate::schema; use crate::{metrics, models}; @@ -133,7 +135,7 @@ async fn store( async fn store_chunk_transactions( pool: &actix_diesel::Database, - transactions: Vec<(usize, &near_indexer::IndexerTransactionWithOutcome)>, + enumerated_transactions: Vec<(usize, &near_indexer::IndexerTransactionWithOutcome)>, chunk_hash: &near_indexer::near_primitives::hash::CryptoHash, block_hash: &near_indexer::near_primitives::hash::CryptoHash, block_timestamp: u64, @@ -143,7 +145,7 @@ async fn store_chunk_transactions( ) -> anyhow::Result<()> { let mut receipts_cache_lock = receipts_cache_arc.lock().await; - let transaction_models: Vec = transactions + let transaction_models: Vec = enumerated_transactions .iter() .map(|(index, tx)| { let transaction_hash = tx.transaction.hash.to_string() + transaction_hash_suffix; @@ -199,23 +201,69 @@ async fn store_chunk_transaction_actions( // hack for supporting duplicated transaction hashes. Empty for most of transactions transaction_hash_suffix: &str, ) -> anyhow::Result<()> { - let transaction_action_models: Vec = transactions - .into_iter() - .flat_map(|tx| { + let mut transaction_action_models: Vec = vec![]; + for tx in transactions { + let mut index = 0; + for action in &tx.transaction.actions { let transaction_hash = tx.transaction.hash.to_string() + transaction_hash_suffix; - tx.transaction - .actions - .iter() - .enumerate() - .map(move |(index, action)| { - models::transactions::TransactionAction::from_action_view( - transaction_hash.clone(), - index as i32, - action, - ) - }) - }) - .collect(); + let (action_kind, args) = + models::extract_action_type_and_value_from_action_view(action); + match action { + ActionView::Delegate { + delegate_action, + signature, + } => { + let parent_index = index; + let delegate_parameters = serde_json::json!({ + "signature": signature, + "sender_id": delegate_action.sender_id, + "receiver_id": delegate_action.receiver_id, + "nonce": delegate_action.nonce, + "max_block_height": delegate_action.max_block_height, + "public_key": delegate_action.public_key, + }); + transaction_action_models.push(models::transactions::TransactionAction { + transaction_hash: transaction_hash.clone(), + index_in_transaction: index, + args, + action_kind, + is_delegate_action: true, + delegate_parameters: Some(delegate_parameters.clone()), + delegate_parent_index_in_transaction: None, + }); + index += 1; + for non_delegate_action in &delegate_action.actions { + let (action_kind, args) = + models::extract_action_type_and_value_from_action_view( + &ActionView::from(Action::from(non_delegate_action.clone())), + ); + transaction_action_models.push(models::transactions::TransactionAction { + transaction_hash: transaction_hash.clone(), + index_in_transaction: index, + args, + action_kind, + is_delegate_action: true, + delegate_parameters: Some(delegate_parameters.clone()), + delegate_parent_index_in_transaction: Some(parent_index), + }); + index += 1; + } + } + _ => { + transaction_action_models.push(models::transactions::TransactionAction { + transaction_hash: transaction_hash.clone(), + index_in_transaction: index, + args, + action_kind, + is_delegate_action: false, + delegate_parameters: None, + delegate_parent_index_in_transaction: None, + }); + index += 1; + } + } + } + } crate::await_retry_or_panic!( diesel::insert_into(schema::transaction_actions::table) @@ -226,6 +274,5 @@ async fn store_chunk_transaction_actions( "TransactionActions were stored in database".to_string(), &transaction_action_models ); - Ok(()) } diff --git a/src/models/receipts.rs b/src/models/receipts.rs index 545505fd..2661efce 100644 --- a/src/models/receipts.rs +++ b/src/models/receipts.rs @@ -121,30 +121,9 @@ pub struct ActionReceiptAction { pub receipt_predecessor_account_id: String, pub receipt_receiver_account_id: String, pub receipt_included_in_block_timestamp: BigDecimal, -} - -impl ActionReceiptAction { - pub fn from_action_view( - receipt_id: String, - index: i32, - action_view: &near_indexer::near_primitives::views::ActionView, - predecessor_account_id: String, - receiver_account_id: String, - block_timestamp: u64, - ) -> Self { - let (action_kind, args) = - crate::models::extract_action_type_and_value_from_action_view(action_view); - - Self { - receipt_id, - index_in_action_receipt: index, - args, - action_kind, - receipt_predecessor_account_id: predecessor_account_id, - receipt_receiver_account_id: receiver_account_id, - receipt_included_in_block_timestamp: block_timestamp.into(), - } - } + pub is_delegate_action: bool, + pub delegate_parameters: Option, + pub delegate_parent_index_in_action_receipt: Option, } #[derive(Insertable, Clone, Debug)] diff --git a/src/models/transactions.rs b/src/models/transactions.rs index edcd9423..eb8d7336 100644 --- a/src/models/transactions.rs +++ b/src/models/transactions.rs @@ -68,21 +68,7 @@ pub struct TransactionAction { pub index_in_transaction: i32, pub action_kind: ActionKind, pub args: serde_json::Value, -} - -impl TransactionAction { - pub fn from_action_view( - transaction_hash: String, - index: i32, - action_view: &near_indexer::near_primitives::views::ActionView, - ) -> Self { - let (action_kind, args) = - crate::models::extract_action_type_and_value_from_action_view(action_view); - Self { - transaction_hash, - index_in_transaction: index, - args, - action_kind, - } - } + pub is_delegate_action: bool, + pub delegate_parameters: Option, + pub delegate_parent_index_in_transaction: Option, } diff --git a/src/schema.patch b/src/schema.patch index 5c256e08..afa2a82c 100644 --- a/src/schema.patch +++ b/src/schema.patch @@ -1,182 +1,81 @@ diff --git a/src/schema.rs b/src/schema.rs -index 16a153d..a3404c7 100644 +index a3404c7..9858b21 100644 --- a/src/schema.rs +++ b/src/schema.rs -@@ -1,6 +1,21 @@ -+// This file is autogenerated. -+// Do not edit it manually. Consider editing `diesel.toml` -+// ref: https://diesel.rs/guides/configuring-diesel-cli.html -+// -+// Steps to create proper schema.patch file: -+// - Add new migration file -+// - Add new tables to diesel.toml if applicable -+// - Comment patch line in diesel.toml -+// - `diesel migration run` -+// - (new tables/items appeared in DB, schema.rs is updated) -+// - `git add src/schema.rs && git commit -m "bad schema"` -+// - Fix schema.rs, it should look exactly like you want, it should not produce any warnings. -+// - git diff -U6 src/schema.rs > src/schema.patch -+// - Uncomment patch line -+ - table! { - use diesel::sql_types::*; - use crate::models::enums::*; - - access_keys (public_key, account_id) { - public_key -> Text, -@@ -30,13 +45,12 @@ table! { - index_in_block -> Int4, - } - } - - table! { - use diesel::sql_types::*; -- use crate::models::enums::*; - - accounts (id) { - id -> Int8, - account_id -> Text, - created_by_receipt_id -> Nullable, - deleted_by_receipt_id -> Nullable, -@@ -58,47 +72,44 @@ table! { +@@ -67,12 +67,15 @@ table! { + index_in_action_receipt -> Int4, + action_kind -> Action_kind, + args -> Jsonb, + receipt_predecessor_account_id -> Text, + receipt_receiver_account_id -> Text, receipt_included_in_block_timestamp -> Numeric, ++ is_delegate_action -> Bool, ++ delegate_parameters -> Nullable, ++ delegate_parent_index_in_action_receipt -> Nullable, } } table! { use diesel::sql_types::*; -- use crate::models::enums::*; - - action_receipt_input_data (input_data_id, input_to_receipt_id) { - input_data_id -> Text, - input_to_receipt_id -> Text, - } - } - - table! { - use diesel::sql_types::*; -- use crate::models::enums::*; - - action_receipt_output_data (output_data_id, output_from_receipt_id) { - output_data_id -> Text, - output_from_receipt_id -> Text, - receiver_account_id -> Text, - } - } - - table! { - use diesel::sql_types::*; -- use crate::models::enums::*; - - action_receipts (receipt_id) { - receipt_id -> Text, - signer_account_id -> Text, - signer_public_key -> Text, - gas_price -> Numeric, - } - } - - table! { - use diesel::sql_types::*; -- use crate::models::enums::*; -+ #[allow(non_snake_case)] - aggregated__circulating_supply (computed_at_block_hash) { - computed_at_block_timestamp -> Numeric, - computed_at_block_hash -> Text, - circulating_tokens_supply -> Numeric, - total_tokens_supply -> Numeric, - total_lockup_contracts_count -> Int4, -@@ -109,12 +120,13 @@ table! { - } +@@ -121,13 +124,13 @@ table! { table! { use diesel::sql_types::*; use crate::models::enums::*; -+ #[allow(non_snake_case)] - assets__fungible_token_events (emitted_for_receipt_id, emitted_at_block_timestamp, emitted_in_shard_id, emitted_index_of_event_entry_in_shard, emitted_by_contract_account_id, amount, event_kind, token_old_owner_account_id, token_new_owner_account_id, event_memo) { + #[allow(non_snake_case)] +- assets__fungible_token_events (emitted_for_receipt_id, emitted_at_block_timestamp, emitted_in_shard_id, emitted_index_of_event_entry_in_shard, emitted_by_contract_account_id, amount, event_kind, token_old_owner_account_id, token_new_owner_account_id, event_memo) { ++ assets__fungible_token_events (emitted_for_receipt_id, emitted_index_of_event_entry_in_shard) { emitted_for_receipt_id -> Text, emitted_at_block_timestamp -> Numeric, emitted_in_shard_id -> Numeric, emitted_index_of_event_entry_in_shard -> Int4, emitted_by_contract_account_id -> Text, -@@ -127,12 +139,13 @@ table! { - } + amount -> Text, +@@ -140,13 +143,13 @@ table! { table! { use diesel::sql_types::*; use crate::models::enums::*; -+ #[allow(non_snake_case)] - assets__non_fungible_token_events (emitted_for_receipt_id, emitted_at_block_timestamp, emitted_in_shard_id, emitted_index_of_event_entry_in_shard, emitted_by_contract_account_id, token_id, event_kind, token_old_owner_account_id, token_new_owner_account_id, token_authorized_account_id, event_memo) { + #[allow(non_snake_case)] +- assets__non_fungible_token_events (emitted_for_receipt_id, emitted_at_block_timestamp, emitted_in_shard_id, emitted_index_of_event_entry_in_shard, emitted_by_contract_account_id, token_id, event_kind, token_old_owner_account_id, token_new_owner_account_id, token_authorized_account_id, event_memo) { ++ assets__non_fungible_token_events (emitted_for_receipt_id, emitted_index_of_event_entry_in_shard) { emitted_for_receipt_id -> Text, emitted_at_block_timestamp -> Numeric, emitted_in_shard_id -> Numeric, emitted_index_of_event_entry_in_shard -> Int4, emitted_by_contract_account_id -> Text, -@@ -142,15 +155,24 @@ table! { - token_new_owner_account_id -> Text, + token_id -> Text, +@@ -156,13 +159,13 @@ table! { token_authorized_account_id -> Text, event_memo -> Text, } } -+table! { -+ use diesel::sql_types::*; -+ #[allow(non_snake_case)] -+ aggregated__lockups(account_id) { -+ account_id -> Text, -+ creation_block_height -> Nullable, -+ deletion_block_height -> Nullable, -+ } -+} -+ - table! { - use diesel::sql_types::*; -- use crate::models::enums::*; - - blocks (block_hash) { - block_height -> Numeric, - block_hash -> Text, - prev_block_hash -> Text, - block_timestamp -> Numeric, -@@ -159,13 +181,12 @@ table! { - author_account_id -> Text, - } - } - table! { - use diesel::sql_types::*; -- use crate::models::enums::*; - - chunks (chunk_hash) { - included_in_block_hash -> Text, - chunk_hash -> Text, - shard_id -> Numeric, - signature -> Text, -@@ -174,24 +195,22 @@ table! { - author_account_id -> Text, +- use diesel::sql_types::*; ++ use diesel::sql_types::*; + #[allow(non_snake_case)] + aggregated__lockups(account_id) { + account_id -> Text, + creation_block_height -> Nullable, + deletion_block_height -> Nullable, } - } - - table! { - use diesel::sql_types::*; -- use crate::models::enums::*; - - data_receipts (data_id) { - data_id -> Text, - receipt_id -> Text, - data -> Nullable, +@@ -256,12 +259,15 @@ table! { + + transaction_actions (transaction_hash, index_in_transaction) { + transaction_hash -> Text, + index_in_transaction -> Int4, + action_kind -> Action_kind, + args -> Jsonb, ++ is_delegate_action -> Bool, ++ delegate_parameters -> Nullable, ++ delegate_parent_index_in_transaction -> Nullable, } } table! { use diesel::sql_types::*; -- use crate::models::enums::*; - - execution_outcome_receipts (executed_receipt_id, index_in_execution_outcome, produced_receipt_id) { - executed_receipt_id -> Text, - index_in_execution_outcome -> Int4, - produced_receipt_id -> Text, - } + use crate::models::enums::*; diff --git a/src/schema.rs b/src/schema.rs index a3404c7a..9858b214 100644 --- a/src/schema.rs +++ b/src/schema.rs @@ -70,6 +70,9 @@ table! { receipt_predecessor_account_id -> Text, receipt_receiver_account_id -> Text, receipt_included_in_block_timestamp -> Numeric, + is_delegate_action -> Bool, + delegate_parameters -> Nullable, + delegate_parent_index_in_action_receipt -> Nullable, } } @@ -124,7 +127,7 @@ table! { use crate::models::enums::*; #[allow(non_snake_case)] - assets__fungible_token_events (emitted_for_receipt_id, emitted_at_block_timestamp, emitted_in_shard_id, emitted_index_of_event_entry_in_shard, emitted_by_contract_account_id, amount, event_kind, token_old_owner_account_id, token_new_owner_account_id, event_memo) { + assets__fungible_token_events (emitted_for_receipt_id, emitted_index_of_event_entry_in_shard) { emitted_for_receipt_id -> Text, emitted_at_block_timestamp -> Numeric, emitted_in_shard_id -> Numeric, @@ -143,7 +146,7 @@ table! { use crate::models::enums::*; #[allow(non_snake_case)] - assets__non_fungible_token_events (emitted_for_receipt_id, emitted_at_block_timestamp, emitted_in_shard_id, emitted_index_of_event_entry_in_shard, emitted_by_contract_account_id, token_id, event_kind, token_old_owner_account_id, token_new_owner_account_id, token_authorized_account_id, event_memo) { + assets__non_fungible_token_events (emitted_for_receipt_id, emitted_index_of_event_entry_in_shard) { emitted_for_receipt_id -> Text, emitted_at_block_timestamp -> Numeric, emitted_in_shard_id -> Numeric, @@ -159,7 +162,7 @@ table! { } table! { - use diesel::sql_types::*; + use diesel::sql_types::*; #[allow(non_snake_case)] aggregated__lockups(account_id) { account_id -> Text, @@ -259,6 +262,9 @@ table! { index_in_transaction -> Int4, action_kind -> Action_kind, args -> Jsonb, + is_delegate_action -> Bool, + delegate_parameters -> Nullable, + delegate_parent_index_in_transaction -> Nullable, } }