From 9b6b7048e8b2d6bf80cb6999c5872df30e74cc21 Mon Sep 17 00:00:00 2001 From: Stan Bondi Date: Wed, 4 Sep 2024 12:09:31 +0400 Subject: [PATCH] fix(consensus)!: state change on foreign proposals in local blocks (#1130) Description --- Propose foreign proposals before associated transaction pending state changes occur. Evidence structure now holds a QC ID for prepare and accept phases for each substate. Indexer will submit transactions to two validators instead of just one. Remove unused `should_propagate` option from the mempool. Motivation and Context --- Previously foreign proposals would appear after the transaction that they justify. Foreign proposals should be proposed and the transaction stage transactions included in the change set for the block. How Has This Been Tested? --- Existing tests, manually What process can a PR reviewer use to test or verify this change? --- Observe blocks contain foreign proposals that affect LocalPrepare and LocalAccept pledging at or before the actual stage transaction is proposed. Breaking Changes --- - [ ] None - [x] Requires data directory to be deleted - [ ] Other - Please specify --- .../src/transaction_manager/mod.rs | 31 +- .../webui/src/components/MinotariNodes.tsx | 63 + .../webui/src/components/MinotariWallet.tsx | 5 +- .../webui/src/routes/Main.tsx | 6 +- .../src/p2p/rpc/service_impl.rs | 3 +- .../src/p2p/services/mempool/gossip.rs | 91 -- .../src/p2p/services/mempool/handle.rs | 3 - .../src/p2p/services/mempool/service.rs | 146 +-- bindings/build.sh | 6 +- bindings/dist/index.d.ts | 1070 ---------------- bindings/dist/index.js | 1088 ---------------- bindings/dist/types/ForeignProposal.d.ts | 10 - bindings/dist/types/ForeignProposal.js | 1 - bindings/dist/types/ForeignProposalState.d.ts | 1 - bindings/dist/types/ForeignProposalState.js | 2 - bindings/dist/types/ShardEvidence.d.ts | 3 +- bindings/dist/types/SubstateLockFlag.d.ts | 1 - bindings/dist/types/SubstateLockFlag.js | 2 - .../dist/types/TransactionPoolRecord.d.ts | 1 - .../tari-indexer-client/AddPeerRequest.d.ts | 5 - .../tari-indexer-client/AddPeerRequest.js | 2 - .../tari-indexer-client/AddPeerResponse.d.ts | 1 - .../tari-indexer-client/AddPeerResponse.js | 2 - .../types/tari-indexer-client/Connection.d.ts | 16 - .../types/tari-indexer-client/Connection.js | 1 - .../ConnectionDirection.d.ts | 1 - .../ConnectionDirection.js | 2 - .../tari-indexer-client/GetAllVnsRequest.d.ts | 4 - .../tari-indexer-client/GetAllVnsRequest.js | 1 - .../GetAllVnsResponse.d.ts | 4 - .../tari-indexer-client/GetAllVnsResponse.js | 1 - .../GetCommsStatsResponse.d.ts | 3 - .../GetCommsStatsResponse.js | 2 - .../GetConnectionsResponse.d.ts | 4 - .../GetConnectionsResponse.js | 1 - .../GetEpochManagerStatsResponse.d.ts | 6 - .../GetEpochManagerStatsResponse.js | 1 - .../GetIdentityResponse.d.ts | 5 - .../GetIdentityResponse.js | 2 - .../GetSubstateRequest.d.ts | 6 - .../tari-indexer-client/GetSubstateRequest.js | 1 - .../GetSubstateResponse.d.ts | 8 - .../GetSubstateResponse.js | 1 - .../GetTransactionResultRequest.d.ts | 3 - .../GetTransactionResultRequest.js | 2 - .../GetTransactionResultResponse.d.ts | 4 - .../GetTransactionResultResponse.js | 1 - .../SubmitTransactionRequest.d.ts | 7 - .../SubmitTransactionRequest.js | 1 - .../SubmitTransactionResponse.d.ts | 5 - .../SubmitTransactionResponse.js | 1 - .../validator-node-client/AddPeerRequest.d.ts | 5 - .../validator-node-client/AddPeerRequest.js | 2 - .../AddPeerResponse.d.ts | 1 - .../validator-node-client/AddPeerResponse.js | 2 - .../types/validator-node-client/ArgDef.d.ts | 4 - .../types/validator-node-client/ArgDef.js | 2 - .../CommitteeShardInfo.d.ts | 10 - .../CommitteeShardInfo.js | 1 - .../validator-node-client/Connection.d.ts | 16 - .../types/validator-node-client/Connection.js | 1 - .../ConnectionDirection.d.ts | 1 - .../ConnectionDirection.js | 2 - .../validator-node-client/FunctionDef.d.ts | 7 - .../validator-node-client/FunctionDef.js | 1 - .../GetAllVnsRequest.d.ts | 4 - .../validator-node-client/GetAllVnsRequest.js | 1 - .../GetAllVnsResponse.d.ts | 4 - .../GetAllVnsResponse.js | 1 - .../GetCommsStatsResponse.d.ts | 3 - .../GetCommsStatsResponse.js | 2 - .../GetConnectionsResponse.d.ts | 4 - .../GetConnectionsResponse.js | 1 - .../GetIdentityResponse.d.ts | 8 - .../GetIdentityResponse.js | 2 - .../GetSubstateRequest.d.ts | 5 - .../GetSubstateRequest.js | 1 - .../GetSubstateResponse.d.ts | 7 - .../GetSubstateResponse.js | 1 - .../GetTransactionResultRequest.d.ts | 3 - .../GetTransactionResultRequest.js | 2 - .../GetTransactionResultResponse.d.ts | 14 - .../GetTransactionResultResponse.js | 1 - .../types/validator-node-client/LogEntry.d.ts | 6 - .../types/validator-node-client/LogEntry.js | 1 - .../types/validator-node-client/LogLevel.d.ts | 1 - .../types/validator-node-client/LogLevel.js | 2 - .../SubmitTransactionRequest.d.ts | 5 - .../SubmitTransactionRequest.js | 1 - .../SubmitTransactionResponse.d.ts | 5 - .../SubmitTransactionResponse.js | 1 - bindings/src/index.ts | 1097 ----------------- bindings/src/types/ForeignProposal.ts | 12 - bindings/src/types/ForeignProposalState.ts | 3 - bindings/src/types/ShardEvidence.ts | 3 +- bindings/src/types/SubstateLockFlag.ts | 3 - bindings/src/types/TransactionPoolRecord.ts | 1 - .../common_types/src/substate_address.rs | 12 + .../common_types/src/versioned_substate_id.rs | 5 - .../src/hotstuff/block_change_set.rs | 126 +- .../hotstuff/foreign_proposal_processor.rs | 481 ++++++++ dan_layer/consensus/src/hotstuff/mod.rs | 1 + .../src/hotstuff/on_message_validate.rs | 6 + .../consensus/src/hotstuff/on_propose.rs | 201 ++- .../on_ready_to_vote_on_local_block.rs | 642 +++++----- .../hotstuff/on_receive_foreign_proposal.rs | 901 +++++++------- .../src/hotstuff/on_receive_local_proposal.rs | 90 +- dan_layer/consensus/src/hotstuff/worker.rs | 26 +- dan_layer/consensus_tests/src/consensus.rs | 2 - .../up.sql | 133 +- dan_layer/state_store_sqlite/src/reader.rs | 72 +- dan_layer/state_store_sqlite/src/schema.rs | 8 +- .../src/sql_models/foreign_proposal.rs | 6 + .../src/sql_models/foreign_substate_pledge.rs | 1 + .../src/sql_models/quorum_certificate.rs | 1 + .../src/sql_models/transaction_pool.rs | 23 +- dan_layer/state_store_sqlite/src/writer.rs | 171 +-- dan_layer/state_store_sqlite/tests/tests.rs | 70 +- .../storage/src/consensus_models/block.rs | 48 +- .../src/consensus_models/block_pledges.rs | 34 +- .../storage/src/consensus_models/command.rs | 44 +- .../storage/src/consensus_models/evidence.rs | 133 +- .../src/consensus_models/foreign_proposal.rs | 53 +- .../src/consensus_models/lock_intent.rs | 7 +- .../src/consensus_models/transaction.rs | 4 +- .../src/consensus_models/transaction_pool.rs | 171 +-- .../transaction_pool_status_update.rs | 43 +- dan_layer/storage/src/state_store/mod.rs | 31 +- .../template_lib/src/models/entity_id.rs | 2 +- .../tests/features/claim_burn.feature | 6 +- .../tests/features/transfer.feature | 4 +- .../tests/features/wallet_daemon.feature | 2 +- .../tests/steps/validator_node.rs | 36 +- 133 files changed, 2376 insertions(+), 5117 deletions(-) create mode 100644 applications/tari_swarm_daemon/webui/src/components/MinotariNodes.tsx delete mode 100644 bindings/dist/types/ForeignProposal.d.ts delete mode 100644 bindings/dist/types/ForeignProposal.js delete mode 100644 bindings/dist/types/ForeignProposalState.d.ts delete mode 100644 bindings/dist/types/ForeignProposalState.js delete mode 100644 bindings/dist/types/SubstateLockFlag.d.ts delete mode 100644 bindings/dist/types/SubstateLockFlag.js delete mode 100644 bindings/dist/types/tari-indexer-client/AddPeerRequest.d.ts delete mode 100644 bindings/dist/types/tari-indexer-client/AddPeerRequest.js delete mode 100644 bindings/dist/types/tari-indexer-client/AddPeerResponse.d.ts delete mode 100644 bindings/dist/types/tari-indexer-client/AddPeerResponse.js delete mode 100644 bindings/dist/types/tari-indexer-client/Connection.d.ts delete mode 100644 bindings/dist/types/tari-indexer-client/Connection.js delete mode 100644 bindings/dist/types/tari-indexer-client/ConnectionDirection.d.ts delete mode 100644 bindings/dist/types/tari-indexer-client/ConnectionDirection.js delete mode 100644 bindings/dist/types/tari-indexer-client/GetAllVnsRequest.d.ts delete mode 100644 bindings/dist/types/tari-indexer-client/GetAllVnsRequest.js delete mode 100644 bindings/dist/types/tari-indexer-client/GetAllVnsResponse.d.ts delete mode 100644 bindings/dist/types/tari-indexer-client/GetAllVnsResponse.js delete mode 100644 bindings/dist/types/tari-indexer-client/GetCommsStatsResponse.d.ts delete mode 100644 bindings/dist/types/tari-indexer-client/GetCommsStatsResponse.js delete mode 100644 bindings/dist/types/tari-indexer-client/GetConnectionsResponse.d.ts delete mode 100644 bindings/dist/types/tari-indexer-client/GetConnectionsResponse.js delete mode 100644 bindings/dist/types/tari-indexer-client/GetEpochManagerStatsResponse.d.ts delete mode 100644 bindings/dist/types/tari-indexer-client/GetEpochManagerStatsResponse.js delete mode 100644 bindings/dist/types/tari-indexer-client/GetIdentityResponse.d.ts delete mode 100644 bindings/dist/types/tari-indexer-client/GetIdentityResponse.js delete mode 100644 bindings/dist/types/tari-indexer-client/GetSubstateRequest.d.ts delete mode 100644 bindings/dist/types/tari-indexer-client/GetSubstateRequest.js delete mode 100644 bindings/dist/types/tari-indexer-client/GetSubstateResponse.d.ts delete mode 100644 bindings/dist/types/tari-indexer-client/GetSubstateResponse.js delete mode 100644 bindings/dist/types/tari-indexer-client/GetTransactionResultRequest.d.ts delete mode 100644 bindings/dist/types/tari-indexer-client/GetTransactionResultRequest.js delete mode 100644 bindings/dist/types/tari-indexer-client/GetTransactionResultResponse.d.ts delete mode 100644 bindings/dist/types/tari-indexer-client/GetTransactionResultResponse.js delete mode 100644 bindings/dist/types/tari-indexer-client/SubmitTransactionRequest.d.ts delete mode 100644 bindings/dist/types/tari-indexer-client/SubmitTransactionRequest.js delete mode 100644 bindings/dist/types/tari-indexer-client/SubmitTransactionResponse.d.ts delete mode 100644 bindings/dist/types/tari-indexer-client/SubmitTransactionResponse.js delete mode 100644 bindings/dist/types/validator-node-client/AddPeerRequest.d.ts delete mode 100644 bindings/dist/types/validator-node-client/AddPeerRequest.js delete mode 100644 bindings/dist/types/validator-node-client/AddPeerResponse.d.ts delete mode 100644 bindings/dist/types/validator-node-client/AddPeerResponse.js delete mode 100644 bindings/dist/types/validator-node-client/ArgDef.d.ts delete mode 100644 bindings/dist/types/validator-node-client/ArgDef.js delete mode 100644 bindings/dist/types/validator-node-client/CommitteeShardInfo.d.ts delete mode 100644 bindings/dist/types/validator-node-client/CommitteeShardInfo.js delete mode 100644 bindings/dist/types/validator-node-client/Connection.d.ts delete mode 100644 bindings/dist/types/validator-node-client/Connection.js delete mode 100644 bindings/dist/types/validator-node-client/ConnectionDirection.d.ts delete mode 100644 bindings/dist/types/validator-node-client/ConnectionDirection.js delete mode 100644 bindings/dist/types/validator-node-client/FunctionDef.d.ts delete mode 100644 bindings/dist/types/validator-node-client/FunctionDef.js delete mode 100644 bindings/dist/types/validator-node-client/GetAllVnsRequest.d.ts delete mode 100644 bindings/dist/types/validator-node-client/GetAllVnsRequest.js delete mode 100644 bindings/dist/types/validator-node-client/GetAllVnsResponse.d.ts delete mode 100644 bindings/dist/types/validator-node-client/GetAllVnsResponse.js delete mode 100644 bindings/dist/types/validator-node-client/GetCommsStatsResponse.d.ts delete mode 100644 bindings/dist/types/validator-node-client/GetCommsStatsResponse.js delete mode 100644 bindings/dist/types/validator-node-client/GetConnectionsResponse.d.ts delete mode 100644 bindings/dist/types/validator-node-client/GetConnectionsResponse.js delete mode 100644 bindings/dist/types/validator-node-client/GetIdentityResponse.d.ts delete mode 100644 bindings/dist/types/validator-node-client/GetIdentityResponse.js delete mode 100644 bindings/dist/types/validator-node-client/GetSubstateRequest.d.ts delete mode 100644 bindings/dist/types/validator-node-client/GetSubstateRequest.js delete mode 100644 bindings/dist/types/validator-node-client/GetSubstateResponse.d.ts delete mode 100644 bindings/dist/types/validator-node-client/GetSubstateResponse.js delete mode 100644 bindings/dist/types/validator-node-client/GetTransactionResultRequest.d.ts delete mode 100644 bindings/dist/types/validator-node-client/GetTransactionResultRequest.js delete mode 100644 bindings/dist/types/validator-node-client/GetTransactionResultResponse.d.ts delete mode 100644 bindings/dist/types/validator-node-client/GetTransactionResultResponse.js delete mode 100644 bindings/dist/types/validator-node-client/LogEntry.d.ts delete mode 100644 bindings/dist/types/validator-node-client/LogEntry.js delete mode 100644 bindings/dist/types/validator-node-client/LogLevel.d.ts delete mode 100644 bindings/dist/types/validator-node-client/LogLevel.js delete mode 100644 bindings/dist/types/validator-node-client/SubmitTransactionRequest.d.ts delete mode 100644 bindings/dist/types/validator-node-client/SubmitTransactionRequest.js delete mode 100644 bindings/dist/types/validator-node-client/SubmitTransactionResponse.d.ts delete mode 100644 bindings/dist/types/validator-node-client/SubmitTransactionResponse.js delete mode 100644 bindings/src/types/ForeignProposal.ts delete mode 100644 bindings/src/types/ForeignProposalState.ts delete mode 100644 bindings/src/types/SubstateLockFlag.ts create mode 100644 dan_layer/consensus/src/hotstuff/foreign_proposal_processor.rs diff --git a/applications/tari_indexer/src/transaction_manager/mod.rs b/applications/tari_indexer/src/transaction_manager/mod.rs index 92e1beef5..f9fd38126 100644 --- a/applications/tari_indexer/src/transaction_manager/mod.rs +++ b/applications/tari_indexer/src/transaction_manager/mod.rs @@ -88,7 +88,7 @@ where let transaction_substate_address = SubstateAddress::for_transaction_receipt(tx_hash.into_array().into()); if transaction.all_inputs_iter().next().is_none() { - self.try_with_committee(iter::once(transaction_substate_address), |mut client| { + self.try_with_committee(iter::once(transaction_substate_address), 2, |mut client| { let transaction = transaction.clone(); async move { client.submit_transaction(transaction).await } }) @@ -98,7 +98,7 @@ where .all_inputs_iter() // If there is no version specified, submit to the validator node with version 0 .map(|i| i.or_zero_version().to_substate_address()); - self.try_with_committee(involved, |mut client| { + self.try_with_committee(involved, 2, |mut client| { let transaction = transaction.clone(); async move { client.submit_transaction(transaction).await } }) @@ -123,7 +123,7 @@ where transaction_id: TransactionId, ) -> Result { let transaction_substate_address = SubstateAddress::for_transaction_receipt(transaction_id.into_array().into()); - self.try_with_committee(iter::once(transaction_substate_address), |mut client| async move { + self.try_with_committee(iter::once(transaction_substate_address), 1, |mut client| async move { client.get_finalized_transaction_result(transaction_id).await.optional() }) .await? @@ -140,7 +140,7 @@ where ) -> Result { let shard = SubstateAddress::from_substate_id(&substate_address, version); - self.try_with_committee(iter::once(shard), |mut client| { + self.try_with_committee(iter::once(shard), 1, |mut client| { // This double clone looks strange, but it's needed because this function is called in a loop // and each iteration needs its own copy of the address (because of the move). let substate_address = substate_address.clone(); @@ -160,6 +160,7 @@ where async fn try_with_committee<'a, F, T, E, TFut, IShard>( &self, substate_addresses: IShard, + mut num_to_query: usize, mut callback: F, ) -> Result where @@ -186,12 +187,19 @@ where return Err(TransactionManagerError::NoCommitteeMembers); } + let mut num_succeeded = 0; let mut last_error = None; + let mut last_return = None; for validator in all_members { let client = self.client_provider.create_client(&validator); match callback(client).await { Ok(ret) => { - return Ok(ret); + num_to_query = num_to_query.saturating_sub(1); + num_succeeded += 1; + last_return = Some(ret); + if num_to_query == 0 { + break; + } }, Err(err) => { warn!( @@ -199,14 +207,17 @@ where "Request failed for validator '{}': {}", validator, err ); last_error = Some(err.to_string()); - continue; }, } } - Err(TransactionManagerError::AllValidatorsFailed { - committee_size, - last_error, - }) + if num_succeeded == 0 { + return Err(TransactionManagerError::AllValidatorsFailed { + committee_size, + last_error, + }); + } + + Ok(last_return.expect("last_return must be Some if num_succeeded > 0")) } } diff --git a/applications/tari_swarm_daemon/webui/src/components/MinotariNodes.tsx b/applications/tari_swarm_daemon/webui/src/components/MinotariNodes.tsx new file mode 100644 index 000000000..b29b641fe --- /dev/null +++ b/applications/tari_swarm_daemon/webui/src/components/MinotariNodes.tsx @@ -0,0 +1,63 @@ +// Copyright 2024 The Tari Project +// SPDX-License-Identifier: BSD-3-Clause + +import React from "react"; +import { jsonRpc } from "../utils/json_rpc.tsx"; +import NodeControls from "./NodeControls.tsx"; + +interface Props { + showLogs: boolean; +} + +export default function MinotariNodes(props: Props) { + const [nodes, setNodes] = React.useState(null); + const [isLoading, setIsLoading] = React.useState(true); + + + React.useEffect(() => { + jsonRpc("list_instances", { by_type: "MinoTariNode" }).then((nodes: any) => setNodes(nodes.instances)) + .then(() => setIsLoading(false)); + }, []); + + if (isLoading) { + return
Loading...
; + } + + return ( +
+ {nodes!.map((node: any, i: number) => ( + + ))} +
+ ); +} + +function Node(props: any) { + const onStart = () => { + jsonRpc("start_instance", { instance_id: props.id }); + }; + + const onStop = () => { + jsonRpc("stop_instance", { instance_id: props.id }); + }; + + const onDeleteData = () => { + jsonRpc("delete_instance_data", { instance_id: props.id }); + }; + + return ( +
+
+ Name + {props.name} +
+ +
+ GRPC + {props.ports.grpc} +
+ + {props.showLogs &&
TODO
} +
+ ); +} diff --git a/applications/tari_swarm_daemon/webui/src/components/MinotariWallet.tsx b/applications/tari_swarm_daemon/webui/src/components/MinotariWallet.tsx index 2703e3eac..ed05761cc 100644 --- a/applications/tari_swarm_daemon/webui/src/components/MinotariWallet.tsx +++ b/applications/tari_swarm_daemon/webui/src/components/MinotariWallet.tsx @@ -48,6 +48,8 @@ function Wallet(props: any) { jsonRpc("delete_instance_data", { instance_id: props.id }); }; + const wallet = props.danWallets[0]; + return (
@@ -60,7 +62,8 @@ function Wallet(props: any) { {props.ports.grpc}
- + {(wallet) ? + : <>} {props.showLogs &&
TODO
}
); diff --git a/applications/tari_swarm_daemon/webui/src/routes/Main.tsx b/applications/tari_swarm_daemon/webui/src/routes/Main.tsx index 907f85c51..714c9961d 100644 --- a/applications/tari_swarm_daemon/webui/src/routes/Main.tsx +++ b/applications/tari_swarm_daemon/webui/src/routes/Main.tsx @@ -6,6 +6,7 @@ import { jsonRpc } from "../utils/json_rpc"; import { ExecutedTransaction } from "../Types.ts"; import MinotariWallet from "../components/MinotariWallet"; import NodeControls from "../components/NodeControls.tsx"; +import MinotariNodes from "../components/MinotariNodes.tsx"; enum Executable { BaseNode = 1, @@ -377,7 +378,6 @@ export default function Main() { const [vns, setVns] = useState({}); const [danWallet, setDanWallets] = useState({}); const [indexers, setIndexers] = useState({}); - const [node, setNode] = useState<{ grpc: any }>(); const [logs, setLogs] = useState({}); const [stdoutLogs, setStdoutLogs] = useState({}); const [connectorSample, setConnectorSample] = useState(null); @@ -470,7 +470,6 @@ export default function Main() { jsonRpc("get_stdout", "miner").then((resp) => { setStdoutLogs((state: any) => ({ ...state, miner: resp })); }); - jsonRpc("grpc_node").then((resp) => setNode({ grpc: resp })); jsonRpc("list_instances", { by_type: null }).then(({ instances }) => setInstances(instances)); }; @@ -502,8 +501,7 @@ export default function Main() {
Base layer
- + diff --git a/applications/tari_validator_node/src/p2p/rpc/service_impl.rs b/applications/tari_validator_node/src/p2p/rpc/service_impl.rs index ba788074b..bdf1a9898 100644 --- a/applications/tari_validator_node/src/p2p/rpc/service_impl.rs +++ b/applications/tari_validator_node/src/p2p/rpc/service_impl.rs @@ -115,13 +115,14 @@ impl ValidatorNodeRpcService for ValidatorNodeRpcServiceImpl { .map_err(|e| RpcStatus::bad_request(format!("Malformed transaction: {}", e)))?; let transaction_id = *transaction.id(); + info!(target: LOG_TARGET, "🌐 Received transaction {transaction_id} from peer"); self.mempool .submit_transaction(transaction) .await .map_err(|e| RpcStatus::bad_request(format!("Invalid transaction: {}", e)))?; - debug!(target: LOG_TARGET, "Accepted instruction into mempool"); + debug!(target: LOG_TARGET, "Accepted transaction {transaction_id} into mempool"); Ok(Response::new(proto::rpc::SubmitTransactionResponse { transaction_id: transaction_id.as_bytes().to_vec(), diff --git a/applications/tari_validator_node/src/p2p/services/mempool/gossip.rs b/applications/tari_validator_node/src/p2p/services/mempool/gossip.rs index 09ac9cd58..91b78038d 100644 --- a/applications/tari_validator_node/src/p2p/services/mempool/gossip.rs +++ b/applications/tari_validator_node/src/p2p/services/mempool/gossip.rs @@ -106,63 +106,6 @@ impl MempoolGossip { self.gossip.publish_message(topic, msg.clone()).await?; } - // let committees = self.epoch_manager.get_committees_by_shards(epoch, shards).await?; - // let local_shard = self.epoch_manager.get_local_committee_shard(epoch).await?; - // let local_committee = self.epoch_manager.get_local_committee(epoch).await?; - // - // if local_committee.is_empty() { - // error!(target: LOG_TARGET, "BUG: forward_to_foreign_replicas: get_local_committee returned empty - // committee"); return Ok(()); - // } - // - // let Some(our_index) = local_committee - // .members() - // .position(|addr| addr == &self.validator_address) - // else { - // error!(target: LOG_TARGET, "BUG: forward_to_foreign_replicas: get_local_committee returned committee that - // this node is not part of"); return Ok(()); - // }; - // - // let mut selected_members = vec![]; - // for (bucket, committee) in committees { - // // Dont forward locally - // if bucket == local_shard.bucket() { - // continue; - // } - // if exclude_bucket.map(|b| b == bucket).unwrap_or(false) { - // continue; - // } - // if committee.is_empty() { - // error!( - // target: LOG_TARGET, - // "BUG: forward_to_foreign_replicas: get_committees_by_shards returned empty committee" - // ); - // continue; - // } - // let n = if local_committee.len() > committee.len() { - // // Our local committee is bigger, so we send to a single node - // 1 - // } else { - // // Our local committee is smaller, so we send to a portion of their nodes - // committee.len() / local_committee.len() - // }; - // - // selected_members.extend(committee.select_n_starting_from(n, our_index).cloned()); - // } - // - // debug!( - // target: LOG_TARGET, - // "forward_to_foreign_replicas: {} member(s) selected", - // selected_members.len(), - // ); - // - // if selected_members.is_empty() { - // return Ok(()); - // } - // - // // TODO: change this to use goissipsub - // self.outbound.broadcast(selected_members.iter(), msg).await?; - Ok(()) } @@ -172,41 +115,7 @@ impl MempoolGossip { addresses: HashSet, msg: T, ) -> Result<(), MempoolError> { - // let committees = self.epoch_manager.get_committees_by_shards(epoch, shards).await?; - // let local_shard = self.epoch_manager.get_local_committee_shard(epoch).await?; - // - // let mut selected_members = vec![]; - // for (bucket, committee) in committees { - // // Dont forward locally - // if bucket == local_shard.bucket() { - // continue; - // } - // if committee.is_empty() { - // error!( - // target: LOG_TARGET, - // "BUG: gossip_to_foreign_replicas: get_committees_by_shards returned empty committee" - // ); - // continue; - // } - // let f = committee.max_failures(); - // - // selected_members.extend(committee.select_n_random(f + 1).cloned()); - // } - // - // debug!( - // target: LOG_TARGET, - // "gossip_to_foreign_replicas: {} member(s) selected", - // selected_members.len(), - // ); - // - // if selected_members.is_empty() { - // return Ok(()); - // } - // - // self.outbound.broadcast(selected_members.iter(), msg).await?; - self.forward_to_foreign_replicas(epoch, addresses, msg, None).await?; - Ok(()) } } diff --git a/applications/tari_validator_node/src/p2p/services/mempool/handle.rs b/applications/tari_validator_node/src/p2p/services/mempool/handle.rs index 94572fe2a..46ac881e8 100644 --- a/applications/tari_validator_node/src/p2p/services/mempool/handle.rs +++ b/applications/tari_validator_node/src/p2p/services/mempool/handle.rs @@ -28,8 +28,6 @@ use crate::p2p::services::mempool::MempoolError; pub enum MempoolRequest { SubmitTransaction { transaction: Box, - /// If true, the transaction will be propagated to peers - should_propagate: bool, reply: oneshot::Sender>, }, RemoveTransactions { @@ -64,7 +62,6 @@ impl MempoolHandle { self.tx_mempool_request .send(MempoolRequest::SubmitTransaction { transaction: Box::new(transaction), - should_propagate: true, reply, }) .await?; diff --git a/applications/tari_validator_node/src/p2p/services/mempool/service.rs b/applications/tari_validator_node/src/p2p/services/mempool/service.rs index 3422350de..314e4f909 100644 --- a/applications/tari_validator_node/src/p2p/services/mempool/service.rs +++ b/applications/tari_validator_node/src/p2p/services/mempool/service.rs @@ -129,16 +129,8 @@ where TValidator: Validator { - handle( - reply, - self.handle_new_transaction_from_local(*transaction, should_propagate) - .await, - ); + MempoolRequest::SubmitTransaction { transaction, reply } => { + handle(reply, self.handle_new_transaction_from_local(*transaction).await); }, MempoolRequest::RemoveTransactions { transaction_ids, reply } => { let num_found = self.remove_transactions(&transaction_ids); @@ -160,11 +152,7 @@ where TValidator: Validator Result<(), MempoolError> { + async fn handle_new_transaction_from_local(&mut self, transaction: Transaction) -> Result<(), MempoolError> { if self.transaction_exists(transaction.id())? { return Ok(()); } @@ -175,8 +163,7 @@ where TValidator: Validator, - should_propagate: bool, sender_shard_group: Option, ) -> Result<(), MempoolError> { #[cfg(feature = "metrics")] @@ -311,18 +297,46 @@ where TValidator: Validator>(); + debug!( + target: LOG_TARGET, + "🎱 Propagating transaction {} ({} address(es))", + transaction.id(), + substate_addresses.len() + ); + if let Err(e) = self + .gossip + .gossip_to_foreign_replicas(current_epoch, substate_addresses, NewTransactionMessage { + transaction, + output_shards: vec![], + }) + .await + { + warn!( + target: LOG_TARGET, + "Unable to propagate transaction among peers: {}", + e + ); } } diff --git a/bindings/build.sh b/bindings/build.sh index 9258d61cd..2fc079492 100755 --- a/bindings/build.sh +++ b/bindings/build.sh @@ -5,15 +5,19 @@ set -e SOURCE_PATH="./src" TYPES_DIR="types" +DIST_DIR="dist" HELPERS_DIR="helpers" MAIN_INDEX_FILE="index.ts" if [ -f "$SOURCE_PATH/$TYPES_DIR" ]; then npx shx rm -rf $SOURCE_PATH/$TYPES_DIR fi -if [ -f "$SOURCE_PATH/$TYPES_DIR" ]; then +if [ -f "$SOURCE_PATH/$MAIN_INDEX_FILE" ]; then npx shx rm -rf $SOURCE_PATH/$MAIN_INDEX_FILE fi +if [ -f "$SOURCE_PATH/$DIST_DIR" ]; then + npx shx rm -rf ./$DIST_DIR +fi cargo test --workspace --exclude integration_tests export_bindings --features ts npx shx mv ../dan_layer/bindings/src/types/* ./src/types/ diff --git a/bindings/dist/index.d.ts b/bindings/dist/index.d.ts index 06f44941c..5ff98569f 100644 --- a/bindings/dist/index.d.ts +++ b/bindings/dist/index.d.ts @@ -37,1076 +37,7 @@ export * from "./types/FeeCostBreakdown"; export * from "./types/FeeReceipt"; export * from "./types/FeeSource"; export * from "./types/FinalizeResult"; -export * from "./types/ForeignProposalState"; -export * from "./types/ForeignProposal"; -export * from "./types/FunctionDef"; -export * from "./types/IndexedValue"; -export * from "./types/IndexedWellKnownTypes"; -export * from "./types/InstructionResult"; -export * from "./types/Instruction"; -export * from "./types/JrpcPermissions"; -export * from "./types/JrpcPermission"; -export * from "./types/LeaderFee"; -export * from "./types/LockFlag"; -export * from "./types/LogEntry"; -export * from "./types/LogLevel"; -export * from "./types/Metadata"; -export * from "./types/NetworkCommitteeInfo"; -export * from "./types/NodeHeight"; -export * from "./types/NonFungibleAddressContents"; -export * from "./types/NonFungibleAddress"; -export * from "./types/NonFungibleContainer"; -export * from "./types/NonFungibleId"; -export * from "./types/NonFungibleIndexAddress"; -export * from "./types/NonFungibleIndex"; -export * from "./types/NonFungibleToken"; -export * from "./types/NonFungible"; -export * from "./types/NumPreshards"; -export * from "./types/Ordering"; -export * from "./types/OwnerRule"; -export * from "./types/PeerAddress"; -export * from "./types/ProofId"; -export * from "./types/QuorumCertificate"; -export * from "./types/QuorumDecision"; -export * from "./types/RejectReason"; -export * from "./types/RequireRule"; -export * from "./types/ResourceAccessRules"; -export * from "./types/ResourceAddress"; -export * from "./types/ResourceContainer"; -export * from "./types/Resource"; -export * from "./types/ResourceType"; -export * from "./types/RestrictedAccessRule"; -export * from "./types/RuleRequirement"; -export * from "./types/ShardEvidence"; -export * from "./types/ShardGroup"; -export * from "./types/Shard"; -export * from "./types/SubstateAddress"; -export * from "./types/SubstateDestroyed"; -export * from "./types/SubstateDiff"; -export * from "./types/SubstateId"; -export * from "./types/SubstateLockFlag"; -export * from "./types/SubstateRecord"; -export * from "./types/SubstateRequirement"; -export * from "./types/Substate"; -export * from "./types/SubstateType"; -export * from "./types/SubstateValue"; -export * from "./types/TemplateDef"; -export * from "./types/TemplateDefV1"; -export * from "./types/TransactionAtom"; -export * from "./types/TransactionPoolRecord"; -export * from "./types/TransactionPoolStage"; -export * from "./types/TransactionReceiptAddress"; -export * from "./types/TransactionReceipt"; -export * from "./types/TransactionResult"; -export * from "./types/TransactionSignature"; -export * from "./types/TransactionStatus"; -export * from "./types/Transaction"; -export * from "./types/Type"; -export * from "./types/UnclaimedConfidentialOutput"; -export * from "./types/UnsignedTransaction"; -export * from "./types/ValidatorSignature"; -export * from "./types/VaultId"; -export * from "./types/Vault"; -export * from "./types/VersionedSubstateIdLockIntent"; -export * from "./types/VersionedSubstateId"; -export * from "./types/ViewableBalanceProof"; -export * from "./base-node-client"; -export * from "./tari-indexer-client"; -export * from "./validator-node-client"; -export * from "./wallet-daemon-client"; -export * from "./helpers/helpers"; -export * from "./types/AccessRule"; -export * from "./types/Account"; -export * from "./types/Amount"; -export * from "./types/ArgDef"; -export * from "./types/Arg"; -export * from "./types/AuthHook"; -export * from "./types/Block"; -export * from "./types/BucketId"; -export * from "./types/Claims"; -export * from "./types/Command"; -export * from "./types/CommitteeInfo"; -export * from "./types/CommitteeShardInfo"; -export * from "./types/Committee"; -export * from "./types/ComponentAccessRules"; -export * from "./types/ComponentAddress"; -export * from "./types/ComponentBody"; -export * from "./types/ComponentHeader"; -export * from "./types/ComponentKey"; -export * from "./types/ConfidentialClaim"; -export * from "./types/ConfidentialOutputStatement"; -export * from "./types/ConfidentialOutput"; -export * from "./types/ConfidentialStatement"; -export * from "./types/ConfidentialTransferInputSelection"; -export * from "./types/ConfidentialWithdrawProof"; -export * from "./types/Decision"; -export * from "./types/ElgamalVerifiableBalance"; -export * from "./types/EntityId"; -export * from "./types/Epoch"; -export * from "./types/Event"; -export * from "./types/Evidence"; -export * from "./types/ExecutedTransaction"; -export * from "./types/ExecuteResult"; -export * from "./types/FeeBreakdown"; -export * from "./types/FeeClaimAddress"; -export * from "./types/FeeClaim"; -export * from "./types/FeeCostBreakdown"; -export * from "./types/FeeReceipt"; -export * from "./types/FeeSource"; -export * from "./types/FinalizeResult"; -export * from "./types/ForeignProposalState"; -export * from "./types/ForeignProposal"; -export * from "./types/FunctionDef"; -export * from "./types/IndexedValue"; -export * from "./types/IndexedWellKnownTypes"; -export * from "./types/InstructionResult"; -export * from "./types/Instruction"; -export * from "./types/JrpcPermissions"; -export * from "./types/JrpcPermission"; -export * from "./types/LeaderFee"; -export * from "./types/LockFlag"; -export * from "./types/LogEntry"; -export * from "./types/LogLevel"; -export * from "./types/Metadata"; -export * from "./types/NetworkCommitteeInfo"; -export * from "./types/NodeHeight"; -export * from "./types/NonFungibleAddressContents"; -export * from "./types/NonFungibleAddress"; -export * from "./types/NonFungibleContainer"; -export * from "./types/NonFungibleId"; -export * from "./types/NonFungibleIndexAddress"; -export * from "./types/NonFungibleIndex"; -export * from "./types/NonFungibleToken"; -export * from "./types/NonFungible"; -export * from "./types/NumPreshards"; -export * from "./types/Ordering"; -export * from "./types/OwnerRule"; -export * from "./types/PeerAddress"; -export * from "./types/ProofId"; -export * from "./types/QuorumCertificate"; -export * from "./types/QuorumDecision"; -export * from "./types/RejectReason"; -export * from "./types/RequireRule"; -export * from "./types/ResourceAccessRules"; -export * from "./types/ResourceAddress"; -export * from "./types/ResourceContainer"; -export * from "./types/Resource"; -export * from "./types/ResourceType"; -export * from "./types/RestrictedAccessRule"; -export * from "./types/RuleRequirement"; -export * from "./types/ShardEvidence"; -export * from "./types/ShardGroup"; -export * from "./types/Shard"; -export * from "./types/SubstateAddress"; -export * from "./types/SubstateDestroyed"; -export * from "./types/SubstateDiff"; -export * from "./types/SubstateId"; -export * from "./types/SubstateLockFlag"; -export * from "./types/SubstateRecord"; -export * from "./types/SubstateRequirement"; -export * from "./types/Substate"; -export * from "./types/SubstateType"; -export * from "./types/SubstateValue"; -export * from "./types/TemplateDef"; -export * from "./types/TemplateDefV1"; -export * from "./types/TransactionAtom"; -export * from "./types/TransactionPoolRecord"; -export * from "./types/TransactionPoolStage"; -export * from "./types/TransactionReceiptAddress"; -export * from "./types/TransactionReceipt"; -export * from "./types/TransactionResult"; -export * from "./types/TransactionSignature"; -export * from "./types/TransactionStatus"; -export * from "./types/Transaction"; -export * from "./types/Type"; -export * from "./types/UnclaimedConfidentialOutput"; -export * from "./types/UnsignedTransaction"; -export * from "./types/ValidatorSignature"; -export * from "./types/VaultId"; -export * from "./types/Vault"; -export * from "./types/VersionedSubstateIdLockIntent"; -export * from "./types/VersionedSubstateId"; -export * from "./types/ViewableBalanceProof"; -export * from "./base-node-client"; -export * from "./tari-indexer-client"; -export * from "./validator-node-client"; -export * from "./wallet-daemon-client"; -export * from "./helpers/helpers"; -export * from "./types/AccessRule"; -export * from "./types/Account"; -export * from "./types/Amount"; -export * from "./types/ArgDef"; -export * from "./types/Arg"; -export * from "./types/AuthHook"; -export * from "./types/Block"; -export * from "./types/BucketId"; -export * from "./types/Claims"; -export * from "./types/Command"; -export * from "./types/CommitteeInfo"; -export * from "./types/CommitteeShardInfo"; -export * from "./types/Committee"; -export * from "./types/ComponentAccessRules"; -export * from "./types/ComponentAddress"; -export * from "./types/ComponentBody"; -export * from "./types/ComponentHeader"; -export * from "./types/ComponentKey"; -export * from "./types/ConfidentialClaim"; -export * from "./types/ConfidentialOutputStatement"; -export * from "./types/ConfidentialOutput"; -export * from "./types/ConfidentialStatement"; -export * from "./types/ConfidentialTransferInputSelection"; -export * from "./types/ConfidentialWithdrawProof"; -export * from "./types/Decision"; -export * from "./types/ElgamalVerifiableBalance"; -export * from "./types/EntityId"; -export * from "./types/Epoch"; -export * from "./types/Event"; -export * from "./types/Evidence"; -export * from "./types/ExecutedTransaction"; -export * from "./types/ExecuteResult"; -export * from "./types/FeeBreakdown"; -export * from "./types/FeeClaimAddress"; -export * from "./types/FeeClaim"; -export * from "./types/FeeCostBreakdown"; -export * from "./types/FeeReceipt"; -export * from "./types/FeeSource"; -export * from "./types/FinalizeResult"; -export * from "./types/ForeignProposalState"; -export * from "./types/ForeignProposal"; -export * from "./types/FunctionDef"; -export * from "./types/IndexedValue"; -export * from "./types/IndexedWellKnownTypes"; -export * from "./types/InstructionResult"; -export * from "./types/Instruction"; -export * from "./types/JrpcPermissions"; -export * from "./types/JrpcPermission"; -export * from "./types/LeaderFee"; -export * from "./types/LockFlag"; -export * from "./types/LogEntry"; -export * from "./types/LogLevel"; -export * from "./types/Metadata"; -export * from "./types/NetworkCommitteeInfo"; -export * from "./types/NodeHeight"; -export * from "./types/NonFungibleAddressContents"; -export * from "./types/NonFungibleAddress"; -export * from "./types/NonFungibleContainer"; -export * from "./types/NonFungibleId"; -export * from "./types/NonFungibleIndexAddress"; -export * from "./types/NonFungibleIndex"; -export * from "./types/NonFungibleToken"; -export * from "./types/NonFungible"; -export * from "./types/NumPreshards"; -export * from "./types/Ordering"; -export * from "./types/OwnerRule"; -export * from "./types/PeerAddress"; -export * from "./types/ProofId"; -export * from "./types/QuorumCertificate"; -export * from "./types/QuorumDecision"; -export * from "./types/RejectReason"; -export * from "./types/RequireRule"; -export * from "./types/ResourceAccessRules"; -export * from "./types/ResourceAddress"; -export * from "./types/ResourceContainer"; -export * from "./types/Resource"; -export * from "./types/ResourceType"; -export * from "./types/RestrictedAccessRule"; -export * from "./types/RuleRequirement"; -export * from "./types/ShardEvidence"; -export * from "./types/ShardGroup"; -export * from "./types/Shard"; -export * from "./types/SubstateAddress"; -export * from "./types/SubstateDestroyed"; -export * from "./types/SubstateDiff"; -export * from "./types/SubstateId"; -export * from "./types/SubstateLockFlag"; -export * from "./types/SubstateLockType"; -export * from "./types/SubstateRecord"; -export * from "./types/SubstateRequirement"; -export * from "./types/Substate"; -export * from "./types/SubstateType"; -export * from "./types/SubstateValue"; -export * from "./types/TemplateDef"; -export * from "./types/TemplateDefV1"; -export * from "./types/TransactionAtom"; -export * from "./types/TransactionPoolRecord"; -export * from "./types/TransactionPoolStage"; -export * from "./types/TransactionReceiptAddress"; -export * from "./types/TransactionReceipt"; -export * from "./types/TransactionResult"; -export * from "./types/TransactionSignature"; -export * from "./types/TransactionStatus"; -export * from "./types/Transaction"; -export * from "./types/Type"; -export * from "./types/UnclaimedConfidentialOutput"; -export * from "./types/UnsignedTransaction"; -export * from "./types/ValidatorSignature"; -export * from "./types/VaultId"; -export * from "./types/Vault"; -export * from "./types/VersionedSubstateIdLockIntent"; -export * from "./types/VersionedSubstateId"; -export * from "./types/ViewableBalanceProof"; -export * from "./base-node-client"; -export * from "./tari-indexer-client"; -export * from "./validator-node-client"; -export * from "./wallet-daemon-client"; -export * from "./helpers/helpers"; -export * from "./types/AccessRule"; -export * from "./types/Account"; -export * from "./types/Amount"; -export * from "./types/ArgDef"; -export * from "./types/Arg"; -export * from "./types/AuthHook"; -export * from "./types/Block"; -export * from "./types/BucketId"; -export * from "./types/Claims"; -export * from "./types/Command"; -export * from "./types/CommitteeInfo"; -export * from "./types/CommitteeShardInfo"; -export * from "./types/Committee"; -export * from "./types/ComponentAccessRules"; -export * from "./types/ComponentAddress"; -export * from "./types/ComponentBody"; -export * from "./types/ComponentHeader"; -export * from "./types/ComponentKey"; -export * from "./types/ConfidentialClaim"; -export * from "./types/ConfidentialOutputStatement"; -export * from "./types/ConfidentialOutput"; -export * from "./types/ConfidentialStatement"; -export * from "./types/ConfidentialTransferInputSelection"; -export * from "./types/ConfidentialWithdrawProof"; -export * from "./types/Decision"; -export * from "./types/ElgamalVerifiableBalance"; -export * from "./types/EntityId"; -export * from "./types/Epoch"; -export * from "./types/Event"; -export * from "./types/Evidence"; -export * from "./types/ExecutedTransaction"; -export * from "./types/ExecuteResult"; -export * from "./types/FeeBreakdown"; -export * from "./types/FeeClaimAddress"; -export * from "./types/FeeClaim"; -export * from "./types/FeeCostBreakdown"; -export * from "./types/FeeReceipt"; -export * from "./types/FeeSource"; -export * from "./types/FinalizeResult"; -export * from "./types/ForeignProposalState"; -export * from "./types/ForeignProposal"; -export * from "./types/FunctionDef"; -export * from "./types/IndexedValue"; -export * from "./types/IndexedWellKnownTypes"; -export * from "./types/InstructionResult"; -export * from "./types/Instruction"; -export * from "./types/JrpcPermissions"; -export * from "./types/JrpcPermission"; -export * from "./types/LeaderFee"; -export * from "./types/LockFlag"; -export * from "./types/LogEntry"; -export * from "./types/LogLevel"; -export * from "./types/Metadata"; -export * from "./types/NetworkCommitteeInfo"; -export * from "./types/NodeHeight"; -export * from "./types/NonFungibleAddressContents"; -export * from "./types/NonFungibleAddress"; -export * from "./types/NonFungibleContainer"; -export * from "./types/NonFungibleId"; -export * from "./types/NonFungibleIndexAddress"; -export * from "./types/NonFungibleIndex"; -export * from "./types/NonFungibleToken"; -export * from "./types/NonFungible"; -export * from "./types/NumPreshards"; -export * from "./types/Ordering"; -export * from "./types/OwnerRule"; -export * from "./types/PeerAddress"; -export * from "./types/ProofId"; -export * from "./types/QuorumCertificate"; -export * from "./types/QuorumDecision"; -export * from "./types/RejectReason"; -export * from "./types/RequireRule"; -export * from "./types/ResourceAccessRules"; -export * from "./types/ResourceAddress"; -export * from "./types/ResourceContainer"; -export * from "./types/Resource"; -export * from "./types/ResourceType"; -export * from "./types/RestrictedAccessRule"; -export * from "./types/RuleRequirement"; -export * from "./types/ShardEvidence"; -export * from "./types/ShardGroup"; -export * from "./types/Shard"; -export * from "./types/SubstateAddress"; -export * from "./types/SubstateDestroyed"; -export * from "./types/SubstateDiff"; -export * from "./types/SubstateId"; -export * from "./types/SubstateLockFlag"; -export * from "./types/SubstateLockType"; -export * from "./types/SubstateRecord"; -export * from "./types/SubstateRequirement"; -export * from "./types/Substate"; -export * from "./types/SubstateType"; -export * from "./types/SubstateValue"; -export * from "./types/TemplateDef"; -export * from "./types/TemplateDefV1"; -export * from "./types/TransactionAtom"; -export * from "./types/TransactionPoolRecord"; -export * from "./types/TransactionPoolStage"; -export * from "./types/TransactionReceiptAddress"; -export * from "./types/TransactionReceipt"; -export * from "./types/TransactionResult"; -export * from "./types/TransactionSignature"; -export * from "./types/TransactionStatus"; -export * from "./types/Transaction"; -export * from "./types/Type"; -export * from "./types/UnclaimedConfidentialOutput"; -export * from "./types/UnsignedTransaction"; -export * from "./types/ValidatorSignature"; -export * from "./types/VaultId"; -export * from "./types/Vault"; -export * from "./types/VersionedSubstateIdLockIntent"; -export * from "./types/VersionedSubstateId"; -export * from "./types/ViewableBalanceProof"; -export * from "./base-node-client"; -export * from "./tari-indexer-client"; -export * from "./validator-node-client"; -export * from "./wallet-daemon-client"; -export * from "./helpers/helpers"; -export * from "./types/AccessRule"; -export * from "./types/Account"; -export * from "./types/Amount"; -export * from "./types/ArgDef"; -export * from "./types/Arg"; -export * from "./types/AuthHook"; -export * from "./types/Block"; -export * from "./types/BucketId"; -export * from "./types/Claims"; -export * from "./types/Command"; -export * from "./types/CommitteeInfo"; -export * from "./types/CommitteeShardInfo"; -export * from "./types/Committee"; -export * from "./types/ComponentAccessRules"; -export * from "./types/ComponentAddress"; -export * from "./types/ComponentBody"; -export * from "./types/ComponentHeader"; -export * from "./types/ComponentKey"; -export * from "./types/ConfidentialClaim"; -export * from "./types/ConfidentialOutputStatement"; -export * from "./types/ConfidentialOutput"; -export * from "./types/ConfidentialStatement"; -export * from "./types/ConfidentialTransferInputSelection"; -export * from "./types/ConfidentialWithdrawProof"; -export * from "./types/Decision"; -export * from "./types/ElgamalVerifiableBalance"; -export * from "./types/EntityId"; -export * from "./types/Epoch"; -export * from "./types/Event"; -export * from "./types/Evidence"; -export * from "./types/ExecutedTransaction"; -export * from "./types/ExecuteResult"; -export * from "./types/FeeBreakdown"; -export * from "./types/FeeClaimAddress"; -export * from "./types/FeeClaim"; -export * from "./types/FeeCostBreakdown"; -export * from "./types/FeeReceipt"; -export * from "./types/FeeSource"; -export * from "./types/FinalizeResult"; -export * from "./types/ForeignProposalState"; -export * from "./types/ForeignProposal"; -export * from "./types/FunctionDef"; -export * from "./types/IndexedValue"; -export * from "./types/IndexedWellKnownTypes"; -export * from "./types/InstructionResult"; -export * from "./types/Instruction"; -export * from "./types/JrpcPermissions"; -export * from "./types/JrpcPermission"; -export * from "./types/LeaderFee"; -export * from "./types/LockFlag"; -export * from "./types/LogEntry"; -export * from "./types/LogLevel"; -export * from "./types/Metadata"; -export * from "./types/NetworkCommitteeInfo"; -export * from "./types/NodeHeight"; -export * from "./types/NonFungibleAddressContents"; -export * from "./types/NonFungibleAddress"; -export * from "./types/NonFungibleContainer"; -export * from "./types/NonFungibleId"; -export * from "./types/NonFungibleIndexAddress"; -export * from "./types/NonFungibleIndex"; -export * from "./types/NonFungibleToken"; -export * from "./types/NonFungible"; -export * from "./types/NumPreshards"; -export * from "./types/Ordering"; -export * from "./types/OwnerRule"; -export * from "./types/PeerAddress"; -export * from "./types/ProofId"; -export * from "./types/QuorumCertificate"; -export * from "./types/QuorumDecision"; -export * from "./types/RejectReason"; -export * from "./types/RequireRule"; -export * from "./types/ResourceAccessRules"; -export * from "./types/ResourceAddress"; -export * from "./types/ResourceContainer"; -export * from "./types/Resource"; -export * from "./types/ResourceType"; -export * from "./types/RestrictedAccessRule"; -export * from "./types/RuleRequirement"; -export * from "./types/ShardEvidence"; -export * from "./types/ShardGroup"; -export * from "./types/Shard"; -export * from "./types/SubstateAddress"; -export * from "./types/SubstateDestroyed"; -export * from "./types/SubstateDiff"; -export * from "./types/SubstateId"; -export * from "./types/SubstateLockFlag"; -export * from "./types/SubstateLockType"; -export * from "./types/SubstateRecord"; -export * from "./types/SubstateRequirement"; -export * from "./types/Substate"; -export * from "./types/SubstateType"; -export * from "./types/SubstateValue"; -export * from "./types/TemplateDef"; -export * from "./types/TemplateDefV1"; -export * from "./types/TransactionAtom"; -export * from "./types/TransactionPoolRecord"; -export * from "./types/TransactionPoolStage"; -export * from "./types/TransactionReceiptAddress"; -export * from "./types/TransactionReceipt"; -export * from "./types/TransactionResult"; -export * from "./types/TransactionSignature"; -export * from "./types/TransactionStatus"; -export * from "./types/Transaction"; -export * from "./types/Type"; -export * from "./types/UnclaimedConfidentialOutput"; -export * from "./types/UnsignedTransaction"; -export * from "./types/ValidatorSignature"; -export * from "./types/VaultId"; -export * from "./types/Vault"; -export * from "./types/VersionedSubstateIdLockIntent"; -export * from "./types/VersionedSubstateId"; -export * from "./types/ViewableBalanceProof"; -export * from "./base-node-client"; -export * from "./tari-indexer-client"; -export * from "./validator-node-client"; -export * from "./wallet-daemon-client"; -export * from "./helpers/helpers"; -export * from "./types/AccessRule"; -export * from "./types/Account"; -export * from "./types/Amount"; -export * from "./types/ArgDef"; -export * from "./types/Arg"; -export * from "./types/AuthHook"; -export * from "./types/Block"; -export * from "./types/BucketId"; -export * from "./types/Claims"; -export * from "./types/Command"; -export * from "./types/CommitteeInfo"; -export * from "./types/CommitteeShardInfo"; -export * from "./types/Committee"; -export * from "./types/ComponentAccessRules"; -export * from "./types/ComponentAddress"; -export * from "./types/ComponentBody"; -export * from "./types/ComponentHeader"; -export * from "./types/ComponentKey"; -export * from "./types/ConfidentialClaim"; -export * from "./types/ConfidentialOutputStatement"; -export * from "./types/ConfidentialOutput"; -export * from "./types/ConfidentialStatement"; -export * from "./types/ConfidentialTransferInputSelection"; -export * from "./types/ConfidentialWithdrawProof"; -export * from "./types/Decision"; -export * from "./types/ElgamalVerifiableBalance"; -export * from "./types/EntityId"; -export * from "./types/Epoch"; -export * from "./types/Event"; -export * from "./types/Evidence"; -export * from "./types/ExecutedTransaction"; -export * from "./types/ExecuteResult"; -export * from "./types/FeeBreakdown"; -export * from "./types/FeeClaimAddress"; -export * from "./types/FeeClaim"; -export * from "./types/FeeCostBreakdown"; -export * from "./types/FeeReceipt"; -export * from "./types/FeeSource"; -export * from "./types/FinalizeResult"; -export * from "./types/ForeignProposalAtom"; -export * from "./types/ForeignProposalState"; -export * from "./types/ForeignProposal"; -export * from "./types/FunctionDef"; -export * from "./types/IndexedValue"; -export * from "./types/IndexedWellKnownTypes"; -export * from "./types/InstructionResult"; -export * from "./types/Instruction"; -export * from "./types/JrpcPermissions"; -export * from "./types/JrpcPermission"; -export * from "./types/LeaderFee"; -export * from "./types/LockFlag"; -export * from "./types/LogEntry"; -export * from "./types/LogLevel"; -export * from "./types/Metadata"; -export * from "./types/NetworkCommitteeInfo"; -export * from "./types/NodeHeight"; -export * from "./types/NonFungibleAddressContents"; -export * from "./types/NonFungibleAddress"; -export * from "./types/NonFungibleContainer"; -export * from "./types/NonFungibleId"; -export * from "./types/NonFungibleIndexAddress"; -export * from "./types/NonFungibleIndex"; -export * from "./types/NonFungibleToken"; -export * from "./types/NonFungible"; -export * from "./types/NumPreshards"; -export * from "./types/Ordering"; -export * from "./types/OwnerRule"; -export * from "./types/PeerAddress"; -export * from "./types/ProofId"; -export * from "./types/QuorumCertificate"; -export * from "./types/QuorumDecision"; -export * from "./types/RejectReason"; -export * from "./types/RequireRule"; -export * from "./types/ResourceAccessRules"; -export * from "./types/ResourceAddress"; -export * from "./types/ResourceContainer"; -export * from "./types/Resource"; -export * from "./types/ResourceType"; -export * from "./types/RestrictedAccessRule"; -export * from "./types/RuleRequirement"; -export * from "./types/ShardEvidence"; -export * from "./types/ShardGroup"; -export * from "./types/Shard"; -export * from "./types/SubstateAddress"; -export * from "./types/SubstateDestroyed"; -export * from "./types/SubstateDiff"; -export * from "./types/SubstateId"; -export * from "./types/SubstateLockFlag"; -export * from "./types/SubstateLockType"; -export * from "./types/SubstateRecord"; -export * from "./types/SubstateRequirement"; -export * from "./types/Substate"; -export * from "./types/SubstateType"; -export * from "./types/SubstateValue"; -export * from "./types/TemplateDef"; -export * from "./types/TemplateDefV1"; -export * from "./types/TransactionAtom"; -export * from "./types/TransactionPoolRecord"; -export * from "./types/TransactionPoolStage"; -export * from "./types/TransactionReceiptAddress"; -export * from "./types/TransactionReceipt"; -export * from "./types/TransactionResult"; -export * from "./types/TransactionSignature"; -export * from "./types/TransactionStatus"; -export * from "./types/Transaction"; -export * from "./types/Type"; -export * from "./types/UnclaimedConfidentialOutput"; -export * from "./types/UnsignedTransaction"; -export * from "./types/ValidatorSignature"; -export * from "./types/VaultId"; -export * from "./types/Vault"; -export * from "./types/VersionedSubstateIdLockIntent"; -export * from "./types/VersionedSubstateId"; -export * from "./types/ViewableBalanceProof"; -export * from "./base-node-client"; -export * from "./tari-indexer-client"; -export * from "./validator-node-client"; -export * from "./wallet-daemon-client"; -export * from "./helpers/helpers"; -export * from "./types/AccessRule"; -export * from "./types/Account"; -export * from "./types/Amount"; -export * from "./types/ArgDef"; -export * from "./types/Arg"; -export * from "./types/AuthHook"; -export * from "./types/Block"; -export * from "./types/BucketId"; -export * from "./types/Claims"; -export * from "./types/Command"; -export * from "./types/CommitteeInfo"; -export * from "./types/CommitteeShardInfo"; -export * from "./types/Committee"; -export * from "./types/ComponentAccessRules"; -export * from "./types/ComponentAddress"; -export * from "./types/ComponentBody"; -export * from "./types/ComponentHeader"; -export * from "./types/ComponentKey"; -export * from "./types/ConfidentialClaim"; -export * from "./types/ConfidentialOutputStatement"; -export * from "./types/ConfidentialOutput"; -export * from "./types/ConfidentialStatement"; -export * from "./types/ConfidentialTransferInputSelection"; -export * from "./types/ConfidentialWithdrawProof"; -export * from "./types/Decision"; -export * from "./types/ElgamalVerifiableBalance"; -export * from "./types/EntityId"; -export * from "./types/Epoch"; -export * from "./types/Event"; -export * from "./types/Evidence"; -export * from "./types/ExecutedTransaction"; -export * from "./types/ExecuteResult"; -export * from "./types/FeeBreakdown"; -export * from "./types/FeeClaimAddress"; -export * from "./types/FeeClaim"; -export * from "./types/FeeCostBreakdown"; -export * from "./types/FeeReceipt"; -export * from "./types/FeeSource"; -export * from "./types/FinalizeResult"; -export * from "./types/ForeignProposalAtom"; -export * from "./types/ForeignProposalState"; -export * from "./types/ForeignProposal"; -export * from "./types/FunctionDef"; -export * from "./types/IndexedValue"; -export * from "./types/IndexedWellKnownTypes"; -export * from "./types/InstructionResult"; -export * from "./types/Instruction"; -export * from "./types/JrpcPermissions"; -export * from "./types/JrpcPermission"; -export * from "./types/LeaderFee"; -export * from "./types/LockFlag"; -export * from "./types/LogEntry"; -export * from "./types/LogLevel"; -export * from "./types/Metadata"; -export * from "./types/NetworkCommitteeInfo"; -export * from "./types/NodeHeight"; -export * from "./types/NonFungibleAddressContents"; -export * from "./types/NonFungibleAddress"; -export * from "./types/NonFungibleContainer"; -export * from "./types/NonFungibleId"; -export * from "./types/NonFungibleIndexAddress"; -export * from "./types/NonFungibleIndex"; -export * from "./types/NonFungibleToken"; -export * from "./types/NonFungible"; -export * from "./types/NumPreshards"; -export * from "./types/Ordering"; -export * from "./types/OwnerRule"; -export * from "./types/PeerAddress"; -export * from "./types/ProofId"; -export * from "./types/QuorumCertificate"; -export * from "./types/QuorumDecision"; -export * from "./types/RejectReason"; -export * from "./types/RequireRule"; -export * from "./types/ResourceAccessRules"; -export * from "./types/ResourceAddress"; -export * from "./types/ResourceContainer"; -export * from "./types/Resource"; -export * from "./types/ResourceType"; -export * from "./types/RestrictedAccessRule"; -export * from "./types/RuleRequirement"; -export * from "./types/ShardEvidence"; -export * from "./types/ShardGroup"; -export * from "./types/Shard"; -export * from "./types/SubstateAddress"; -export * from "./types/SubstateDestroyed"; -export * from "./types/SubstateDiff"; -export * from "./types/SubstateId"; -export * from "./types/SubstateLockFlag"; -export * from "./types/SubstateLockType"; -export * from "./types/SubstateRecord"; -export * from "./types/SubstateRequirement"; -export * from "./types/Substate"; -export * from "./types/SubstateType"; -export * from "./types/SubstateValue"; -export * from "./types/TemplateDef"; -export * from "./types/TemplateDefV1"; -export * from "./types/TransactionAtom"; -export * from "./types/TransactionPoolRecord"; -export * from "./types/TransactionPoolStage"; -export * from "./types/TransactionReceiptAddress"; -export * from "./types/TransactionReceipt"; -export * from "./types/TransactionResult"; -export * from "./types/TransactionSignature"; -export * from "./types/TransactionStatus"; -export * from "./types/Transaction"; -export * from "./types/Type"; -export * from "./types/UnclaimedConfidentialOutput"; -export * from "./types/UnsignedTransaction"; -export * from "./types/ValidatorSignature"; -export * from "./types/VaultId"; -export * from "./types/Vault"; -export * from "./types/VersionedSubstateIdLockIntent"; -export * from "./types/VersionedSubstateId"; -export * from "./types/ViewableBalanceProof"; -export * from "./base-node-client"; -export * from "./tari-indexer-client"; -export * from "./validator-node-client"; -export * from "./wallet-daemon-client"; -export * from "./helpers/helpers"; -export * from "./types/AccessRule"; -export * from "./types/Account"; -export * from "./types/Amount"; -export * from "./types/ArgDef"; -export * from "./types/Arg"; -export * from "./types/AuthHook"; -export * from "./types/Block"; -export * from "./types/BucketId"; -export * from "./types/Claims"; -export * from "./types/Command"; -export * from "./types/CommitteeInfo"; -export * from "./types/CommitteeShardInfo"; -export * from "./types/Committee"; -export * from "./types/ComponentAccessRules"; -export * from "./types/ComponentAddress"; -export * from "./types/ComponentBody"; -export * from "./types/ComponentHeader"; -export * from "./types/ComponentKey"; -export * from "./types/ConfidentialClaim"; -export * from "./types/ConfidentialOutputStatement"; -export * from "./types/ConfidentialOutput"; -export * from "./types/ConfidentialStatement"; -export * from "./types/ConfidentialTransferInputSelection"; -export * from "./types/ConfidentialWithdrawProof"; -export * from "./types/Decision"; -export * from "./types/ElgamalVerifiableBalance"; -export * from "./types/EntityId"; -export * from "./types/Epoch"; -export * from "./types/Event"; -export * from "./types/Evidence"; -export * from "./types/ExecutedTransaction"; -export * from "./types/ExecuteResult"; -export * from "./types/FeeBreakdown"; -export * from "./types/FeeClaimAddress"; -export * from "./types/FeeClaim"; -export * from "./types/FeeCostBreakdown"; -export * from "./types/FeeReceipt"; -export * from "./types/FeeSource"; -export * from "./types/FinalizeResult"; -export * from "./types/ForeignProposalAtom"; -export * from "./types/ForeignProposalState"; -export * from "./types/ForeignProposal"; -export * from "./types/FunctionDef"; -export * from "./types/IndexedValue"; -export * from "./types/IndexedWellKnownTypes"; -export * from "./types/InstructionResult"; -export * from "./types/Instruction"; -export * from "./types/JrpcPermissions"; -export * from "./types/JrpcPermission"; -export * from "./types/LeaderFee"; -export * from "./types/LockFlag"; -export * from "./types/LogEntry"; -export * from "./types/LogLevel"; -export * from "./types/Metadata"; -export * from "./types/MintConfidentialOutputAtom"; -export * from "./types/NetworkCommitteeInfo"; -export * from "./types/NodeHeight"; -export * from "./types/NonFungibleAddressContents"; -export * from "./types/NonFungibleAddress"; -export * from "./types/NonFungibleContainer"; -export * from "./types/NonFungibleId"; -export * from "./types/NonFungibleIndexAddress"; -export * from "./types/NonFungibleIndex"; -export * from "./types/NonFungibleToken"; -export * from "./types/NonFungible"; -export * from "./types/NumPreshards"; -export * from "./types/Ordering"; -export * from "./types/OwnerRule"; -export * from "./types/PeerAddress"; -export * from "./types/ProofId"; -export * from "./types/QuorumCertificate"; -export * from "./types/QuorumDecision"; -export * from "./types/RejectReason"; -export * from "./types/RequireRule"; -export * from "./types/ResourceAccessRules"; -export * from "./types/ResourceAddress"; -export * from "./types/ResourceContainer"; -export * from "./types/Resource"; -export * from "./types/ResourceType"; -export * from "./types/RestrictedAccessRule"; -export * from "./types/RuleRequirement"; -export * from "./types/ShardEvidence"; -export * from "./types/ShardGroup"; -export * from "./types/Shard"; -export * from "./types/SubstateAddress"; -export * from "./types/SubstateDestroyed"; -export * from "./types/SubstateDiff"; -export * from "./types/SubstateId"; -export * from "./types/SubstateLockFlag"; -export * from "./types/SubstateLockType"; -export * from "./types/SubstateRecord"; -export * from "./types/SubstateRequirement"; -export * from "./types/Substate"; -export * from "./types/SubstateType"; -export * from "./types/SubstateValue"; -export * from "./types/TemplateDef"; -export * from "./types/TemplateDefV1"; -export * from "./types/TransactionAtom"; -export * from "./types/TransactionPoolRecord"; -export * from "./types/TransactionPoolStage"; -export * from "./types/TransactionReceiptAddress"; -export * from "./types/TransactionReceipt"; -export * from "./types/TransactionResult"; -export * from "./types/TransactionSignature"; -export * from "./types/TransactionStatus"; -export * from "./types/Transaction"; -export * from "./types/Type"; -export * from "./types/UnclaimedConfidentialOutput"; -export * from "./types/UnsignedTransaction"; -export * from "./types/ValidatorSignature"; -export * from "./types/VaultId"; -export * from "./types/Vault"; -export * from "./types/VersionedSubstateIdLockIntent"; -export * from "./types/VersionedSubstateId"; -export * from "./types/ViewableBalanceProof"; -export * from "./base-node-client"; -export * from "./tari-indexer-client"; -export * from "./validator-node-client"; -export * from "./wallet-daemon-client"; -export * from "./helpers/helpers"; -export * from "./types/AccessRule"; -export * from "./types/Account"; -export * from "./types/Amount"; -export * from "./types/ArgDef"; -export * from "./types/Arg"; -export * from "./types/AuthHook"; -export * from "./types/Block"; -export * from "./types/BucketId"; -export * from "./types/Claims"; -export * from "./types/Command"; -export * from "./types/CommitteeInfo"; -export * from "./types/CommitteeShardInfo"; -export * from "./types/Committee"; -export * from "./types/ComponentAccessRules"; -export * from "./types/ComponentAddress"; -export * from "./types/ComponentBody"; -export * from "./types/ComponentHeader"; -export * from "./types/ComponentKey"; -export * from "./types/ConfidentialClaim"; -export * from "./types/ConfidentialOutputStatement"; -export * from "./types/ConfidentialOutput"; -export * from "./types/ConfidentialStatement"; -export * from "./types/ConfidentialTransferInputSelection"; -export * from "./types/ConfidentialWithdrawProof"; -export * from "./types/Decision"; -export * from "./types/ElgamalVerifiableBalance"; -export * from "./types/EntityId"; -export * from "./types/Epoch"; -export * from "./types/Event"; -export * from "./types/Evidence"; -export * from "./types/ExecutedTransaction"; -export * from "./types/ExecuteResult"; -export * from "./types/FeeBreakdown"; -export * from "./types/FeeClaimAddress"; -export * from "./types/FeeClaim"; -export * from "./types/FeeCostBreakdown"; -export * from "./types/FeeReceipt"; -export * from "./types/FeeSource"; -export * from "./types/FinalizeResult"; -export * from "./types/ForeignProposalAtom"; -export * from "./types/ForeignProposalState"; -export * from "./types/ForeignProposal"; -export * from "./types/FunctionDef"; -export * from "./types/IndexedValue"; -export * from "./types/IndexedWellKnownTypes"; -export * from "./types/InstructionResult"; -export * from "./types/Instruction"; -export * from "./types/JrpcPermissions"; -export * from "./types/JrpcPermission"; -export * from "./types/LeaderFee"; -export * from "./types/LockFlag"; -export * from "./types/LogEntry"; -export * from "./types/LogLevel"; -export * from "./types/Metadata"; -export * from "./types/MintConfidentialOutputAtom"; -export * from "./types/NetworkCommitteeInfo"; -export * from "./types/NodeHeight"; -export * from "./types/NonFungibleAddressContents"; -export * from "./types/NonFungibleAddress"; -export * from "./types/NonFungibleContainer"; -export * from "./types/NonFungibleId"; -export * from "./types/NonFungibleIndexAddress"; -export * from "./types/NonFungibleIndex"; -export * from "./types/NonFungibleToken"; -export * from "./types/NonFungible"; -export * from "./types/NumPreshards"; -export * from "./types/Ordering"; -export * from "./types/OwnerRule"; -export * from "./types/PeerAddress"; -export * from "./types/ProofId"; -export * from "./types/QuorumCertificate"; -export * from "./types/QuorumDecision"; -export * from "./types/RejectReason"; -export * from "./types/RequireRule"; -export * from "./types/ResourceAccessRules"; -export * from "./types/ResourceAddress"; -export * from "./types/ResourceContainer"; -export * from "./types/Resource"; -export * from "./types/ResourceType"; -export * from "./types/RestrictedAccessRule"; -export * from "./types/RuleRequirement"; -export * from "./types/ShardEvidence"; -export * from "./types/ShardGroup"; -export * from "./types/Shard"; -export * from "./types/SubstateAddress"; -export * from "./types/SubstateDestroyed"; -export * from "./types/SubstateDiff"; -export * from "./types/SubstateId"; -export * from "./types/SubstateLockFlag"; -export * from "./types/SubstateLockType"; -export * from "./types/SubstateRecord"; -export * from "./types/SubstateRequirement"; -export * from "./types/Substate"; -export * from "./types/SubstateType"; -export * from "./types/SubstateValue"; -export * from "./types/TemplateDef"; -export * from "./types/TemplateDefV1"; -export * from "./types/TransactionAtom"; -export * from "./types/TransactionPoolRecord"; -export * from "./types/TransactionPoolStage"; -export * from "./types/TransactionReceiptAddress"; -export * from "./types/TransactionReceipt"; -export * from "./types/TransactionResult"; -export * from "./types/TransactionSignature"; -export * from "./types/TransactionStatus"; -export * from "./types/Transaction"; -export * from "./types/Type"; -export * from "./types/UnclaimedConfidentialOutputAddress"; -export * from "./types/UnclaimedConfidentialOutput"; -export * from "./types/UnsignedTransaction"; -export * from "./types/ValidatorSignature"; -export * from "./types/VaultId"; -export * from "./types/Vault"; -export * from "./types/VersionedSubstateIdLockIntent"; -export * from "./types/VersionedSubstateId"; -export * from "./types/ViewableBalanceProof"; -export * from "./base-node-client"; -export * from "./tari-indexer-client"; -export * from "./validator-node-client"; -export * from "./wallet-daemon-client"; -export * from "./helpers/helpers"; -export * from "./types/AccessRule"; -export * from "./types/Account"; -export * from "./types/Amount"; -export * from "./types/ArgDef"; -export * from "./types/Arg"; -export * from "./types/AuthHook"; -export * from "./types/Block"; -export * from "./types/BucketId"; -export * from "./types/Claims"; -export * from "./types/Command"; -export * from "./types/CommitteeInfo"; -export * from "./types/CommitteeShardInfo"; -export * from "./types/Committee"; -export * from "./types/ComponentAccessRules"; -export * from "./types/ComponentAddress"; -export * from "./types/ComponentBody"; -export * from "./types/ComponentHeader"; -export * from "./types/ComponentKey"; -export * from "./types/ConfidentialClaim"; -export * from "./types/ConfidentialOutputStatement"; -export * from "./types/ConfidentialOutput"; -export * from "./types/ConfidentialStatement"; -export * from "./types/ConfidentialTransferInputSelection"; -export * from "./types/ConfidentialWithdrawProof"; -export * from "./types/Decision"; -export * from "./types/ElgamalVerifiableBalance"; -export * from "./types/EntityId"; -export * from "./types/Epoch"; -export * from "./types/Event"; -export * from "./types/Evidence"; -export * from "./types/ExecutedTransaction"; -export * from "./types/ExecuteResult"; -export * from "./types/FeeBreakdown"; -export * from "./types/FeeClaimAddress"; -export * from "./types/FeeClaim"; -export * from "./types/FeeCostBreakdown"; -export * from "./types/FeeReceipt"; -export * from "./types/FeeSource"; -export * from "./types/FinalizeResult"; export * from "./types/ForeignProposalAtom"; -export * from "./types/ForeignProposalState"; -export * from "./types/ForeignProposal"; export * from "./types/FunctionDef"; export * from "./types/IndexedValue"; export * from "./types/IndexedWellKnownTypes"; @@ -1153,7 +84,6 @@ export * from "./types/SubstateAddress"; export * from "./types/SubstateDestroyed"; export * from "./types/SubstateDiff"; export * from "./types/SubstateId"; -export * from "./types/SubstateLockFlag"; export * from "./types/SubstateLockType"; export * from "./types/SubstateRecord"; export * from "./types/SubstateRequirement"; diff --git a/bindings/dist/index.js b/bindings/dist/index.js index 78b5f1c1c..703a728be 100644 --- a/bindings/dist/index.js +++ b/bindings/dist/index.js @@ -39,1094 +39,7 @@ export * from "./types/FeeCostBreakdown"; export * from "./types/FeeReceipt"; export * from "./types/FeeSource"; export * from "./types/FinalizeResult"; -export * from "./types/ForeignProposalState"; -export * from "./types/ForeignProposal"; -export * from "./types/FunctionDef"; -export * from "./types/IndexedValue"; -export * from "./types/IndexedWellKnownTypes"; -export * from "./types/InstructionResult"; -export * from "./types/Instruction"; -export * from "./types/JrpcPermissions"; -export * from "./types/JrpcPermission"; -export * from "./types/LeaderFee"; -export * from "./types/LockFlag"; -export * from "./types/LogEntry"; -export * from "./types/LogLevel"; -export * from "./types/Metadata"; -export * from "./types/NetworkCommitteeInfo"; -export * from "./types/NodeHeight"; -export * from "./types/NonFungibleAddressContents"; -export * from "./types/NonFungibleAddress"; -export * from "./types/NonFungibleContainer"; -export * from "./types/NonFungibleId"; -export * from "./types/NonFungibleIndexAddress"; -export * from "./types/NonFungibleIndex"; -export * from "./types/NonFungibleToken"; -export * from "./types/NonFungible"; -export * from "./types/NumPreshards"; -export * from "./types/Ordering"; -export * from "./types/OwnerRule"; -export * from "./types/PeerAddress"; -export * from "./types/ProofId"; -export * from "./types/QuorumCertificate"; -export * from "./types/QuorumDecision"; -export * from "./types/RejectReason"; -export * from "./types/RequireRule"; -export * from "./types/ResourceAccessRules"; -export * from "./types/ResourceAddress"; -export * from "./types/ResourceContainer"; -export * from "./types/Resource"; -export * from "./types/ResourceType"; -export * from "./types/RestrictedAccessRule"; -export * from "./types/RuleRequirement"; -export * from "./types/ShardEvidence"; -export * from "./types/ShardGroup"; -export * from "./types/Shard"; -export * from "./types/SubstateAddress"; -export * from "./types/SubstateDestroyed"; -export * from "./types/SubstateDiff"; -export * from "./types/SubstateId"; -export * from "./types/SubstateLockFlag"; -export * from "./types/SubstateRecord"; -export * from "./types/SubstateRequirement"; -export * from "./types/Substate"; -export * from "./types/SubstateType"; -export * from "./types/SubstateValue"; -export * from "./types/TemplateDef"; -export * from "./types/TemplateDefV1"; -export * from "./types/TransactionAtom"; -export * from "./types/TransactionPoolRecord"; -export * from "./types/TransactionPoolStage"; -export * from "./types/TransactionReceiptAddress"; -export * from "./types/TransactionReceipt"; -export * from "./types/TransactionResult"; -export * from "./types/TransactionSignature"; -export * from "./types/TransactionStatus"; -export * from "./types/Transaction"; -export * from "./types/Type"; -export * from "./types/UnclaimedConfidentialOutput"; -export * from "./types/UnsignedTransaction"; -export * from "./types/ValidatorSignature"; -export * from "./types/VaultId"; -export * from "./types/Vault"; -export * from "./types/VersionedSubstateIdLockIntent"; -export * from "./types/VersionedSubstateId"; -export * from "./types/ViewableBalanceProof"; -export * from "./base-node-client"; -export * from "./tari-indexer-client"; -export * from "./validator-node-client"; -export * from "./wallet-daemon-client"; -export * from "./helpers/helpers"; -// Copyright 2023 The Tari Project -// SPDX-License-Identifier: BSD-3-Clause -export * from "./types/AccessRule"; -export * from "./types/Account"; -export * from "./types/Amount"; -export * from "./types/ArgDef"; -export * from "./types/Arg"; -export * from "./types/AuthHook"; -export * from "./types/Block"; -export * from "./types/BucketId"; -export * from "./types/Claims"; -export * from "./types/Command"; -export * from "./types/CommitteeInfo"; -export * from "./types/CommitteeShardInfo"; -export * from "./types/Committee"; -export * from "./types/ComponentAccessRules"; -export * from "./types/ComponentAddress"; -export * from "./types/ComponentBody"; -export * from "./types/ComponentHeader"; -export * from "./types/ComponentKey"; -export * from "./types/ConfidentialClaim"; -export * from "./types/ConfidentialOutputStatement"; -export * from "./types/ConfidentialOutput"; -export * from "./types/ConfidentialStatement"; -export * from "./types/ConfidentialTransferInputSelection"; -export * from "./types/ConfidentialWithdrawProof"; -export * from "./types/Decision"; -export * from "./types/ElgamalVerifiableBalance"; -export * from "./types/EntityId"; -export * from "./types/Epoch"; -export * from "./types/Event"; -export * from "./types/Evidence"; -export * from "./types/ExecutedTransaction"; -export * from "./types/ExecuteResult"; -export * from "./types/FeeBreakdown"; -export * from "./types/FeeClaimAddress"; -export * from "./types/FeeClaim"; -export * from "./types/FeeCostBreakdown"; -export * from "./types/FeeReceipt"; -export * from "./types/FeeSource"; -export * from "./types/FinalizeResult"; -export * from "./types/ForeignProposalState"; -export * from "./types/ForeignProposal"; -export * from "./types/FunctionDef"; -export * from "./types/IndexedValue"; -export * from "./types/IndexedWellKnownTypes"; -export * from "./types/InstructionResult"; -export * from "./types/Instruction"; -export * from "./types/JrpcPermissions"; -export * from "./types/JrpcPermission"; -export * from "./types/LeaderFee"; -export * from "./types/LockFlag"; -export * from "./types/LogEntry"; -export * from "./types/LogLevel"; -export * from "./types/Metadata"; -export * from "./types/NetworkCommitteeInfo"; -export * from "./types/NodeHeight"; -export * from "./types/NonFungibleAddressContents"; -export * from "./types/NonFungibleAddress"; -export * from "./types/NonFungibleContainer"; -export * from "./types/NonFungibleId"; -export * from "./types/NonFungibleIndexAddress"; -export * from "./types/NonFungibleIndex"; -export * from "./types/NonFungibleToken"; -export * from "./types/NonFungible"; -export * from "./types/NumPreshards"; -export * from "./types/Ordering"; -export * from "./types/OwnerRule"; -export * from "./types/PeerAddress"; -export * from "./types/ProofId"; -export * from "./types/QuorumCertificate"; -export * from "./types/QuorumDecision"; -export * from "./types/RejectReason"; -export * from "./types/RequireRule"; -export * from "./types/ResourceAccessRules"; -export * from "./types/ResourceAddress"; -export * from "./types/ResourceContainer"; -export * from "./types/Resource"; -export * from "./types/ResourceType"; -export * from "./types/RestrictedAccessRule"; -export * from "./types/RuleRequirement"; -export * from "./types/ShardEvidence"; -export * from "./types/ShardGroup"; -export * from "./types/Shard"; -export * from "./types/SubstateAddress"; -export * from "./types/SubstateDestroyed"; -export * from "./types/SubstateDiff"; -export * from "./types/SubstateId"; -export * from "./types/SubstateLockFlag"; -export * from "./types/SubstateRecord"; -export * from "./types/SubstateRequirement"; -export * from "./types/Substate"; -export * from "./types/SubstateType"; -export * from "./types/SubstateValue"; -export * from "./types/TemplateDef"; -export * from "./types/TemplateDefV1"; -export * from "./types/TransactionAtom"; -export * from "./types/TransactionPoolRecord"; -export * from "./types/TransactionPoolStage"; -export * from "./types/TransactionReceiptAddress"; -export * from "./types/TransactionReceipt"; -export * from "./types/TransactionResult"; -export * from "./types/TransactionSignature"; -export * from "./types/TransactionStatus"; -export * from "./types/Transaction"; -export * from "./types/Type"; -export * from "./types/UnclaimedConfidentialOutput"; -export * from "./types/UnsignedTransaction"; -export * from "./types/ValidatorSignature"; -export * from "./types/VaultId"; -export * from "./types/Vault"; -export * from "./types/VersionedSubstateIdLockIntent"; -export * from "./types/VersionedSubstateId"; -export * from "./types/ViewableBalanceProof"; -export * from "./base-node-client"; -export * from "./tari-indexer-client"; -export * from "./validator-node-client"; -export * from "./wallet-daemon-client"; -export * from "./helpers/helpers"; -// Copyright 2023 The Tari Project -// SPDX-License-Identifier: BSD-3-Clause -export * from "./types/AccessRule"; -export * from "./types/Account"; -export * from "./types/Amount"; -export * from "./types/ArgDef"; -export * from "./types/Arg"; -export * from "./types/AuthHook"; -export * from "./types/Block"; -export * from "./types/BucketId"; -export * from "./types/Claims"; -export * from "./types/Command"; -export * from "./types/CommitteeInfo"; -export * from "./types/CommitteeShardInfo"; -export * from "./types/Committee"; -export * from "./types/ComponentAccessRules"; -export * from "./types/ComponentAddress"; -export * from "./types/ComponentBody"; -export * from "./types/ComponentHeader"; -export * from "./types/ComponentKey"; -export * from "./types/ConfidentialClaim"; -export * from "./types/ConfidentialOutputStatement"; -export * from "./types/ConfidentialOutput"; -export * from "./types/ConfidentialStatement"; -export * from "./types/ConfidentialTransferInputSelection"; -export * from "./types/ConfidentialWithdrawProof"; -export * from "./types/Decision"; -export * from "./types/ElgamalVerifiableBalance"; -export * from "./types/EntityId"; -export * from "./types/Epoch"; -export * from "./types/Event"; -export * from "./types/Evidence"; -export * from "./types/ExecutedTransaction"; -export * from "./types/ExecuteResult"; -export * from "./types/FeeBreakdown"; -export * from "./types/FeeClaimAddress"; -export * from "./types/FeeClaim"; -export * from "./types/FeeCostBreakdown"; -export * from "./types/FeeReceipt"; -export * from "./types/FeeSource"; -export * from "./types/FinalizeResult"; -export * from "./types/ForeignProposalState"; -export * from "./types/ForeignProposal"; -export * from "./types/FunctionDef"; -export * from "./types/IndexedValue"; -export * from "./types/IndexedWellKnownTypes"; -export * from "./types/InstructionResult"; -export * from "./types/Instruction"; -export * from "./types/JrpcPermissions"; -export * from "./types/JrpcPermission"; -export * from "./types/LeaderFee"; -export * from "./types/LockFlag"; -export * from "./types/LogEntry"; -export * from "./types/LogLevel"; -export * from "./types/Metadata"; -export * from "./types/NetworkCommitteeInfo"; -export * from "./types/NodeHeight"; -export * from "./types/NonFungibleAddressContents"; -export * from "./types/NonFungibleAddress"; -export * from "./types/NonFungibleContainer"; -export * from "./types/NonFungibleId"; -export * from "./types/NonFungibleIndexAddress"; -export * from "./types/NonFungibleIndex"; -export * from "./types/NonFungibleToken"; -export * from "./types/NonFungible"; -export * from "./types/NumPreshards"; -export * from "./types/Ordering"; -export * from "./types/OwnerRule"; -export * from "./types/PeerAddress"; -export * from "./types/ProofId"; -export * from "./types/QuorumCertificate"; -export * from "./types/QuorumDecision"; -export * from "./types/RejectReason"; -export * from "./types/RequireRule"; -export * from "./types/ResourceAccessRules"; -export * from "./types/ResourceAddress"; -export * from "./types/ResourceContainer"; -export * from "./types/Resource"; -export * from "./types/ResourceType"; -export * from "./types/RestrictedAccessRule"; -export * from "./types/RuleRequirement"; -export * from "./types/ShardEvidence"; -export * from "./types/ShardGroup"; -export * from "./types/Shard"; -export * from "./types/SubstateAddress"; -export * from "./types/SubstateDestroyed"; -export * from "./types/SubstateDiff"; -export * from "./types/SubstateId"; -export * from "./types/SubstateLockFlag"; -export * from "./types/SubstateLockType"; -export * from "./types/SubstateRecord"; -export * from "./types/SubstateRequirement"; -export * from "./types/Substate"; -export * from "./types/SubstateType"; -export * from "./types/SubstateValue"; -export * from "./types/TemplateDef"; -export * from "./types/TemplateDefV1"; -export * from "./types/TransactionAtom"; -export * from "./types/TransactionPoolRecord"; -export * from "./types/TransactionPoolStage"; -export * from "./types/TransactionReceiptAddress"; -export * from "./types/TransactionReceipt"; -export * from "./types/TransactionResult"; -export * from "./types/TransactionSignature"; -export * from "./types/TransactionStatus"; -export * from "./types/Transaction"; -export * from "./types/Type"; -export * from "./types/UnclaimedConfidentialOutput"; -export * from "./types/UnsignedTransaction"; -export * from "./types/ValidatorSignature"; -export * from "./types/VaultId"; -export * from "./types/Vault"; -export * from "./types/VersionedSubstateIdLockIntent"; -export * from "./types/VersionedSubstateId"; -export * from "./types/ViewableBalanceProof"; -export * from "./base-node-client"; -export * from "./tari-indexer-client"; -export * from "./validator-node-client"; -export * from "./wallet-daemon-client"; -export * from "./helpers/helpers"; -// Copyright 2023 The Tari Project -// SPDX-License-Identifier: BSD-3-Clause -export * from "./types/AccessRule"; -export * from "./types/Account"; -export * from "./types/Amount"; -export * from "./types/ArgDef"; -export * from "./types/Arg"; -export * from "./types/AuthHook"; -export * from "./types/Block"; -export * from "./types/BucketId"; -export * from "./types/Claims"; -export * from "./types/Command"; -export * from "./types/CommitteeInfo"; -export * from "./types/CommitteeShardInfo"; -export * from "./types/Committee"; -export * from "./types/ComponentAccessRules"; -export * from "./types/ComponentAddress"; -export * from "./types/ComponentBody"; -export * from "./types/ComponentHeader"; -export * from "./types/ComponentKey"; -export * from "./types/ConfidentialClaim"; -export * from "./types/ConfidentialOutputStatement"; -export * from "./types/ConfidentialOutput"; -export * from "./types/ConfidentialStatement"; -export * from "./types/ConfidentialTransferInputSelection"; -export * from "./types/ConfidentialWithdrawProof"; -export * from "./types/Decision"; -export * from "./types/ElgamalVerifiableBalance"; -export * from "./types/EntityId"; -export * from "./types/Epoch"; -export * from "./types/Event"; -export * from "./types/Evidence"; -export * from "./types/ExecutedTransaction"; -export * from "./types/ExecuteResult"; -export * from "./types/FeeBreakdown"; -export * from "./types/FeeClaimAddress"; -export * from "./types/FeeClaim"; -export * from "./types/FeeCostBreakdown"; -export * from "./types/FeeReceipt"; -export * from "./types/FeeSource"; -export * from "./types/FinalizeResult"; -export * from "./types/ForeignProposalState"; -export * from "./types/ForeignProposal"; -export * from "./types/FunctionDef"; -export * from "./types/IndexedValue"; -export * from "./types/IndexedWellKnownTypes"; -export * from "./types/InstructionResult"; -export * from "./types/Instruction"; -export * from "./types/JrpcPermissions"; -export * from "./types/JrpcPermission"; -export * from "./types/LeaderFee"; -export * from "./types/LockFlag"; -export * from "./types/LogEntry"; -export * from "./types/LogLevel"; -export * from "./types/Metadata"; -export * from "./types/NetworkCommitteeInfo"; -export * from "./types/NodeHeight"; -export * from "./types/NonFungibleAddressContents"; -export * from "./types/NonFungibleAddress"; -export * from "./types/NonFungibleContainer"; -export * from "./types/NonFungibleId"; -export * from "./types/NonFungibleIndexAddress"; -export * from "./types/NonFungibleIndex"; -export * from "./types/NonFungibleToken"; -export * from "./types/NonFungible"; -export * from "./types/NumPreshards"; -export * from "./types/Ordering"; -export * from "./types/OwnerRule"; -export * from "./types/PeerAddress"; -export * from "./types/ProofId"; -export * from "./types/QuorumCertificate"; -export * from "./types/QuorumDecision"; -export * from "./types/RejectReason"; -export * from "./types/RequireRule"; -export * from "./types/ResourceAccessRules"; -export * from "./types/ResourceAddress"; -export * from "./types/ResourceContainer"; -export * from "./types/Resource"; -export * from "./types/ResourceType"; -export * from "./types/RestrictedAccessRule"; -export * from "./types/RuleRequirement"; -export * from "./types/ShardEvidence"; -export * from "./types/ShardGroup"; -export * from "./types/Shard"; -export * from "./types/SubstateAddress"; -export * from "./types/SubstateDestroyed"; -export * from "./types/SubstateDiff"; -export * from "./types/SubstateId"; -export * from "./types/SubstateLockFlag"; -export * from "./types/SubstateLockType"; -export * from "./types/SubstateRecord"; -export * from "./types/SubstateRequirement"; -export * from "./types/Substate"; -export * from "./types/SubstateType"; -export * from "./types/SubstateValue"; -export * from "./types/TemplateDef"; -export * from "./types/TemplateDefV1"; -export * from "./types/TransactionAtom"; -export * from "./types/TransactionPoolRecord"; -export * from "./types/TransactionPoolStage"; -export * from "./types/TransactionReceiptAddress"; -export * from "./types/TransactionReceipt"; -export * from "./types/TransactionResult"; -export * from "./types/TransactionSignature"; -export * from "./types/TransactionStatus"; -export * from "./types/Transaction"; -export * from "./types/Type"; -export * from "./types/UnclaimedConfidentialOutput"; -export * from "./types/UnsignedTransaction"; -export * from "./types/ValidatorSignature"; -export * from "./types/VaultId"; -export * from "./types/Vault"; -export * from "./types/VersionedSubstateIdLockIntent"; -export * from "./types/VersionedSubstateId"; -export * from "./types/ViewableBalanceProof"; -export * from "./base-node-client"; -export * from "./tari-indexer-client"; -export * from "./validator-node-client"; -export * from "./wallet-daemon-client"; -export * from "./helpers/helpers"; -// Copyright 2023 The Tari Project -// SPDX-License-Identifier: BSD-3-Clause -export * from "./types/AccessRule"; -export * from "./types/Account"; -export * from "./types/Amount"; -export * from "./types/ArgDef"; -export * from "./types/Arg"; -export * from "./types/AuthHook"; -export * from "./types/Block"; -export * from "./types/BucketId"; -export * from "./types/Claims"; -export * from "./types/Command"; -export * from "./types/CommitteeInfo"; -export * from "./types/CommitteeShardInfo"; -export * from "./types/Committee"; -export * from "./types/ComponentAccessRules"; -export * from "./types/ComponentAddress"; -export * from "./types/ComponentBody"; -export * from "./types/ComponentHeader"; -export * from "./types/ComponentKey"; -export * from "./types/ConfidentialClaim"; -export * from "./types/ConfidentialOutputStatement"; -export * from "./types/ConfidentialOutput"; -export * from "./types/ConfidentialStatement"; -export * from "./types/ConfidentialTransferInputSelection"; -export * from "./types/ConfidentialWithdrawProof"; -export * from "./types/Decision"; -export * from "./types/ElgamalVerifiableBalance"; -export * from "./types/EntityId"; -export * from "./types/Epoch"; -export * from "./types/Event"; -export * from "./types/Evidence"; -export * from "./types/ExecutedTransaction"; -export * from "./types/ExecuteResult"; -export * from "./types/FeeBreakdown"; -export * from "./types/FeeClaimAddress"; -export * from "./types/FeeClaim"; -export * from "./types/FeeCostBreakdown"; -export * from "./types/FeeReceipt"; -export * from "./types/FeeSource"; -export * from "./types/FinalizeResult"; -export * from "./types/ForeignProposalState"; -export * from "./types/ForeignProposal"; -export * from "./types/FunctionDef"; -export * from "./types/IndexedValue"; -export * from "./types/IndexedWellKnownTypes"; -export * from "./types/InstructionResult"; -export * from "./types/Instruction"; -export * from "./types/JrpcPermissions"; -export * from "./types/JrpcPermission"; -export * from "./types/LeaderFee"; -export * from "./types/LockFlag"; -export * from "./types/LogEntry"; -export * from "./types/LogLevel"; -export * from "./types/Metadata"; -export * from "./types/NetworkCommitteeInfo"; -export * from "./types/NodeHeight"; -export * from "./types/NonFungibleAddressContents"; -export * from "./types/NonFungibleAddress"; -export * from "./types/NonFungibleContainer"; -export * from "./types/NonFungibleId"; -export * from "./types/NonFungibleIndexAddress"; -export * from "./types/NonFungibleIndex"; -export * from "./types/NonFungibleToken"; -export * from "./types/NonFungible"; -export * from "./types/NumPreshards"; -export * from "./types/Ordering"; -export * from "./types/OwnerRule"; -export * from "./types/PeerAddress"; -export * from "./types/ProofId"; -export * from "./types/QuorumCertificate"; -export * from "./types/QuorumDecision"; -export * from "./types/RejectReason"; -export * from "./types/RequireRule"; -export * from "./types/ResourceAccessRules"; -export * from "./types/ResourceAddress"; -export * from "./types/ResourceContainer"; -export * from "./types/Resource"; -export * from "./types/ResourceType"; -export * from "./types/RestrictedAccessRule"; -export * from "./types/RuleRequirement"; -export * from "./types/ShardEvidence"; -export * from "./types/ShardGroup"; -export * from "./types/Shard"; -export * from "./types/SubstateAddress"; -export * from "./types/SubstateDestroyed"; -export * from "./types/SubstateDiff"; -export * from "./types/SubstateId"; -export * from "./types/SubstateLockFlag"; -export * from "./types/SubstateLockType"; -export * from "./types/SubstateRecord"; -export * from "./types/SubstateRequirement"; -export * from "./types/Substate"; -export * from "./types/SubstateType"; -export * from "./types/SubstateValue"; -export * from "./types/TemplateDef"; -export * from "./types/TemplateDefV1"; -export * from "./types/TransactionAtom"; -export * from "./types/TransactionPoolRecord"; -export * from "./types/TransactionPoolStage"; -export * from "./types/TransactionReceiptAddress"; -export * from "./types/TransactionReceipt"; -export * from "./types/TransactionResult"; -export * from "./types/TransactionSignature"; -export * from "./types/TransactionStatus"; -export * from "./types/Transaction"; -export * from "./types/Type"; -export * from "./types/UnclaimedConfidentialOutput"; -export * from "./types/UnsignedTransaction"; -export * from "./types/ValidatorSignature"; -export * from "./types/VaultId"; -export * from "./types/Vault"; -export * from "./types/VersionedSubstateIdLockIntent"; -export * from "./types/VersionedSubstateId"; -export * from "./types/ViewableBalanceProof"; -export * from "./base-node-client"; -export * from "./tari-indexer-client"; -export * from "./validator-node-client"; -export * from "./wallet-daemon-client"; -export * from "./helpers/helpers"; -// Copyright 2023 The Tari Project -// SPDX-License-Identifier: BSD-3-Clause -export * from "./types/AccessRule"; -export * from "./types/Account"; -export * from "./types/Amount"; -export * from "./types/ArgDef"; -export * from "./types/Arg"; -export * from "./types/AuthHook"; -export * from "./types/Block"; -export * from "./types/BucketId"; -export * from "./types/Claims"; -export * from "./types/Command"; -export * from "./types/CommitteeInfo"; -export * from "./types/CommitteeShardInfo"; -export * from "./types/Committee"; -export * from "./types/ComponentAccessRules"; -export * from "./types/ComponentAddress"; -export * from "./types/ComponentBody"; -export * from "./types/ComponentHeader"; -export * from "./types/ComponentKey"; -export * from "./types/ConfidentialClaim"; -export * from "./types/ConfidentialOutputStatement"; -export * from "./types/ConfidentialOutput"; -export * from "./types/ConfidentialStatement"; -export * from "./types/ConfidentialTransferInputSelection"; -export * from "./types/ConfidentialWithdrawProof"; -export * from "./types/Decision"; -export * from "./types/ElgamalVerifiableBalance"; -export * from "./types/EntityId"; -export * from "./types/Epoch"; -export * from "./types/Event"; -export * from "./types/Evidence"; -export * from "./types/ExecutedTransaction"; -export * from "./types/ExecuteResult"; -export * from "./types/FeeBreakdown"; -export * from "./types/FeeClaimAddress"; -export * from "./types/FeeClaim"; -export * from "./types/FeeCostBreakdown"; -export * from "./types/FeeReceipt"; -export * from "./types/FeeSource"; -export * from "./types/FinalizeResult"; -export * from "./types/ForeignProposalAtom"; -export * from "./types/ForeignProposalState"; -export * from "./types/ForeignProposal"; -export * from "./types/FunctionDef"; -export * from "./types/IndexedValue"; -export * from "./types/IndexedWellKnownTypes"; -export * from "./types/InstructionResult"; -export * from "./types/Instruction"; -export * from "./types/JrpcPermissions"; -export * from "./types/JrpcPermission"; -export * from "./types/LeaderFee"; -export * from "./types/LockFlag"; -export * from "./types/LogEntry"; -export * from "./types/LogLevel"; -export * from "./types/Metadata"; -export * from "./types/NetworkCommitteeInfo"; -export * from "./types/NodeHeight"; -export * from "./types/NonFungibleAddressContents"; -export * from "./types/NonFungibleAddress"; -export * from "./types/NonFungibleContainer"; -export * from "./types/NonFungibleId"; -export * from "./types/NonFungibleIndexAddress"; -export * from "./types/NonFungibleIndex"; -export * from "./types/NonFungibleToken"; -export * from "./types/NonFungible"; -export * from "./types/NumPreshards"; -export * from "./types/Ordering"; -export * from "./types/OwnerRule"; -export * from "./types/PeerAddress"; -export * from "./types/ProofId"; -export * from "./types/QuorumCertificate"; -export * from "./types/QuorumDecision"; -export * from "./types/RejectReason"; -export * from "./types/RequireRule"; -export * from "./types/ResourceAccessRules"; -export * from "./types/ResourceAddress"; -export * from "./types/ResourceContainer"; -export * from "./types/Resource"; -export * from "./types/ResourceType"; -export * from "./types/RestrictedAccessRule"; -export * from "./types/RuleRequirement"; -export * from "./types/ShardEvidence"; -export * from "./types/ShardGroup"; -export * from "./types/Shard"; -export * from "./types/SubstateAddress"; -export * from "./types/SubstateDestroyed"; -export * from "./types/SubstateDiff"; -export * from "./types/SubstateId"; -export * from "./types/SubstateLockFlag"; -export * from "./types/SubstateLockType"; -export * from "./types/SubstateRecord"; -export * from "./types/SubstateRequirement"; -export * from "./types/Substate"; -export * from "./types/SubstateType"; -export * from "./types/SubstateValue"; -export * from "./types/TemplateDef"; -export * from "./types/TemplateDefV1"; -export * from "./types/TransactionAtom"; -export * from "./types/TransactionPoolRecord"; -export * from "./types/TransactionPoolStage"; -export * from "./types/TransactionReceiptAddress"; -export * from "./types/TransactionReceipt"; -export * from "./types/TransactionResult"; -export * from "./types/TransactionSignature"; -export * from "./types/TransactionStatus"; -export * from "./types/Transaction"; -export * from "./types/Type"; -export * from "./types/UnclaimedConfidentialOutput"; -export * from "./types/UnsignedTransaction"; -export * from "./types/ValidatorSignature"; -export * from "./types/VaultId"; -export * from "./types/Vault"; -export * from "./types/VersionedSubstateIdLockIntent"; -export * from "./types/VersionedSubstateId"; -export * from "./types/ViewableBalanceProof"; -export * from "./base-node-client"; -export * from "./tari-indexer-client"; -export * from "./validator-node-client"; -export * from "./wallet-daemon-client"; -export * from "./helpers/helpers"; -// Copyright 2023 The Tari Project -// SPDX-License-Identifier: BSD-3-Clause -export * from "./types/AccessRule"; -export * from "./types/Account"; -export * from "./types/Amount"; -export * from "./types/ArgDef"; -export * from "./types/Arg"; -export * from "./types/AuthHook"; -export * from "./types/Block"; -export * from "./types/BucketId"; -export * from "./types/Claims"; -export * from "./types/Command"; -export * from "./types/CommitteeInfo"; -export * from "./types/CommitteeShardInfo"; -export * from "./types/Committee"; -export * from "./types/ComponentAccessRules"; -export * from "./types/ComponentAddress"; -export * from "./types/ComponentBody"; -export * from "./types/ComponentHeader"; -export * from "./types/ComponentKey"; -export * from "./types/ConfidentialClaim"; -export * from "./types/ConfidentialOutputStatement"; -export * from "./types/ConfidentialOutput"; -export * from "./types/ConfidentialStatement"; -export * from "./types/ConfidentialTransferInputSelection"; -export * from "./types/ConfidentialWithdrawProof"; -export * from "./types/Decision"; -export * from "./types/ElgamalVerifiableBalance"; -export * from "./types/EntityId"; -export * from "./types/Epoch"; -export * from "./types/Event"; -export * from "./types/Evidence"; -export * from "./types/ExecutedTransaction"; -export * from "./types/ExecuteResult"; -export * from "./types/FeeBreakdown"; -export * from "./types/FeeClaimAddress"; -export * from "./types/FeeClaim"; -export * from "./types/FeeCostBreakdown"; -export * from "./types/FeeReceipt"; -export * from "./types/FeeSource"; -export * from "./types/FinalizeResult"; -export * from "./types/ForeignProposalAtom"; -export * from "./types/ForeignProposalState"; -export * from "./types/ForeignProposal"; -export * from "./types/FunctionDef"; -export * from "./types/IndexedValue"; -export * from "./types/IndexedWellKnownTypes"; -export * from "./types/InstructionResult"; -export * from "./types/Instruction"; -export * from "./types/JrpcPermissions"; -export * from "./types/JrpcPermission"; -export * from "./types/LeaderFee"; -export * from "./types/LockFlag"; -export * from "./types/LogEntry"; -export * from "./types/LogLevel"; -export * from "./types/Metadata"; -export * from "./types/NetworkCommitteeInfo"; -export * from "./types/NodeHeight"; -export * from "./types/NonFungibleAddressContents"; -export * from "./types/NonFungibleAddress"; -export * from "./types/NonFungibleContainer"; -export * from "./types/NonFungibleId"; -export * from "./types/NonFungibleIndexAddress"; -export * from "./types/NonFungibleIndex"; -export * from "./types/NonFungibleToken"; -export * from "./types/NonFungible"; -export * from "./types/NumPreshards"; -export * from "./types/Ordering"; -export * from "./types/OwnerRule"; -export * from "./types/PeerAddress"; -export * from "./types/ProofId"; -export * from "./types/QuorumCertificate"; -export * from "./types/QuorumDecision"; -export * from "./types/RejectReason"; -export * from "./types/RequireRule"; -export * from "./types/ResourceAccessRules"; -export * from "./types/ResourceAddress"; -export * from "./types/ResourceContainer"; -export * from "./types/Resource"; -export * from "./types/ResourceType"; -export * from "./types/RestrictedAccessRule"; -export * from "./types/RuleRequirement"; -export * from "./types/ShardEvidence"; -export * from "./types/ShardGroup"; -export * from "./types/Shard"; -export * from "./types/SubstateAddress"; -export * from "./types/SubstateDestroyed"; -export * from "./types/SubstateDiff"; -export * from "./types/SubstateId"; -export * from "./types/SubstateLockFlag"; -export * from "./types/SubstateLockType"; -export * from "./types/SubstateRecord"; -export * from "./types/SubstateRequirement"; -export * from "./types/Substate"; -export * from "./types/SubstateType"; -export * from "./types/SubstateValue"; -export * from "./types/TemplateDef"; -export * from "./types/TemplateDefV1"; -export * from "./types/TransactionAtom"; -export * from "./types/TransactionPoolRecord"; -export * from "./types/TransactionPoolStage"; -export * from "./types/TransactionReceiptAddress"; -export * from "./types/TransactionReceipt"; -export * from "./types/TransactionResult"; -export * from "./types/TransactionSignature"; -export * from "./types/TransactionStatus"; -export * from "./types/Transaction"; -export * from "./types/Type"; -export * from "./types/UnclaimedConfidentialOutput"; -export * from "./types/UnsignedTransaction"; -export * from "./types/ValidatorSignature"; -export * from "./types/VaultId"; -export * from "./types/Vault"; -export * from "./types/VersionedSubstateIdLockIntent"; -export * from "./types/VersionedSubstateId"; -export * from "./types/ViewableBalanceProof"; -export * from "./base-node-client"; -export * from "./tari-indexer-client"; -export * from "./validator-node-client"; -export * from "./wallet-daemon-client"; -export * from "./helpers/helpers"; -// Copyright 2023 The Tari Project -// SPDX-License-Identifier: BSD-3-Clause -export * from "./types/AccessRule"; -export * from "./types/Account"; -export * from "./types/Amount"; -export * from "./types/ArgDef"; -export * from "./types/Arg"; -export * from "./types/AuthHook"; -export * from "./types/Block"; -export * from "./types/BucketId"; -export * from "./types/Claims"; -export * from "./types/Command"; -export * from "./types/CommitteeInfo"; -export * from "./types/CommitteeShardInfo"; -export * from "./types/Committee"; -export * from "./types/ComponentAccessRules"; -export * from "./types/ComponentAddress"; -export * from "./types/ComponentBody"; -export * from "./types/ComponentHeader"; -export * from "./types/ComponentKey"; -export * from "./types/ConfidentialClaim"; -export * from "./types/ConfidentialOutputStatement"; -export * from "./types/ConfidentialOutput"; -export * from "./types/ConfidentialStatement"; -export * from "./types/ConfidentialTransferInputSelection"; -export * from "./types/ConfidentialWithdrawProof"; -export * from "./types/Decision"; -export * from "./types/ElgamalVerifiableBalance"; -export * from "./types/EntityId"; -export * from "./types/Epoch"; -export * from "./types/Event"; -export * from "./types/Evidence"; -export * from "./types/ExecutedTransaction"; -export * from "./types/ExecuteResult"; -export * from "./types/FeeBreakdown"; -export * from "./types/FeeClaimAddress"; -export * from "./types/FeeClaim"; -export * from "./types/FeeCostBreakdown"; -export * from "./types/FeeReceipt"; -export * from "./types/FeeSource"; -export * from "./types/FinalizeResult"; -export * from "./types/ForeignProposalAtom"; -export * from "./types/ForeignProposalState"; -export * from "./types/ForeignProposal"; -export * from "./types/FunctionDef"; -export * from "./types/IndexedValue"; -export * from "./types/IndexedWellKnownTypes"; -export * from "./types/InstructionResult"; -export * from "./types/Instruction"; -export * from "./types/JrpcPermissions"; -export * from "./types/JrpcPermission"; -export * from "./types/LeaderFee"; -export * from "./types/LockFlag"; -export * from "./types/LogEntry"; -export * from "./types/LogLevel"; -export * from "./types/Metadata"; -export * from "./types/MintConfidentialOutputAtom"; -export * from "./types/NetworkCommitteeInfo"; -export * from "./types/NodeHeight"; -export * from "./types/NonFungibleAddressContents"; -export * from "./types/NonFungibleAddress"; -export * from "./types/NonFungibleContainer"; -export * from "./types/NonFungibleId"; -export * from "./types/NonFungibleIndexAddress"; -export * from "./types/NonFungibleIndex"; -export * from "./types/NonFungibleToken"; -export * from "./types/NonFungible"; -export * from "./types/NumPreshards"; -export * from "./types/Ordering"; -export * from "./types/OwnerRule"; -export * from "./types/PeerAddress"; -export * from "./types/ProofId"; -export * from "./types/QuorumCertificate"; -export * from "./types/QuorumDecision"; -export * from "./types/RejectReason"; -export * from "./types/RequireRule"; -export * from "./types/ResourceAccessRules"; -export * from "./types/ResourceAddress"; -export * from "./types/ResourceContainer"; -export * from "./types/Resource"; -export * from "./types/ResourceType"; -export * from "./types/RestrictedAccessRule"; -export * from "./types/RuleRequirement"; -export * from "./types/ShardEvidence"; -export * from "./types/ShardGroup"; -export * from "./types/Shard"; -export * from "./types/SubstateAddress"; -export * from "./types/SubstateDestroyed"; -export * from "./types/SubstateDiff"; -export * from "./types/SubstateId"; -export * from "./types/SubstateLockFlag"; -export * from "./types/SubstateLockType"; -export * from "./types/SubstateRecord"; -export * from "./types/SubstateRequirement"; -export * from "./types/Substate"; -export * from "./types/SubstateType"; -export * from "./types/SubstateValue"; -export * from "./types/TemplateDef"; -export * from "./types/TemplateDefV1"; -export * from "./types/TransactionAtom"; -export * from "./types/TransactionPoolRecord"; -export * from "./types/TransactionPoolStage"; -export * from "./types/TransactionReceiptAddress"; -export * from "./types/TransactionReceipt"; -export * from "./types/TransactionResult"; -export * from "./types/TransactionSignature"; -export * from "./types/TransactionStatus"; -export * from "./types/Transaction"; -export * from "./types/Type"; -export * from "./types/UnclaimedConfidentialOutput"; -export * from "./types/UnsignedTransaction"; -export * from "./types/ValidatorSignature"; -export * from "./types/VaultId"; -export * from "./types/Vault"; -export * from "./types/VersionedSubstateIdLockIntent"; -export * from "./types/VersionedSubstateId"; -export * from "./types/ViewableBalanceProof"; -export * from "./base-node-client"; -export * from "./tari-indexer-client"; -export * from "./validator-node-client"; -export * from "./wallet-daemon-client"; -export * from "./helpers/helpers"; -// Copyright 2023 The Tari Project -// SPDX-License-Identifier: BSD-3-Clause -export * from "./types/AccessRule"; -export * from "./types/Account"; -export * from "./types/Amount"; -export * from "./types/ArgDef"; -export * from "./types/Arg"; -export * from "./types/AuthHook"; -export * from "./types/Block"; -export * from "./types/BucketId"; -export * from "./types/Claims"; -export * from "./types/Command"; -export * from "./types/CommitteeInfo"; -export * from "./types/CommitteeShardInfo"; -export * from "./types/Committee"; -export * from "./types/ComponentAccessRules"; -export * from "./types/ComponentAddress"; -export * from "./types/ComponentBody"; -export * from "./types/ComponentHeader"; -export * from "./types/ComponentKey"; -export * from "./types/ConfidentialClaim"; -export * from "./types/ConfidentialOutputStatement"; -export * from "./types/ConfidentialOutput"; -export * from "./types/ConfidentialStatement"; -export * from "./types/ConfidentialTransferInputSelection"; -export * from "./types/ConfidentialWithdrawProof"; -export * from "./types/Decision"; -export * from "./types/ElgamalVerifiableBalance"; -export * from "./types/EntityId"; -export * from "./types/Epoch"; -export * from "./types/Event"; -export * from "./types/Evidence"; -export * from "./types/ExecutedTransaction"; -export * from "./types/ExecuteResult"; -export * from "./types/FeeBreakdown"; -export * from "./types/FeeClaimAddress"; -export * from "./types/FeeClaim"; -export * from "./types/FeeCostBreakdown"; -export * from "./types/FeeReceipt"; -export * from "./types/FeeSource"; -export * from "./types/FinalizeResult"; -export * from "./types/ForeignProposalAtom"; -export * from "./types/ForeignProposalState"; -export * from "./types/ForeignProposal"; -export * from "./types/FunctionDef"; -export * from "./types/IndexedValue"; -export * from "./types/IndexedWellKnownTypes"; -export * from "./types/InstructionResult"; -export * from "./types/Instruction"; -export * from "./types/JrpcPermissions"; -export * from "./types/JrpcPermission"; -export * from "./types/LeaderFee"; -export * from "./types/LockFlag"; -export * from "./types/LogEntry"; -export * from "./types/LogLevel"; -export * from "./types/Metadata"; -export * from "./types/MintConfidentialOutputAtom"; -export * from "./types/NetworkCommitteeInfo"; -export * from "./types/NodeHeight"; -export * from "./types/NonFungibleAddressContents"; -export * from "./types/NonFungibleAddress"; -export * from "./types/NonFungibleContainer"; -export * from "./types/NonFungibleId"; -export * from "./types/NonFungibleIndexAddress"; -export * from "./types/NonFungibleIndex"; -export * from "./types/NonFungibleToken"; -export * from "./types/NonFungible"; -export * from "./types/NumPreshards"; -export * from "./types/Ordering"; -export * from "./types/OwnerRule"; -export * from "./types/PeerAddress"; -export * from "./types/ProofId"; -export * from "./types/QuorumCertificate"; -export * from "./types/QuorumDecision"; -export * from "./types/RejectReason"; -export * from "./types/RequireRule"; -export * from "./types/ResourceAccessRules"; -export * from "./types/ResourceAddress"; -export * from "./types/ResourceContainer"; -export * from "./types/Resource"; -export * from "./types/ResourceType"; -export * from "./types/RestrictedAccessRule"; -export * from "./types/RuleRequirement"; -export * from "./types/ShardEvidence"; -export * from "./types/ShardGroup"; -export * from "./types/Shard"; -export * from "./types/SubstateAddress"; -export * from "./types/SubstateDestroyed"; -export * from "./types/SubstateDiff"; -export * from "./types/SubstateId"; -export * from "./types/SubstateLockFlag"; -export * from "./types/SubstateLockType"; -export * from "./types/SubstateRecord"; -export * from "./types/SubstateRequirement"; -export * from "./types/Substate"; -export * from "./types/SubstateType"; -export * from "./types/SubstateValue"; -export * from "./types/TemplateDef"; -export * from "./types/TemplateDefV1"; -export * from "./types/TransactionAtom"; -export * from "./types/TransactionPoolRecord"; -export * from "./types/TransactionPoolStage"; -export * from "./types/TransactionReceiptAddress"; -export * from "./types/TransactionReceipt"; -export * from "./types/TransactionResult"; -export * from "./types/TransactionSignature"; -export * from "./types/TransactionStatus"; -export * from "./types/Transaction"; -export * from "./types/Type"; -export * from "./types/UnclaimedConfidentialOutputAddress"; -export * from "./types/UnclaimedConfidentialOutput"; -export * from "./types/UnsignedTransaction"; -export * from "./types/ValidatorSignature"; -export * from "./types/VaultId"; -export * from "./types/Vault"; -export * from "./types/VersionedSubstateIdLockIntent"; -export * from "./types/VersionedSubstateId"; -export * from "./types/ViewableBalanceProof"; -export * from "./base-node-client"; -export * from "./tari-indexer-client"; -export * from "./validator-node-client"; -export * from "./wallet-daemon-client"; -export * from "./helpers/helpers"; -// Copyright 2023 The Tari Project -// SPDX-License-Identifier: BSD-3-Clause -export * from "./types/AccessRule"; -export * from "./types/Account"; -export * from "./types/Amount"; -export * from "./types/ArgDef"; -export * from "./types/Arg"; -export * from "./types/AuthHook"; -export * from "./types/Block"; -export * from "./types/BucketId"; -export * from "./types/Claims"; -export * from "./types/Command"; -export * from "./types/CommitteeInfo"; -export * from "./types/CommitteeShardInfo"; -export * from "./types/Committee"; -export * from "./types/ComponentAccessRules"; -export * from "./types/ComponentAddress"; -export * from "./types/ComponentBody"; -export * from "./types/ComponentHeader"; -export * from "./types/ComponentKey"; -export * from "./types/ConfidentialClaim"; -export * from "./types/ConfidentialOutputStatement"; -export * from "./types/ConfidentialOutput"; -export * from "./types/ConfidentialStatement"; -export * from "./types/ConfidentialTransferInputSelection"; -export * from "./types/ConfidentialWithdrawProof"; -export * from "./types/Decision"; -export * from "./types/ElgamalVerifiableBalance"; -export * from "./types/EntityId"; -export * from "./types/Epoch"; -export * from "./types/Event"; -export * from "./types/Evidence"; -export * from "./types/ExecutedTransaction"; -export * from "./types/ExecuteResult"; -export * from "./types/FeeBreakdown"; -export * from "./types/FeeClaimAddress"; -export * from "./types/FeeClaim"; -export * from "./types/FeeCostBreakdown"; -export * from "./types/FeeReceipt"; -export * from "./types/FeeSource"; -export * from "./types/FinalizeResult"; export * from "./types/ForeignProposalAtom"; -export * from "./types/ForeignProposalState"; -export * from "./types/ForeignProposal"; export * from "./types/FunctionDef"; export * from "./types/IndexedValue"; export * from "./types/IndexedWellKnownTypes"; @@ -1173,7 +86,6 @@ export * from "./types/SubstateAddress"; export * from "./types/SubstateDestroyed"; export * from "./types/SubstateDiff"; export * from "./types/SubstateId"; -export * from "./types/SubstateLockFlag"; export * from "./types/SubstateLockType"; export * from "./types/SubstateRecord"; export * from "./types/SubstateRequirement"; diff --git a/bindings/dist/types/ForeignProposal.d.ts b/bindings/dist/types/ForeignProposal.d.ts deleted file mode 100644 index d78fb37bc..000000000 --- a/bindings/dist/types/ForeignProposal.d.ts +++ /dev/null @@ -1,10 +0,0 @@ -import type { ForeignProposalState } from "./ForeignProposalState"; -import type { NodeHeight } from "./NodeHeight"; -export interface ForeignProposal { - shard_group: number; - block_id: string; - state: ForeignProposalState; - proposed_height: NodeHeight | null; - transactions: Array; - base_layer_block_height: number; -} diff --git a/bindings/dist/types/ForeignProposal.js b/bindings/dist/types/ForeignProposal.js deleted file mode 100644 index cb0ff5c3b..000000000 --- a/bindings/dist/types/ForeignProposal.js +++ /dev/null @@ -1 +0,0 @@ -export {}; diff --git a/bindings/dist/types/ForeignProposalState.d.ts b/bindings/dist/types/ForeignProposalState.d.ts deleted file mode 100644 index 4512d8b5d..000000000 --- a/bindings/dist/types/ForeignProposalState.d.ts +++ /dev/null @@ -1 +0,0 @@ -export type ForeignProposalState = "New" | "Proposed" | "Deleted"; diff --git a/bindings/dist/types/ForeignProposalState.js b/bindings/dist/types/ForeignProposalState.js deleted file mode 100644 index e5b481d1e..000000000 --- a/bindings/dist/types/ForeignProposalState.js +++ /dev/null @@ -1,2 +0,0 @@ -// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually. -export {}; diff --git a/bindings/dist/types/ShardEvidence.d.ts b/bindings/dist/types/ShardEvidence.d.ts index 8aaadf4cf..b47531c96 100644 --- a/bindings/dist/types/ShardEvidence.d.ts +++ b/bindings/dist/types/ShardEvidence.d.ts @@ -1,5 +1,6 @@ import type { SubstateLockType } from "./SubstateLockType"; export interface ShardEvidence { - qc_ids: Array; + prepare_justify: string | null; + accept_justify: string | null; lock: SubstateLockType; } diff --git a/bindings/dist/types/SubstateLockFlag.d.ts b/bindings/dist/types/SubstateLockFlag.d.ts deleted file mode 100644 index 65ce172c2..000000000 --- a/bindings/dist/types/SubstateLockFlag.d.ts +++ /dev/null @@ -1 +0,0 @@ -export type SubstateLockFlag = "Read" | "Write" | "Output"; diff --git a/bindings/dist/types/SubstateLockFlag.js b/bindings/dist/types/SubstateLockFlag.js deleted file mode 100644 index e5b481d1e..000000000 --- a/bindings/dist/types/SubstateLockFlag.js +++ /dev/null @@ -1,2 +0,0 @@ -// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually. -export {}; diff --git a/bindings/dist/types/TransactionPoolRecord.d.ts b/bindings/dist/types/TransactionPoolRecord.d.ts index ce0482b19..025d38ada 100644 --- a/bindings/dist/types/TransactionPoolRecord.d.ts +++ b/bindings/dist/types/TransactionPoolRecord.d.ts @@ -5,7 +5,6 @@ import type { TransactionPoolStage } from "./TransactionPoolStage"; export interface TransactionPoolRecord { transaction_id: string; evidence: Evidence; - remote_evidence: Evidence | null; transaction_fee: number; leader_fee: LeaderFee | null; stage: TransactionPoolStage; diff --git a/bindings/dist/types/tari-indexer-client/AddPeerRequest.d.ts b/bindings/dist/types/tari-indexer-client/AddPeerRequest.d.ts deleted file mode 100644 index b4ee7b776..000000000 --- a/bindings/dist/types/tari-indexer-client/AddPeerRequest.d.ts +++ /dev/null @@ -1,5 +0,0 @@ -export interface AddPeerRequest { - public_key: string; - addresses: Array; - wait_for_dial: boolean; -} diff --git a/bindings/dist/types/tari-indexer-client/AddPeerRequest.js b/bindings/dist/types/tari-indexer-client/AddPeerRequest.js deleted file mode 100644 index e5b481d1e..000000000 --- a/bindings/dist/types/tari-indexer-client/AddPeerRequest.js +++ /dev/null @@ -1,2 +0,0 @@ -// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually. -export {}; diff --git a/bindings/dist/types/tari-indexer-client/AddPeerResponse.d.ts b/bindings/dist/types/tari-indexer-client/AddPeerResponse.d.ts deleted file mode 100644 index bc71882d4..000000000 --- a/bindings/dist/types/tari-indexer-client/AddPeerResponse.d.ts +++ /dev/null @@ -1 +0,0 @@ -export type AddPeerResponse = Record; diff --git a/bindings/dist/types/tari-indexer-client/AddPeerResponse.js b/bindings/dist/types/tari-indexer-client/AddPeerResponse.js deleted file mode 100644 index e5b481d1e..000000000 --- a/bindings/dist/types/tari-indexer-client/AddPeerResponse.js +++ /dev/null @@ -1,2 +0,0 @@ -// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually. -export {}; diff --git a/bindings/dist/types/tari-indexer-client/Connection.d.ts b/bindings/dist/types/tari-indexer-client/Connection.d.ts deleted file mode 100644 index 7062400fb..000000000 --- a/bindings/dist/types/tari-indexer-client/Connection.d.ts +++ /dev/null @@ -1,16 +0,0 @@ -import type { ConnectionDirection } from "./ConnectionDirection"; -export interface Connection { - connection_id: string; - peer_id: string; - address: string; - direction: ConnectionDirection; - age: { - secs: number; - nanos: number; - }; - ping_latency: { - secs: number; - nanos: number; - } | null; - user_agent: string | null; -} diff --git a/bindings/dist/types/tari-indexer-client/Connection.js b/bindings/dist/types/tari-indexer-client/Connection.js deleted file mode 100644 index cb0ff5c3b..000000000 --- a/bindings/dist/types/tari-indexer-client/Connection.js +++ /dev/null @@ -1 +0,0 @@ -export {}; diff --git a/bindings/dist/types/tari-indexer-client/ConnectionDirection.d.ts b/bindings/dist/types/tari-indexer-client/ConnectionDirection.d.ts deleted file mode 100644 index 2724420af..000000000 --- a/bindings/dist/types/tari-indexer-client/ConnectionDirection.d.ts +++ /dev/null @@ -1 +0,0 @@ -export type ConnectionDirection = "Inbound" | "Outbound"; diff --git a/bindings/dist/types/tari-indexer-client/ConnectionDirection.js b/bindings/dist/types/tari-indexer-client/ConnectionDirection.js deleted file mode 100644 index e5b481d1e..000000000 --- a/bindings/dist/types/tari-indexer-client/ConnectionDirection.js +++ /dev/null @@ -1,2 +0,0 @@ -// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually. -export {}; diff --git a/bindings/dist/types/tari-indexer-client/GetAllVnsRequest.d.ts b/bindings/dist/types/tari-indexer-client/GetAllVnsRequest.d.ts deleted file mode 100644 index 192cce8bb..000000000 --- a/bindings/dist/types/tari-indexer-client/GetAllVnsRequest.d.ts +++ /dev/null @@ -1,4 +0,0 @@ -import type { Epoch } from "../Epoch"; -export interface GetAllVnsRequest { - epoch: Epoch; -} diff --git a/bindings/dist/types/tari-indexer-client/GetAllVnsRequest.js b/bindings/dist/types/tari-indexer-client/GetAllVnsRequest.js deleted file mode 100644 index cb0ff5c3b..000000000 --- a/bindings/dist/types/tari-indexer-client/GetAllVnsRequest.js +++ /dev/null @@ -1 +0,0 @@ -export {}; diff --git a/bindings/dist/types/tari-indexer-client/GetAllVnsResponse.d.ts b/bindings/dist/types/tari-indexer-client/GetAllVnsResponse.d.ts deleted file mode 100644 index 41eb9f7eb..000000000 --- a/bindings/dist/types/tari-indexer-client/GetAllVnsResponse.d.ts +++ /dev/null @@ -1,4 +0,0 @@ -import type { BaseLayerValidatorNode } from "../base-node-client/BaseLayerValidatorNode"; -export interface GetAllVnsResponse { - vns: Array; -} diff --git a/bindings/dist/types/tari-indexer-client/GetAllVnsResponse.js b/bindings/dist/types/tari-indexer-client/GetAllVnsResponse.js deleted file mode 100644 index cb0ff5c3b..000000000 --- a/bindings/dist/types/tari-indexer-client/GetAllVnsResponse.js +++ /dev/null @@ -1 +0,0 @@ -export {}; diff --git a/bindings/dist/types/tari-indexer-client/GetCommsStatsResponse.d.ts b/bindings/dist/types/tari-indexer-client/GetCommsStatsResponse.d.ts deleted file mode 100644 index eb94a57b1..000000000 --- a/bindings/dist/types/tari-indexer-client/GetCommsStatsResponse.d.ts +++ /dev/null @@ -1,3 +0,0 @@ -export interface GetCommsStatsResponse { - connection_status: string; -} diff --git a/bindings/dist/types/tari-indexer-client/GetCommsStatsResponse.js b/bindings/dist/types/tari-indexer-client/GetCommsStatsResponse.js deleted file mode 100644 index e5b481d1e..000000000 --- a/bindings/dist/types/tari-indexer-client/GetCommsStatsResponse.js +++ /dev/null @@ -1,2 +0,0 @@ -// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually. -export {}; diff --git a/bindings/dist/types/tari-indexer-client/GetConnectionsResponse.d.ts b/bindings/dist/types/tari-indexer-client/GetConnectionsResponse.d.ts deleted file mode 100644 index af26db631..000000000 --- a/bindings/dist/types/tari-indexer-client/GetConnectionsResponse.d.ts +++ /dev/null @@ -1,4 +0,0 @@ -import type { Connection } from "./Connection"; -export interface GetConnectionsResponse { - connections: Array; -} diff --git a/bindings/dist/types/tari-indexer-client/GetConnectionsResponse.js b/bindings/dist/types/tari-indexer-client/GetConnectionsResponse.js deleted file mode 100644 index cb0ff5c3b..000000000 --- a/bindings/dist/types/tari-indexer-client/GetConnectionsResponse.js +++ /dev/null @@ -1 +0,0 @@ -export {}; diff --git a/bindings/dist/types/tari-indexer-client/GetEpochManagerStatsResponse.d.ts b/bindings/dist/types/tari-indexer-client/GetEpochManagerStatsResponse.d.ts deleted file mode 100644 index afffb9055..000000000 --- a/bindings/dist/types/tari-indexer-client/GetEpochManagerStatsResponse.d.ts +++ /dev/null @@ -1,6 +0,0 @@ -import type { Epoch } from "../Epoch"; -export interface GetEpochManagerStatsResponse { - current_epoch: Epoch; - current_block_height: number; - current_block_hash: string; -} diff --git a/bindings/dist/types/tari-indexer-client/GetEpochManagerStatsResponse.js b/bindings/dist/types/tari-indexer-client/GetEpochManagerStatsResponse.js deleted file mode 100644 index cb0ff5c3b..000000000 --- a/bindings/dist/types/tari-indexer-client/GetEpochManagerStatsResponse.js +++ /dev/null @@ -1 +0,0 @@ -export {}; diff --git a/bindings/dist/types/tari-indexer-client/GetIdentityResponse.d.ts b/bindings/dist/types/tari-indexer-client/GetIdentityResponse.d.ts deleted file mode 100644 index 2b2af1a8e..000000000 --- a/bindings/dist/types/tari-indexer-client/GetIdentityResponse.d.ts +++ /dev/null @@ -1,5 +0,0 @@ -export interface GetIdentityResponse { - peer_id: string; - public_key: string; - public_addresses: Array; -} diff --git a/bindings/dist/types/tari-indexer-client/GetIdentityResponse.js b/bindings/dist/types/tari-indexer-client/GetIdentityResponse.js deleted file mode 100644 index e5b481d1e..000000000 --- a/bindings/dist/types/tari-indexer-client/GetIdentityResponse.js +++ /dev/null @@ -1,2 +0,0 @@ -// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually. -export {}; diff --git a/bindings/dist/types/tari-indexer-client/GetSubstateRequest.d.ts b/bindings/dist/types/tari-indexer-client/GetSubstateRequest.d.ts deleted file mode 100644 index e3d9cdead..000000000 --- a/bindings/dist/types/tari-indexer-client/GetSubstateRequest.d.ts +++ /dev/null @@ -1,6 +0,0 @@ -import type { SubstateId } from "../SubstateId"; -export interface GetSubstateRequest { - address: SubstateId; - version: number | null; - local_search_only: boolean; -} diff --git a/bindings/dist/types/tari-indexer-client/GetSubstateRequest.js b/bindings/dist/types/tari-indexer-client/GetSubstateRequest.js deleted file mode 100644 index cb0ff5c3b..000000000 --- a/bindings/dist/types/tari-indexer-client/GetSubstateRequest.js +++ /dev/null @@ -1 +0,0 @@ -export {}; diff --git a/bindings/dist/types/tari-indexer-client/GetSubstateResponse.d.ts b/bindings/dist/types/tari-indexer-client/GetSubstateResponse.d.ts deleted file mode 100644 index b55ef6b5a..000000000 --- a/bindings/dist/types/tari-indexer-client/GetSubstateResponse.d.ts +++ /dev/null @@ -1,8 +0,0 @@ -import type { Substate } from "../Substate"; -import type { SubstateId } from "../SubstateId"; -export interface GetSubstateResponse { - address: SubstateId; - version: number; - substate: Substate; - created_by_transaction: string; -} diff --git a/bindings/dist/types/tari-indexer-client/GetSubstateResponse.js b/bindings/dist/types/tari-indexer-client/GetSubstateResponse.js deleted file mode 100644 index cb0ff5c3b..000000000 --- a/bindings/dist/types/tari-indexer-client/GetSubstateResponse.js +++ /dev/null @@ -1 +0,0 @@ -export {}; diff --git a/bindings/dist/types/tari-indexer-client/GetTransactionResultRequest.d.ts b/bindings/dist/types/tari-indexer-client/GetTransactionResultRequest.d.ts deleted file mode 100644 index 1d606964f..000000000 --- a/bindings/dist/types/tari-indexer-client/GetTransactionResultRequest.d.ts +++ /dev/null @@ -1,3 +0,0 @@ -export interface GetTransactionResultRequest { - transaction_id: string; -} diff --git a/bindings/dist/types/tari-indexer-client/GetTransactionResultRequest.js b/bindings/dist/types/tari-indexer-client/GetTransactionResultRequest.js deleted file mode 100644 index e5b481d1e..000000000 --- a/bindings/dist/types/tari-indexer-client/GetTransactionResultRequest.js +++ /dev/null @@ -1,2 +0,0 @@ -// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually. -export {}; diff --git a/bindings/dist/types/tari-indexer-client/GetTransactionResultResponse.d.ts b/bindings/dist/types/tari-indexer-client/GetTransactionResultResponse.d.ts deleted file mode 100644 index f24ceacec..000000000 --- a/bindings/dist/types/tari-indexer-client/GetTransactionResultResponse.d.ts +++ /dev/null @@ -1,4 +0,0 @@ -import type { IndexerTransactionFinalizedResult } from "./IndexerTransactionFinalizedResult"; -export interface GetTransactionResultResponse { - result: IndexerTransactionFinalizedResult; -} diff --git a/bindings/dist/types/tari-indexer-client/GetTransactionResultResponse.js b/bindings/dist/types/tari-indexer-client/GetTransactionResultResponse.js deleted file mode 100644 index cb0ff5c3b..000000000 --- a/bindings/dist/types/tari-indexer-client/GetTransactionResultResponse.js +++ /dev/null @@ -1 +0,0 @@ -export {}; diff --git a/bindings/dist/types/tari-indexer-client/SubmitTransactionRequest.d.ts b/bindings/dist/types/tari-indexer-client/SubmitTransactionRequest.d.ts deleted file mode 100644 index c4e127552..000000000 --- a/bindings/dist/types/tari-indexer-client/SubmitTransactionRequest.d.ts +++ /dev/null @@ -1,7 +0,0 @@ -import type { SubstateRequirement } from "../SubstateRequirement"; -import type { Transaction } from "../Transaction"; -export interface SubmitTransactionRequest { - transaction: Transaction; - required_substates: Array; - is_dry_run: boolean; -} diff --git a/bindings/dist/types/tari-indexer-client/SubmitTransactionRequest.js b/bindings/dist/types/tari-indexer-client/SubmitTransactionRequest.js deleted file mode 100644 index cb0ff5c3b..000000000 --- a/bindings/dist/types/tari-indexer-client/SubmitTransactionRequest.js +++ /dev/null @@ -1 +0,0 @@ -export {}; diff --git a/bindings/dist/types/tari-indexer-client/SubmitTransactionResponse.d.ts b/bindings/dist/types/tari-indexer-client/SubmitTransactionResponse.d.ts deleted file mode 100644 index a0eeec4d3..000000000 --- a/bindings/dist/types/tari-indexer-client/SubmitTransactionResponse.d.ts +++ /dev/null @@ -1,5 +0,0 @@ -import type { IndexerTransactionFinalizedResult } from "./IndexerTransactionFinalizedResult"; -export interface SubmitTransactionResponse { - transaction_id: string; - result: IndexerTransactionFinalizedResult; -} diff --git a/bindings/dist/types/tari-indexer-client/SubmitTransactionResponse.js b/bindings/dist/types/tari-indexer-client/SubmitTransactionResponse.js deleted file mode 100644 index cb0ff5c3b..000000000 --- a/bindings/dist/types/tari-indexer-client/SubmitTransactionResponse.js +++ /dev/null @@ -1 +0,0 @@ -export {}; diff --git a/bindings/dist/types/validator-node-client/AddPeerRequest.d.ts b/bindings/dist/types/validator-node-client/AddPeerRequest.d.ts deleted file mode 100644 index b4ee7b776..000000000 --- a/bindings/dist/types/validator-node-client/AddPeerRequest.d.ts +++ /dev/null @@ -1,5 +0,0 @@ -export interface AddPeerRequest { - public_key: string; - addresses: Array; - wait_for_dial: boolean; -} diff --git a/bindings/dist/types/validator-node-client/AddPeerRequest.js b/bindings/dist/types/validator-node-client/AddPeerRequest.js deleted file mode 100644 index e5b481d1e..000000000 --- a/bindings/dist/types/validator-node-client/AddPeerRequest.js +++ /dev/null @@ -1,2 +0,0 @@ -// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually. -export {}; diff --git a/bindings/dist/types/validator-node-client/AddPeerResponse.d.ts b/bindings/dist/types/validator-node-client/AddPeerResponse.d.ts deleted file mode 100644 index bc71882d4..000000000 --- a/bindings/dist/types/validator-node-client/AddPeerResponse.d.ts +++ /dev/null @@ -1 +0,0 @@ -export type AddPeerResponse = Record; diff --git a/bindings/dist/types/validator-node-client/AddPeerResponse.js b/bindings/dist/types/validator-node-client/AddPeerResponse.js deleted file mode 100644 index e5b481d1e..000000000 --- a/bindings/dist/types/validator-node-client/AddPeerResponse.js +++ /dev/null @@ -1,2 +0,0 @@ -// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually. -export {}; diff --git a/bindings/dist/types/validator-node-client/ArgDef.d.ts b/bindings/dist/types/validator-node-client/ArgDef.d.ts deleted file mode 100644 index 1e95c8598..000000000 --- a/bindings/dist/types/validator-node-client/ArgDef.d.ts +++ /dev/null @@ -1,4 +0,0 @@ -export interface ArgDef { - name: string; - arg_type: string; -} diff --git a/bindings/dist/types/validator-node-client/ArgDef.js b/bindings/dist/types/validator-node-client/ArgDef.js deleted file mode 100644 index e5b481d1e..000000000 --- a/bindings/dist/types/validator-node-client/ArgDef.js +++ /dev/null @@ -1,2 +0,0 @@ -// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually. -export {}; diff --git a/bindings/dist/types/validator-node-client/CommitteeShardInfo.d.ts b/bindings/dist/types/validator-node-client/CommitteeShardInfo.d.ts deleted file mode 100644 index 6fc8518e7..000000000 --- a/bindings/dist/types/validator-node-client/CommitteeShardInfo.d.ts +++ /dev/null @@ -1,10 +0,0 @@ -import type { SubstateAddress } from "../SubstateAddress"; -import type { ValidatorNode } from "./ValidatorNode"; -export interface CommitteeShardInfo { - shard: number; - substate_address_range: { - start: SubstateAddress; - end: SubstateAddress; - }; - validators: Array; -} diff --git a/bindings/dist/types/validator-node-client/CommitteeShardInfo.js b/bindings/dist/types/validator-node-client/CommitteeShardInfo.js deleted file mode 100644 index cb0ff5c3b..000000000 --- a/bindings/dist/types/validator-node-client/CommitteeShardInfo.js +++ /dev/null @@ -1 +0,0 @@ -export {}; diff --git a/bindings/dist/types/validator-node-client/Connection.d.ts b/bindings/dist/types/validator-node-client/Connection.d.ts deleted file mode 100644 index 7062400fb..000000000 --- a/bindings/dist/types/validator-node-client/Connection.d.ts +++ /dev/null @@ -1,16 +0,0 @@ -import type { ConnectionDirection } from "./ConnectionDirection"; -export interface Connection { - connection_id: string; - peer_id: string; - address: string; - direction: ConnectionDirection; - age: { - secs: number; - nanos: number; - }; - ping_latency: { - secs: number; - nanos: number; - } | null; - user_agent: string | null; -} diff --git a/bindings/dist/types/validator-node-client/Connection.js b/bindings/dist/types/validator-node-client/Connection.js deleted file mode 100644 index cb0ff5c3b..000000000 --- a/bindings/dist/types/validator-node-client/Connection.js +++ /dev/null @@ -1 +0,0 @@ -export {}; diff --git a/bindings/dist/types/validator-node-client/ConnectionDirection.d.ts b/bindings/dist/types/validator-node-client/ConnectionDirection.d.ts deleted file mode 100644 index 2724420af..000000000 --- a/bindings/dist/types/validator-node-client/ConnectionDirection.d.ts +++ /dev/null @@ -1 +0,0 @@ -export type ConnectionDirection = "Inbound" | "Outbound"; diff --git a/bindings/dist/types/validator-node-client/ConnectionDirection.js b/bindings/dist/types/validator-node-client/ConnectionDirection.js deleted file mode 100644 index e5b481d1e..000000000 --- a/bindings/dist/types/validator-node-client/ConnectionDirection.js +++ /dev/null @@ -1,2 +0,0 @@ -// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually. -export {}; diff --git a/bindings/dist/types/validator-node-client/FunctionDef.d.ts b/bindings/dist/types/validator-node-client/FunctionDef.d.ts deleted file mode 100644 index e741620ae..000000000 --- a/bindings/dist/types/validator-node-client/FunctionDef.d.ts +++ /dev/null @@ -1,7 +0,0 @@ -import type { ArgDef } from "./ArgDef"; -export interface FunctionDef { - name: string; - arguments: Array; - output: string; - is_mut: boolean; -} diff --git a/bindings/dist/types/validator-node-client/FunctionDef.js b/bindings/dist/types/validator-node-client/FunctionDef.js deleted file mode 100644 index cb0ff5c3b..000000000 --- a/bindings/dist/types/validator-node-client/FunctionDef.js +++ /dev/null @@ -1 +0,0 @@ -export {}; diff --git a/bindings/dist/types/validator-node-client/GetAllVnsRequest.d.ts b/bindings/dist/types/validator-node-client/GetAllVnsRequest.d.ts deleted file mode 100644 index 192cce8bb..000000000 --- a/bindings/dist/types/validator-node-client/GetAllVnsRequest.d.ts +++ /dev/null @@ -1,4 +0,0 @@ -import type { Epoch } from "../Epoch"; -export interface GetAllVnsRequest { - epoch: Epoch; -} diff --git a/bindings/dist/types/validator-node-client/GetAllVnsRequest.js b/bindings/dist/types/validator-node-client/GetAllVnsRequest.js deleted file mode 100644 index cb0ff5c3b..000000000 --- a/bindings/dist/types/validator-node-client/GetAllVnsRequest.js +++ /dev/null @@ -1 +0,0 @@ -export {}; diff --git a/bindings/dist/types/validator-node-client/GetAllVnsResponse.d.ts b/bindings/dist/types/validator-node-client/GetAllVnsResponse.d.ts deleted file mode 100644 index 41eb9f7eb..000000000 --- a/bindings/dist/types/validator-node-client/GetAllVnsResponse.d.ts +++ /dev/null @@ -1,4 +0,0 @@ -import type { BaseLayerValidatorNode } from "../base-node-client/BaseLayerValidatorNode"; -export interface GetAllVnsResponse { - vns: Array; -} diff --git a/bindings/dist/types/validator-node-client/GetAllVnsResponse.js b/bindings/dist/types/validator-node-client/GetAllVnsResponse.js deleted file mode 100644 index cb0ff5c3b..000000000 --- a/bindings/dist/types/validator-node-client/GetAllVnsResponse.js +++ /dev/null @@ -1 +0,0 @@ -export {}; diff --git a/bindings/dist/types/validator-node-client/GetCommsStatsResponse.d.ts b/bindings/dist/types/validator-node-client/GetCommsStatsResponse.d.ts deleted file mode 100644 index eb94a57b1..000000000 --- a/bindings/dist/types/validator-node-client/GetCommsStatsResponse.d.ts +++ /dev/null @@ -1,3 +0,0 @@ -export interface GetCommsStatsResponse { - connection_status: string; -} diff --git a/bindings/dist/types/validator-node-client/GetCommsStatsResponse.js b/bindings/dist/types/validator-node-client/GetCommsStatsResponse.js deleted file mode 100644 index e5b481d1e..000000000 --- a/bindings/dist/types/validator-node-client/GetCommsStatsResponse.js +++ /dev/null @@ -1,2 +0,0 @@ -// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually. -export {}; diff --git a/bindings/dist/types/validator-node-client/GetConnectionsResponse.d.ts b/bindings/dist/types/validator-node-client/GetConnectionsResponse.d.ts deleted file mode 100644 index af26db631..000000000 --- a/bindings/dist/types/validator-node-client/GetConnectionsResponse.d.ts +++ /dev/null @@ -1,4 +0,0 @@ -import type { Connection } from "./Connection"; -export interface GetConnectionsResponse { - connections: Array; -} diff --git a/bindings/dist/types/validator-node-client/GetConnectionsResponse.js b/bindings/dist/types/validator-node-client/GetConnectionsResponse.js deleted file mode 100644 index cb0ff5c3b..000000000 --- a/bindings/dist/types/validator-node-client/GetConnectionsResponse.js +++ /dev/null @@ -1 +0,0 @@ -export {}; diff --git a/bindings/dist/types/validator-node-client/GetIdentityResponse.d.ts b/bindings/dist/types/validator-node-client/GetIdentityResponse.d.ts deleted file mode 100644 index cfa1a62cc..000000000 --- a/bindings/dist/types/validator-node-client/GetIdentityResponse.d.ts +++ /dev/null @@ -1,8 +0,0 @@ -export interface GetIdentityResponse { - peer_id: string; - public_key: string; - public_addresses: Array; - supported_protocols: Array; - protocol_version: string; - user_agent: string; -} diff --git a/bindings/dist/types/validator-node-client/GetIdentityResponse.js b/bindings/dist/types/validator-node-client/GetIdentityResponse.js deleted file mode 100644 index e5b481d1e..000000000 --- a/bindings/dist/types/validator-node-client/GetIdentityResponse.js +++ /dev/null @@ -1,2 +0,0 @@ -// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually. -export {}; diff --git a/bindings/dist/types/validator-node-client/GetSubstateRequest.d.ts b/bindings/dist/types/validator-node-client/GetSubstateRequest.d.ts deleted file mode 100644 index a6b189487..000000000 --- a/bindings/dist/types/validator-node-client/GetSubstateRequest.d.ts +++ /dev/null @@ -1,5 +0,0 @@ -import type { SubstateId } from "../SubstateId"; -export interface GetSubstateRequest { - address: SubstateId; - version: number; -} diff --git a/bindings/dist/types/validator-node-client/GetSubstateRequest.js b/bindings/dist/types/validator-node-client/GetSubstateRequest.js deleted file mode 100644 index cb0ff5c3b..000000000 --- a/bindings/dist/types/validator-node-client/GetSubstateRequest.js +++ /dev/null @@ -1 +0,0 @@ -export {}; diff --git a/bindings/dist/types/validator-node-client/GetSubstateResponse.d.ts b/bindings/dist/types/validator-node-client/GetSubstateResponse.d.ts deleted file mode 100644 index eaf15e942..000000000 --- a/bindings/dist/types/validator-node-client/GetSubstateResponse.d.ts +++ /dev/null @@ -1,7 +0,0 @@ -import type { SubstateStatus } from "./SubstateStatus"; -import type { SubstateValue } from "../SubstateValue"; -export interface GetSubstateResponse { - value: SubstateValue | null; - created_by_tx: string | null; - status: SubstateStatus; -} diff --git a/bindings/dist/types/validator-node-client/GetSubstateResponse.js b/bindings/dist/types/validator-node-client/GetSubstateResponse.js deleted file mode 100644 index cb0ff5c3b..000000000 --- a/bindings/dist/types/validator-node-client/GetSubstateResponse.js +++ /dev/null @@ -1 +0,0 @@ -export {}; diff --git a/bindings/dist/types/validator-node-client/GetTransactionResultRequest.d.ts b/bindings/dist/types/validator-node-client/GetTransactionResultRequest.d.ts deleted file mode 100644 index 1d606964f..000000000 --- a/bindings/dist/types/validator-node-client/GetTransactionResultRequest.d.ts +++ /dev/null @@ -1,3 +0,0 @@ -export interface GetTransactionResultRequest { - transaction_id: string; -} diff --git a/bindings/dist/types/validator-node-client/GetTransactionResultRequest.js b/bindings/dist/types/validator-node-client/GetTransactionResultRequest.js deleted file mode 100644 index e5b481d1e..000000000 --- a/bindings/dist/types/validator-node-client/GetTransactionResultRequest.js +++ /dev/null @@ -1,2 +0,0 @@ -// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually. -export {}; diff --git a/bindings/dist/types/validator-node-client/GetTransactionResultResponse.d.ts b/bindings/dist/types/validator-node-client/GetTransactionResultResponse.d.ts deleted file mode 100644 index b3f1f7714..000000000 --- a/bindings/dist/types/validator-node-client/GetTransactionResultResponse.d.ts +++ /dev/null @@ -1,14 +0,0 @@ -import type { Decision } from "../Decision"; -import type { ExecuteResult } from "../ExecuteResult"; -export interface GetTransactionResultResponse { - result: ExecuteResult | null; - final_decision: Decision | null; - finalized_time: { - secs: number; - nanos: number; - } | null; - execution_time: { - secs: number; - nanos: number; - } | null; -} diff --git a/bindings/dist/types/validator-node-client/GetTransactionResultResponse.js b/bindings/dist/types/validator-node-client/GetTransactionResultResponse.js deleted file mode 100644 index cb0ff5c3b..000000000 --- a/bindings/dist/types/validator-node-client/GetTransactionResultResponse.js +++ /dev/null @@ -1 +0,0 @@ -export {}; diff --git a/bindings/dist/types/validator-node-client/LogEntry.d.ts b/bindings/dist/types/validator-node-client/LogEntry.d.ts deleted file mode 100644 index 80f43a450..000000000 --- a/bindings/dist/types/validator-node-client/LogEntry.d.ts +++ /dev/null @@ -1,6 +0,0 @@ -import type { LogLevel } from "./LogLevel"; -export interface LogEntry { - timestamp: number; - message: string; - level: LogLevel; -} diff --git a/bindings/dist/types/validator-node-client/LogEntry.js b/bindings/dist/types/validator-node-client/LogEntry.js deleted file mode 100644 index cb0ff5c3b..000000000 --- a/bindings/dist/types/validator-node-client/LogEntry.js +++ /dev/null @@ -1 +0,0 @@ -export {}; diff --git a/bindings/dist/types/validator-node-client/LogLevel.d.ts b/bindings/dist/types/validator-node-client/LogLevel.d.ts deleted file mode 100644 index 58fb38783..000000000 --- a/bindings/dist/types/validator-node-client/LogLevel.d.ts +++ /dev/null @@ -1 +0,0 @@ -export type LogLevel = "Error" | "Warn" | "Info" | "Debug"; diff --git a/bindings/dist/types/validator-node-client/LogLevel.js b/bindings/dist/types/validator-node-client/LogLevel.js deleted file mode 100644 index e5b481d1e..000000000 --- a/bindings/dist/types/validator-node-client/LogLevel.js +++ /dev/null @@ -1,2 +0,0 @@ -// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually. -export {}; diff --git a/bindings/dist/types/validator-node-client/SubmitTransactionRequest.d.ts b/bindings/dist/types/validator-node-client/SubmitTransactionRequest.d.ts deleted file mode 100644 index 570305779..000000000 --- a/bindings/dist/types/validator-node-client/SubmitTransactionRequest.d.ts +++ /dev/null @@ -1,5 +0,0 @@ -import type { Transaction } from "../Transaction"; -export interface SubmitTransactionRequest { - transaction: Transaction; - is_dry_run: boolean; -} diff --git a/bindings/dist/types/validator-node-client/SubmitTransactionRequest.js b/bindings/dist/types/validator-node-client/SubmitTransactionRequest.js deleted file mode 100644 index cb0ff5c3b..000000000 --- a/bindings/dist/types/validator-node-client/SubmitTransactionRequest.js +++ /dev/null @@ -1 +0,0 @@ -export {}; diff --git a/bindings/dist/types/validator-node-client/SubmitTransactionResponse.d.ts b/bindings/dist/types/validator-node-client/SubmitTransactionResponse.d.ts deleted file mode 100644 index 4fc5bd534..000000000 --- a/bindings/dist/types/validator-node-client/SubmitTransactionResponse.d.ts +++ /dev/null @@ -1,5 +0,0 @@ -import type { DryRunTransactionFinalizeResult } from "./DryRunTransactionFinalizeResult"; -export interface SubmitTransactionResponse { - transaction_id: string; - dry_run_result: DryRunTransactionFinalizeResult | null; -} diff --git a/bindings/dist/types/validator-node-client/SubmitTransactionResponse.js b/bindings/dist/types/validator-node-client/SubmitTransactionResponse.js deleted file mode 100644 index cb0ff5c3b..000000000 --- a/bindings/dist/types/validator-node-client/SubmitTransactionResponse.js +++ /dev/null @@ -1 +0,0 @@ -export {}; diff --git a/bindings/src/index.ts b/bindings/src/index.ts index 1d73647b3..aa672d944 100644 --- a/bindings/src/index.ts +++ b/bindings/src/index.ts @@ -1,1100 +1,6 @@ // Copyright 2023 The Tari Project // SPDX-License-Identifier: BSD-3-Clause -export * from "./types/AccessRule"; -export * from "./types/Account"; -export * from "./types/Amount"; -export * from "./types/ArgDef"; -export * from "./types/Arg"; -export * from "./types/AuthHook"; -export * from "./types/Block"; -export * from "./types/BucketId"; -export * from "./types/Claims"; -export * from "./types/Command"; -export * from "./types/CommitteeInfo"; -export * from "./types/CommitteeShardInfo"; -export * from "./types/Committee"; -export * from "./types/ComponentAccessRules"; -export * from "./types/ComponentAddress"; -export * from "./types/ComponentBody"; -export * from "./types/ComponentHeader"; -export * from "./types/ComponentKey"; -export * from "./types/ConfidentialClaim"; -export * from "./types/ConfidentialOutputStatement"; -export * from "./types/ConfidentialOutput"; -export * from "./types/ConfidentialStatement"; -export * from "./types/ConfidentialTransferInputSelection"; -export * from "./types/ConfidentialWithdrawProof"; -export * from "./types/Decision"; -export * from "./types/ElgamalVerifiableBalance"; -export * from "./types/EntityId"; -export * from "./types/Epoch"; -export * from "./types/Event"; -export * from "./types/Evidence"; -export * from "./types/ExecutedTransaction"; -export * from "./types/ExecuteResult"; -export * from "./types/FeeBreakdown"; -export * from "./types/FeeClaimAddress"; -export * from "./types/FeeClaim"; -export * from "./types/FeeCostBreakdown"; -export * from "./types/FeeReceipt"; -export * from "./types/FeeSource"; -export * from "./types/FinalizeResult"; -export * from "./types/ForeignProposalState"; -export * from "./types/ForeignProposal"; -export * from "./types/FunctionDef"; -export * from "./types/IndexedValue"; -export * from "./types/IndexedWellKnownTypes"; -export * from "./types/InstructionResult"; -export * from "./types/Instruction"; -export * from "./types/JrpcPermissions"; -export * from "./types/JrpcPermission"; -export * from "./types/LeaderFee"; -export * from "./types/LockFlag"; -export * from "./types/LogEntry"; -export * from "./types/LogLevel"; -export * from "./types/Metadata"; -export * from "./types/NetworkCommitteeInfo"; -export * from "./types/NodeHeight"; -export * from "./types/NonFungibleAddressContents"; -export * from "./types/NonFungibleAddress"; -export * from "./types/NonFungibleContainer"; -export * from "./types/NonFungibleId"; -export * from "./types/NonFungibleIndexAddress"; -export * from "./types/NonFungibleIndex"; -export * from "./types/NonFungibleToken"; -export * from "./types/NonFungible"; -export * from "./types/NumPreshards"; -export * from "./types/Ordering"; -export * from "./types/OwnerRule"; -export * from "./types/PeerAddress"; -export * from "./types/ProofId"; -export * from "./types/QuorumCertificate"; -export * from "./types/QuorumDecision"; -export * from "./types/RejectReason"; -export * from "./types/RequireRule"; -export * from "./types/ResourceAccessRules"; -export * from "./types/ResourceAddress"; -export * from "./types/ResourceContainer"; -export * from "./types/Resource"; -export * from "./types/ResourceType"; -export * from "./types/RestrictedAccessRule"; -export * from "./types/RuleRequirement"; -export * from "./types/ShardEvidence"; -export * from "./types/ShardGroup"; -export * from "./types/Shard"; -export * from "./types/SubstateAddress"; -export * from "./types/SubstateDestroyed"; -export * from "./types/SubstateDiff"; -export * from "./types/SubstateId"; -export * from "./types/SubstateLockFlag"; -export * from "./types/SubstateRecord"; -export * from "./types/SubstateRequirement"; -export * from "./types/Substate"; -export * from "./types/SubstateType"; -export * from "./types/SubstateValue"; -export * from "./types/TemplateDef"; -export * from "./types/TemplateDefV1"; -export * from "./types/TransactionAtom"; -export * from "./types/TransactionPoolRecord"; -export * from "./types/TransactionPoolStage"; -export * from "./types/TransactionReceiptAddress"; -export * from "./types/TransactionReceipt"; -export * from "./types/TransactionResult"; -export * from "./types/TransactionSignature"; -export * from "./types/TransactionStatus"; -export * from "./types/Transaction"; -export * from "./types/Type"; -export * from "./types/UnclaimedConfidentialOutput"; -export * from "./types/UnsignedTransaction"; -export * from "./types/ValidatorSignature"; -export * from "./types/VaultId"; -export * from "./types/Vault"; -export * from "./types/VersionedSubstateIdLockIntent"; -export * from "./types/VersionedSubstateId"; -export * from "./types/ViewableBalanceProof"; -export * from "./base-node-client"; -export * from "./tari-indexer-client"; -export * from "./validator-node-client"; -export * from "./wallet-daemon-client"; -export * from "./helpers/helpers"; -// Copyright 2023 The Tari Project -// SPDX-License-Identifier: BSD-3-Clause - -export * from "./types/AccessRule"; -export * from "./types/Account"; -export * from "./types/Amount"; -export * from "./types/ArgDef"; -export * from "./types/Arg"; -export * from "./types/AuthHook"; -export * from "./types/Block"; -export * from "./types/BucketId"; -export * from "./types/Claims"; -export * from "./types/Command"; -export * from "./types/CommitteeInfo"; -export * from "./types/CommitteeShardInfo"; -export * from "./types/Committee"; -export * from "./types/ComponentAccessRules"; -export * from "./types/ComponentAddress"; -export * from "./types/ComponentBody"; -export * from "./types/ComponentHeader"; -export * from "./types/ComponentKey"; -export * from "./types/ConfidentialClaim"; -export * from "./types/ConfidentialOutputStatement"; -export * from "./types/ConfidentialOutput"; -export * from "./types/ConfidentialStatement"; -export * from "./types/ConfidentialTransferInputSelection"; -export * from "./types/ConfidentialWithdrawProof"; -export * from "./types/Decision"; -export * from "./types/ElgamalVerifiableBalance"; -export * from "./types/EntityId"; -export * from "./types/Epoch"; -export * from "./types/Event"; -export * from "./types/Evidence"; -export * from "./types/ExecutedTransaction"; -export * from "./types/ExecuteResult"; -export * from "./types/FeeBreakdown"; -export * from "./types/FeeClaimAddress"; -export * from "./types/FeeClaim"; -export * from "./types/FeeCostBreakdown"; -export * from "./types/FeeReceipt"; -export * from "./types/FeeSource"; -export * from "./types/FinalizeResult"; -export * from "./types/ForeignProposalState"; -export * from "./types/ForeignProposal"; -export * from "./types/FunctionDef"; -export * from "./types/IndexedValue"; -export * from "./types/IndexedWellKnownTypes"; -export * from "./types/InstructionResult"; -export * from "./types/Instruction"; -export * from "./types/JrpcPermissions"; -export * from "./types/JrpcPermission"; -export * from "./types/LeaderFee"; -export * from "./types/LockFlag"; -export * from "./types/LogEntry"; -export * from "./types/LogLevel"; -export * from "./types/Metadata"; -export * from "./types/NetworkCommitteeInfo"; -export * from "./types/NodeHeight"; -export * from "./types/NonFungibleAddressContents"; -export * from "./types/NonFungibleAddress"; -export * from "./types/NonFungibleContainer"; -export * from "./types/NonFungibleId"; -export * from "./types/NonFungibleIndexAddress"; -export * from "./types/NonFungibleIndex"; -export * from "./types/NonFungibleToken"; -export * from "./types/NonFungible"; -export * from "./types/NumPreshards"; -export * from "./types/Ordering"; -export * from "./types/OwnerRule"; -export * from "./types/PeerAddress"; -export * from "./types/ProofId"; -export * from "./types/QuorumCertificate"; -export * from "./types/QuorumDecision"; -export * from "./types/RejectReason"; -export * from "./types/RequireRule"; -export * from "./types/ResourceAccessRules"; -export * from "./types/ResourceAddress"; -export * from "./types/ResourceContainer"; -export * from "./types/Resource"; -export * from "./types/ResourceType"; -export * from "./types/RestrictedAccessRule"; -export * from "./types/RuleRequirement"; -export * from "./types/ShardEvidence"; -export * from "./types/ShardGroup"; -export * from "./types/Shard"; -export * from "./types/SubstateAddress"; -export * from "./types/SubstateDestroyed"; -export * from "./types/SubstateDiff"; -export * from "./types/SubstateId"; -export * from "./types/SubstateLockFlag"; -export * from "./types/SubstateRecord"; -export * from "./types/SubstateRequirement"; -export * from "./types/Substate"; -export * from "./types/SubstateType"; -export * from "./types/SubstateValue"; -export * from "./types/TemplateDef"; -export * from "./types/TemplateDefV1"; -export * from "./types/TransactionAtom"; -export * from "./types/TransactionPoolRecord"; -export * from "./types/TransactionPoolStage"; -export * from "./types/TransactionReceiptAddress"; -export * from "./types/TransactionReceipt"; -export * from "./types/TransactionResult"; -export * from "./types/TransactionSignature"; -export * from "./types/TransactionStatus"; -export * from "./types/Transaction"; -export * from "./types/Type"; -export * from "./types/UnclaimedConfidentialOutput"; -export * from "./types/UnsignedTransaction"; -export * from "./types/ValidatorSignature"; -export * from "./types/VaultId"; -export * from "./types/Vault"; -export * from "./types/VersionedSubstateIdLockIntent"; -export * from "./types/VersionedSubstateId"; -export * from "./types/ViewableBalanceProof"; -export * from "./base-node-client"; -export * from "./tari-indexer-client"; -export * from "./validator-node-client"; -export * from "./wallet-daemon-client"; -export * from "./helpers/helpers"; -// Copyright 2023 The Tari Project -// SPDX-License-Identifier: BSD-3-Clause - -export * from "./types/AccessRule"; -export * from "./types/Account"; -export * from "./types/Amount"; -export * from "./types/ArgDef"; -export * from "./types/Arg"; -export * from "./types/AuthHook"; -export * from "./types/Block"; -export * from "./types/BucketId"; -export * from "./types/Claims"; -export * from "./types/Command"; -export * from "./types/CommitteeInfo"; -export * from "./types/CommitteeShardInfo"; -export * from "./types/Committee"; -export * from "./types/ComponentAccessRules"; -export * from "./types/ComponentAddress"; -export * from "./types/ComponentBody"; -export * from "./types/ComponentHeader"; -export * from "./types/ComponentKey"; -export * from "./types/ConfidentialClaim"; -export * from "./types/ConfidentialOutputStatement"; -export * from "./types/ConfidentialOutput"; -export * from "./types/ConfidentialStatement"; -export * from "./types/ConfidentialTransferInputSelection"; -export * from "./types/ConfidentialWithdrawProof"; -export * from "./types/Decision"; -export * from "./types/ElgamalVerifiableBalance"; -export * from "./types/EntityId"; -export * from "./types/Epoch"; -export * from "./types/Event"; -export * from "./types/Evidence"; -export * from "./types/ExecutedTransaction"; -export * from "./types/ExecuteResult"; -export * from "./types/FeeBreakdown"; -export * from "./types/FeeClaimAddress"; -export * from "./types/FeeClaim"; -export * from "./types/FeeCostBreakdown"; -export * from "./types/FeeReceipt"; -export * from "./types/FeeSource"; -export * from "./types/FinalizeResult"; -export * from "./types/ForeignProposalState"; -export * from "./types/ForeignProposal"; -export * from "./types/FunctionDef"; -export * from "./types/IndexedValue"; -export * from "./types/IndexedWellKnownTypes"; -export * from "./types/InstructionResult"; -export * from "./types/Instruction"; -export * from "./types/JrpcPermissions"; -export * from "./types/JrpcPermission"; -export * from "./types/LeaderFee"; -export * from "./types/LockFlag"; -export * from "./types/LogEntry"; -export * from "./types/LogLevel"; -export * from "./types/Metadata"; -export * from "./types/NetworkCommitteeInfo"; -export * from "./types/NodeHeight"; -export * from "./types/NonFungibleAddressContents"; -export * from "./types/NonFungibleAddress"; -export * from "./types/NonFungibleContainer"; -export * from "./types/NonFungibleId"; -export * from "./types/NonFungibleIndexAddress"; -export * from "./types/NonFungibleIndex"; -export * from "./types/NonFungibleToken"; -export * from "./types/NonFungible"; -export * from "./types/NumPreshards"; -export * from "./types/Ordering"; -export * from "./types/OwnerRule"; -export * from "./types/PeerAddress"; -export * from "./types/ProofId"; -export * from "./types/QuorumCertificate"; -export * from "./types/QuorumDecision"; -export * from "./types/RejectReason"; -export * from "./types/RequireRule"; -export * from "./types/ResourceAccessRules"; -export * from "./types/ResourceAddress"; -export * from "./types/ResourceContainer"; -export * from "./types/Resource"; -export * from "./types/ResourceType"; -export * from "./types/RestrictedAccessRule"; -export * from "./types/RuleRequirement"; -export * from "./types/ShardEvidence"; -export * from "./types/ShardGroup"; -export * from "./types/Shard"; -export * from "./types/SubstateAddress"; -export * from "./types/SubstateDestroyed"; -export * from "./types/SubstateDiff"; -export * from "./types/SubstateId"; -export * from "./types/SubstateLockFlag"; -export * from "./types/SubstateLockType"; -export * from "./types/SubstateRecord"; -export * from "./types/SubstateRequirement"; -export * from "./types/Substate"; -export * from "./types/SubstateType"; -export * from "./types/SubstateValue"; -export * from "./types/TemplateDef"; -export * from "./types/TemplateDefV1"; -export * from "./types/TransactionAtom"; -export * from "./types/TransactionPoolRecord"; -export * from "./types/TransactionPoolStage"; -export * from "./types/TransactionReceiptAddress"; -export * from "./types/TransactionReceipt"; -export * from "./types/TransactionResult"; -export * from "./types/TransactionSignature"; -export * from "./types/TransactionStatus"; -export * from "./types/Transaction"; -export * from "./types/Type"; -export * from "./types/UnclaimedConfidentialOutput"; -export * from "./types/UnsignedTransaction"; -export * from "./types/ValidatorSignature"; -export * from "./types/VaultId"; -export * from "./types/Vault"; -export * from "./types/VersionedSubstateIdLockIntent"; -export * from "./types/VersionedSubstateId"; -export * from "./types/ViewableBalanceProof"; -export * from "./base-node-client"; -export * from "./tari-indexer-client"; -export * from "./validator-node-client"; -export * from "./wallet-daemon-client"; -export * from "./helpers/helpers"; -// Copyright 2023 The Tari Project -// SPDX-License-Identifier: BSD-3-Clause - -export * from "./types/AccessRule"; -export * from "./types/Account"; -export * from "./types/Amount"; -export * from "./types/ArgDef"; -export * from "./types/Arg"; -export * from "./types/AuthHook"; -export * from "./types/Block"; -export * from "./types/BucketId"; -export * from "./types/Claims"; -export * from "./types/Command"; -export * from "./types/CommitteeInfo"; -export * from "./types/CommitteeShardInfo"; -export * from "./types/Committee"; -export * from "./types/ComponentAccessRules"; -export * from "./types/ComponentAddress"; -export * from "./types/ComponentBody"; -export * from "./types/ComponentHeader"; -export * from "./types/ComponentKey"; -export * from "./types/ConfidentialClaim"; -export * from "./types/ConfidentialOutputStatement"; -export * from "./types/ConfidentialOutput"; -export * from "./types/ConfidentialStatement"; -export * from "./types/ConfidentialTransferInputSelection"; -export * from "./types/ConfidentialWithdrawProof"; -export * from "./types/Decision"; -export * from "./types/ElgamalVerifiableBalance"; -export * from "./types/EntityId"; -export * from "./types/Epoch"; -export * from "./types/Event"; -export * from "./types/Evidence"; -export * from "./types/ExecutedTransaction"; -export * from "./types/ExecuteResult"; -export * from "./types/FeeBreakdown"; -export * from "./types/FeeClaimAddress"; -export * from "./types/FeeClaim"; -export * from "./types/FeeCostBreakdown"; -export * from "./types/FeeReceipt"; -export * from "./types/FeeSource"; -export * from "./types/FinalizeResult"; -export * from "./types/ForeignProposalState"; -export * from "./types/ForeignProposal"; -export * from "./types/FunctionDef"; -export * from "./types/IndexedValue"; -export * from "./types/IndexedWellKnownTypes"; -export * from "./types/InstructionResult"; -export * from "./types/Instruction"; -export * from "./types/JrpcPermissions"; -export * from "./types/JrpcPermission"; -export * from "./types/LeaderFee"; -export * from "./types/LockFlag"; -export * from "./types/LogEntry"; -export * from "./types/LogLevel"; -export * from "./types/Metadata"; -export * from "./types/NetworkCommitteeInfo"; -export * from "./types/NodeHeight"; -export * from "./types/NonFungibleAddressContents"; -export * from "./types/NonFungibleAddress"; -export * from "./types/NonFungibleContainer"; -export * from "./types/NonFungibleId"; -export * from "./types/NonFungibleIndexAddress"; -export * from "./types/NonFungibleIndex"; -export * from "./types/NonFungibleToken"; -export * from "./types/NonFungible"; -export * from "./types/NumPreshards"; -export * from "./types/Ordering"; -export * from "./types/OwnerRule"; -export * from "./types/PeerAddress"; -export * from "./types/ProofId"; -export * from "./types/QuorumCertificate"; -export * from "./types/QuorumDecision"; -export * from "./types/RejectReason"; -export * from "./types/RequireRule"; -export * from "./types/ResourceAccessRules"; -export * from "./types/ResourceAddress"; -export * from "./types/ResourceContainer"; -export * from "./types/Resource"; -export * from "./types/ResourceType"; -export * from "./types/RestrictedAccessRule"; -export * from "./types/RuleRequirement"; -export * from "./types/ShardEvidence"; -export * from "./types/ShardGroup"; -export * from "./types/Shard"; -export * from "./types/SubstateAddress"; -export * from "./types/SubstateDestroyed"; -export * from "./types/SubstateDiff"; -export * from "./types/SubstateId"; -export * from "./types/SubstateLockFlag"; -export * from "./types/SubstateLockType"; -export * from "./types/SubstateRecord"; -export * from "./types/SubstateRequirement"; -export * from "./types/Substate"; -export * from "./types/SubstateType"; -export * from "./types/SubstateValue"; -export * from "./types/TemplateDef"; -export * from "./types/TemplateDefV1"; -export * from "./types/TransactionAtom"; -export * from "./types/TransactionPoolRecord"; -export * from "./types/TransactionPoolStage"; -export * from "./types/TransactionReceiptAddress"; -export * from "./types/TransactionReceipt"; -export * from "./types/TransactionResult"; -export * from "./types/TransactionSignature"; -export * from "./types/TransactionStatus"; -export * from "./types/Transaction"; -export * from "./types/Type"; -export * from "./types/UnclaimedConfidentialOutput"; -export * from "./types/UnsignedTransaction"; -export * from "./types/ValidatorSignature"; -export * from "./types/VaultId"; -export * from "./types/Vault"; -export * from "./types/VersionedSubstateIdLockIntent"; -export * from "./types/VersionedSubstateId"; -export * from "./types/ViewableBalanceProof"; -export * from "./base-node-client"; -export * from "./tari-indexer-client"; -export * from "./validator-node-client"; -export * from "./wallet-daemon-client"; -export * from "./helpers/helpers"; -// Copyright 2023 The Tari Project -// SPDX-License-Identifier: BSD-3-Clause - -export * from "./types/AccessRule"; -export * from "./types/Account"; -export * from "./types/Amount"; -export * from "./types/ArgDef"; -export * from "./types/Arg"; -export * from "./types/AuthHook"; -export * from "./types/Block"; -export * from "./types/BucketId"; -export * from "./types/Claims"; -export * from "./types/Command"; -export * from "./types/CommitteeInfo"; -export * from "./types/CommitteeShardInfo"; -export * from "./types/Committee"; -export * from "./types/ComponentAccessRules"; -export * from "./types/ComponentAddress"; -export * from "./types/ComponentBody"; -export * from "./types/ComponentHeader"; -export * from "./types/ComponentKey"; -export * from "./types/ConfidentialClaim"; -export * from "./types/ConfidentialOutputStatement"; -export * from "./types/ConfidentialOutput"; -export * from "./types/ConfidentialStatement"; -export * from "./types/ConfidentialTransferInputSelection"; -export * from "./types/ConfidentialWithdrawProof"; -export * from "./types/Decision"; -export * from "./types/ElgamalVerifiableBalance"; -export * from "./types/EntityId"; -export * from "./types/Epoch"; -export * from "./types/Event"; -export * from "./types/Evidence"; -export * from "./types/ExecutedTransaction"; -export * from "./types/ExecuteResult"; -export * from "./types/FeeBreakdown"; -export * from "./types/FeeClaimAddress"; -export * from "./types/FeeClaim"; -export * from "./types/FeeCostBreakdown"; -export * from "./types/FeeReceipt"; -export * from "./types/FeeSource"; -export * from "./types/FinalizeResult"; -export * from "./types/ForeignProposalState"; -export * from "./types/ForeignProposal"; -export * from "./types/FunctionDef"; -export * from "./types/IndexedValue"; -export * from "./types/IndexedWellKnownTypes"; -export * from "./types/InstructionResult"; -export * from "./types/Instruction"; -export * from "./types/JrpcPermissions"; -export * from "./types/JrpcPermission"; -export * from "./types/LeaderFee"; -export * from "./types/LockFlag"; -export * from "./types/LogEntry"; -export * from "./types/LogLevel"; -export * from "./types/Metadata"; -export * from "./types/NetworkCommitteeInfo"; -export * from "./types/NodeHeight"; -export * from "./types/NonFungibleAddressContents"; -export * from "./types/NonFungibleAddress"; -export * from "./types/NonFungibleContainer"; -export * from "./types/NonFungibleId"; -export * from "./types/NonFungibleIndexAddress"; -export * from "./types/NonFungibleIndex"; -export * from "./types/NonFungibleToken"; -export * from "./types/NonFungible"; -export * from "./types/NumPreshards"; -export * from "./types/Ordering"; -export * from "./types/OwnerRule"; -export * from "./types/PeerAddress"; -export * from "./types/ProofId"; -export * from "./types/QuorumCertificate"; -export * from "./types/QuorumDecision"; -export * from "./types/RejectReason"; -export * from "./types/RequireRule"; -export * from "./types/ResourceAccessRules"; -export * from "./types/ResourceAddress"; -export * from "./types/ResourceContainer"; -export * from "./types/Resource"; -export * from "./types/ResourceType"; -export * from "./types/RestrictedAccessRule"; -export * from "./types/RuleRequirement"; -export * from "./types/ShardEvidence"; -export * from "./types/ShardGroup"; -export * from "./types/Shard"; -export * from "./types/SubstateAddress"; -export * from "./types/SubstateDestroyed"; -export * from "./types/SubstateDiff"; -export * from "./types/SubstateId"; -export * from "./types/SubstateLockFlag"; -export * from "./types/SubstateLockType"; -export * from "./types/SubstateRecord"; -export * from "./types/SubstateRequirement"; -export * from "./types/Substate"; -export * from "./types/SubstateType"; -export * from "./types/SubstateValue"; -export * from "./types/TemplateDef"; -export * from "./types/TemplateDefV1"; -export * from "./types/TransactionAtom"; -export * from "./types/TransactionPoolRecord"; -export * from "./types/TransactionPoolStage"; -export * from "./types/TransactionReceiptAddress"; -export * from "./types/TransactionReceipt"; -export * from "./types/TransactionResult"; -export * from "./types/TransactionSignature"; -export * from "./types/TransactionStatus"; -export * from "./types/Transaction"; -export * from "./types/Type"; -export * from "./types/UnclaimedConfidentialOutput"; -export * from "./types/UnsignedTransaction"; -export * from "./types/ValidatorSignature"; -export * from "./types/VaultId"; -export * from "./types/Vault"; -export * from "./types/VersionedSubstateIdLockIntent"; -export * from "./types/VersionedSubstateId"; -export * from "./types/ViewableBalanceProof"; -export * from "./base-node-client"; -export * from "./tari-indexer-client"; -export * from "./validator-node-client"; -export * from "./wallet-daemon-client"; -export * from "./helpers/helpers"; -// Copyright 2023 The Tari Project -// SPDX-License-Identifier: BSD-3-Clause - -export * from "./types/AccessRule"; -export * from "./types/Account"; -export * from "./types/Amount"; -export * from "./types/ArgDef"; -export * from "./types/Arg"; -export * from "./types/AuthHook"; -export * from "./types/Block"; -export * from "./types/BucketId"; -export * from "./types/Claims"; -export * from "./types/Command"; -export * from "./types/CommitteeInfo"; -export * from "./types/CommitteeShardInfo"; -export * from "./types/Committee"; -export * from "./types/ComponentAccessRules"; -export * from "./types/ComponentAddress"; -export * from "./types/ComponentBody"; -export * from "./types/ComponentHeader"; -export * from "./types/ComponentKey"; -export * from "./types/ConfidentialClaim"; -export * from "./types/ConfidentialOutputStatement"; -export * from "./types/ConfidentialOutput"; -export * from "./types/ConfidentialStatement"; -export * from "./types/ConfidentialTransferInputSelection"; -export * from "./types/ConfidentialWithdrawProof"; -export * from "./types/Decision"; -export * from "./types/ElgamalVerifiableBalance"; -export * from "./types/EntityId"; -export * from "./types/Epoch"; -export * from "./types/Event"; -export * from "./types/Evidence"; -export * from "./types/ExecutedTransaction"; -export * from "./types/ExecuteResult"; -export * from "./types/FeeBreakdown"; -export * from "./types/FeeClaimAddress"; -export * from "./types/FeeClaim"; -export * from "./types/FeeCostBreakdown"; -export * from "./types/FeeReceipt"; -export * from "./types/FeeSource"; -export * from "./types/FinalizeResult"; -export * from "./types/ForeignProposalAtom"; -export * from "./types/ForeignProposalState"; -export * from "./types/ForeignProposal"; -export * from "./types/FunctionDef"; -export * from "./types/IndexedValue"; -export * from "./types/IndexedWellKnownTypes"; -export * from "./types/InstructionResult"; -export * from "./types/Instruction"; -export * from "./types/JrpcPermissions"; -export * from "./types/JrpcPermission"; -export * from "./types/LeaderFee"; -export * from "./types/LockFlag"; -export * from "./types/LogEntry"; -export * from "./types/LogLevel"; -export * from "./types/Metadata"; -export * from "./types/NetworkCommitteeInfo"; -export * from "./types/NodeHeight"; -export * from "./types/NonFungibleAddressContents"; -export * from "./types/NonFungibleAddress"; -export * from "./types/NonFungibleContainer"; -export * from "./types/NonFungibleId"; -export * from "./types/NonFungibleIndexAddress"; -export * from "./types/NonFungibleIndex"; -export * from "./types/NonFungibleToken"; -export * from "./types/NonFungible"; -export * from "./types/NumPreshards"; -export * from "./types/Ordering"; -export * from "./types/OwnerRule"; -export * from "./types/PeerAddress"; -export * from "./types/ProofId"; -export * from "./types/QuorumCertificate"; -export * from "./types/QuorumDecision"; -export * from "./types/RejectReason"; -export * from "./types/RequireRule"; -export * from "./types/ResourceAccessRules"; -export * from "./types/ResourceAddress"; -export * from "./types/ResourceContainer"; -export * from "./types/Resource"; -export * from "./types/ResourceType"; -export * from "./types/RestrictedAccessRule"; -export * from "./types/RuleRequirement"; -export * from "./types/ShardEvidence"; -export * from "./types/ShardGroup"; -export * from "./types/Shard"; -export * from "./types/SubstateAddress"; -export * from "./types/SubstateDestroyed"; -export * from "./types/SubstateDiff"; -export * from "./types/SubstateId"; -export * from "./types/SubstateLockFlag"; -export * from "./types/SubstateLockType"; -export * from "./types/SubstateRecord"; -export * from "./types/SubstateRequirement"; -export * from "./types/Substate"; -export * from "./types/SubstateType"; -export * from "./types/SubstateValue"; -export * from "./types/TemplateDef"; -export * from "./types/TemplateDefV1"; -export * from "./types/TransactionAtom"; -export * from "./types/TransactionPoolRecord"; -export * from "./types/TransactionPoolStage"; -export * from "./types/TransactionReceiptAddress"; -export * from "./types/TransactionReceipt"; -export * from "./types/TransactionResult"; -export * from "./types/TransactionSignature"; -export * from "./types/TransactionStatus"; -export * from "./types/Transaction"; -export * from "./types/Type"; -export * from "./types/UnclaimedConfidentialOutput"; -export * from "./types/UnsignedTransaction"; -export * from "./types/ValidatorSignature"; -export * from "./types/VaultId"; -export * from "./types/Vault"; -export * from "./types/VersionedSubstateIdLockIntent"; -export * from "./types/VersionedSubstateId"; -export * from "./types/ViewableBalanceProof"; -export * from "./base-node-client"; -export * from "./tari-indexer-client"; -export * from "./validator-node-client"; -export * from "./wallet-daemon-client"; -export * from "./helpers/helpers"; -// Copyright 2023 The Tari Project -// SPDX-License-Identifier: BSD-3-Clause - -export * from "./types/AccessRule"; -export * from "./types/Account"; -export * from "./types/Amount"; -export * from "./types/ArgDef"; -export * from "./types/Arg"; -export * from "./types/AuthHook"; -export * from "./types/Block"; -export * from "./types/BucketId"; -export * from "./types/Claims"; -export * from "./types/Command"; -export * from "./types/CommitteeInfo"; -export * from "./types/CommitteeShardInfo"; -export * from "./types/Committee"; -export * from "./types/ComponentAccessRules"; -export * from "./types/ComponentAddress"; -export * from "./types/ComponentBody"; -export * from "./types/ComponentHeader"; -export * from "./types/ComponentKey"; -export * from "./types/ConfidentialClaim"; -export * from "./types/ConfidentialOutputStatement"; -export * from "./types/ConfidentialOutput"; -export * from "./types/ConfidentialStatement"; -export * from "./types/ConfidentialTransferInputSelection"; -export * from "./types/ConfidentialWithdrawProof"; -export * from "./types/Decision"; -export * from "./types/ElgamalVerifiableBalance"; -export * from "./types/EntityId"; -export * from "./types/Epoch"; -export * from "./types/Event"; -export * from "./types/Evidence"; -export * from "./types/ExecutedTransaction"; -export * from "./types/ExecuteResult"; -export * from "./types/FeeBreakdown"; -export * from "./types/FeeClaimAddress"; -export * from "./types/FeeClaim"; -export * from "./types/FeeCostBreakdown"; -export * from "./types/FeeReceipt"; -export * from "./types/FeeSource"; -export * from "./types/FinalizeResult"; -export * from "./types/ForeignProposalAtom"; -export * from "./types/ForeignProposalState"; -export * from "./types/ForeignProposal"; -export * from "./types/FunctionDef"; -export * from "./types/IndexedValue"; -export * from "./types/IndexedWellKnownTypes"; -export * from "./types/InstructionResult"; -export * from "./types/Instruction"; -export * from "./types/JrpcPermissions"; -export * from "./types/JrpcPermission"; -export * from "./types/LeaderFee"; -export * from "./types/LockFlag"; -export * from "./types/LogEntry"; -export * from "./types/LogLevel"; -export * from "./types/Metadata"; -export * from "./types/NetworkCommitteeInfo"; -export * from "./types/NodeHeight"; -export * from "./types/NonFungibleAddressContents"; -export * from "./types/NonFungibleAddress"; -export * from "./types/NonFungibleContainer"; -export * from "./types/NonFungibleId"; -export * from "./types/NonFungibleIndexAddress"; -export * from "./types/NonFungibleIndex"; -export * from "./types/NonFungibleToken"; -export * from "./types/NonFungible"; -export * from "./types/NumPreshards"; -export * from "./types/Ordering"; -export * from "./types/OwnerRule"; -export * from "./types/PeerAddress"; -export * from "./types/ProofId"; -export * from "./types/QuorumCertificate"; -export * from "./types/QuorumDecision"; -export * from "./types/RejectReason"; -export * from "./types/RequireRule"; -export * from "./types/ResourceAccessRules"; -export * from "./types/ResourceAddress"; -export * from "./types/ResourceContainer"; -export * from "./types/Resource"; -export * from "./types/ResourceType"; -export * from "./types/RestrictedAccessRule"; -export * from "./types/RuleRequirement"; -export * from "./types/ShardEvidence"; -export * from "./types/ShardGroup"; -export * from "./types/Shard"; -export * from "./types/SubstateAddress"; -export * from "./types/SubstateDestroyed"; -export * from "./types/SubstateDiff"; -export * from "./types/SubstateId"; -export * from "./types/SubstateLockFlag"; -export * from "./types/SubstateLockType"; -export * from "./types/SubstateRecord"; -export * from "./types/SubstateRequirement"; -export * from "./types/Substate"; -export * from "./types/SubstateType"; -export * from "./types/SubstateValue"; -export * from "./types/TemplateDef"; -export * from "./types/TemplateDefV1"; -export * from "./types/TransactionAtom"; -export * from "./types/TransactionPoolRecord"; -export * from "./types/TransactionPoolStage"; -export * from "./types/TransactionReceiptAddress"; -export * from "./types/TransactionReceipt"; -export * from "./types/TransactionResult"; -export * from "./types/TransactionSignature"; -export * from "./types/TransactionStatus"; -export * from "./types/Transaction"; -export * from "./types/Type"; -export * from "./types/UnclaimedConfidentialOutput"; -export * from "./types/UnsignedTransaction"; -export * from "./types/ValidatorSignature"; -export * from "./types/VaultId"; -export * from "./types/Vault"; -export * from "./types/VersionedSubstateIdLockIntent"; -export * from "./types/VersionedSubstateId"; -export * from "./types/ViewableBalanceProof"; -export * from "./base-node-client"; -export * from "./tari-indexer-client"; -export * from "./validator-node-client"; -export * from "./wallet-daemon-client"; -export * from "./helpers/helpers"; -// Copyright 2023 The Tari Project -// SPDX-License-Identifier: BSD-3-Clause - -export * from "./types/AccessRule"; -export * from "./types/Account"; -export * from "./types/Amount"; -export * from "./types/ArgDef"; -export * from "./types/Arg"; -export * from "./types/AuthHook"; -export * from "./types/Block"; -export * from "./types/BucketId"; -export * from "./types/Claims"; -export * from "./types/Command"; -export * from "./types/CommitteeInfo"; -export * from "./types/CommitteeShardInfo"; -export * from "./types/Committee"; -export * from "./types/ComponentAccessRules"; -export * from "./types/ComponentAddress"; -export * from "./types/ComponentBody"; -export * from "./types/ComponentHeader"; -export * from "./types/ComponentKey"; -export * from "./types/ConfidentialClaim"; -export * from "./types/ConfidentialOutputStatement"; -export * from "./types/ConfidentialOutput"; -export * from "./types/ConfidentialStatement"; -export * from "./types/ConfidentialTransferInputSelection"; -export * from "./types/ConfidentialWithdrawProof"; -export * from "./types/Decision"; -export * from "./types/ElgamalVerifiableBalance"; -export * from "./types/EntityId"; -export * from "./types/Epoch"; -export * from "./types/Event"; -export * from "./types/Evidence"; -export * from "./types/ExecutedTransaction"; -export * from "./types/ExecuteResult"; -export * from "./types/FeeBreakdown"; -export * from "./types/FeeClaimAddress"; -export * from "./types/FeeClaim"; -export * from "./types/FeeCostBreakdown"; -export * from "./types/FeeReceipt"; -export * from "./types/FeeSource"; -export * from "./types/FinalizeResult"; -export * from "./types/ForeignProposalAtom"; -export * from "./types/ForeignProposalState"; -export * from "./types/ForeignProposal"; -export * from "./types/FunctionDef"; -export * from "./types/IndexedValue"; -export * from "./types/IndexedWellKnownTypes"; -export * from "./types/InstructionResult"; -export * from "./types/Instruction"; -export * from "./types/JrpcPermissions"; -export * from "./types/JrpcPermission"; -export * from "./types/LeaderFee"; -export * from "./types/LockFlag"; -export * from "./types/LogEntry"; -export * from "./types/LogLevel"; -export * from "./types/Metadata"; -export * from "./types/MintConfidentialOutputAtom"; -export * from "./types/NetworkCommitteeInfo"; -export * from "./types/NodeHeight"; -export * from "./types/NonFungibleAddressContents"; -export * from "./types/NonFungibleAddress"; -export * from "./types/NonFungibleContainer"; -export * from "./types/NonFungibleId"; -export * from "./types/NonFungibleIndexAddress"; -export * from "./types/NonFungibleIndex"; -export * from "./types/NonFungibleToken"; -export * from "./types/NonFungible"; -export * from "./types/NumPreshards"; -export * from "./types/Ordering"; -export * from "./types/OwnerRule"; -export * from "./types/PeerAddress"; -export * from "./types/ProofId"; -export * from "./types/QuorumCertificate"; -export * from "./types/QuorumDecision"; -export * from "./types/RejectReason"; -export * from "./types/RequireRule"; -export * from "./types/ResourceAccessRules"; -export * from "./types/ResourceAddress"; -export * from "./types/ResourceContainer"; -export * from "./types/Resource"; -export * from "./types/ResourceType"; -export * from "./types/RestrictedAccessRule"; -export * from "./types/RuleRequirement"; -export * from "./types/ShardEvidence"; -export * from "./types/ShardGroup"; -export * from "./types/Shard"; -export * from "./types/SubstateAddress"; -export * from "./types/SubstateDestroyed"; -export * from "./types/SubstateDiff"; -export * from "./types/SubstateId"; -export * from "./types/SubstateLockFlag"; -export * from "./types/SubstateLockType"; -export * from "./types/SubstateRecord"; -export * from "./types/SubstateRequirement"; -export * from "./types/Substate"; -export * from "./types/SubstateType"; -export * from "./types/SubstateValue"; -export * from "./types/TemplateDef"; -export * from "./types/TemplateDefV1"; -export * from "./types/TransactionAtom"; -export * from "./types/TransactionPoolRecord"; -export * from "./types/TransactionPoolStage"; -export * from "./types/TransactionReceiptAddress"; -export * from "./types/TransactionReceipt"; -export * from "./types/TransactionResult"; -export * from "./types/TransactionSignature"; -export * from "./types/TransactionStatus"; -export * from "./types/Transaction"; -export * from "./types/Type"; -export * from "./types/UnclaimedConfidentialOutput"; -export * from "./types/UnsignedTransaction"; -export * from "./types/ValidatorSignature"; -export * from "./types/VaultId"; -export * from "./types/Vault"; -export * from "./types/VersionedSubstateIdLockIntent"; -export * from "./types/VersionedSubstateId"; -export * from "./types/ViewableBalanceProof"; -export * from "./base-node-client"; -export * from "./tari-indexer-client"; -export * from "./validator-node-client"; -export * from "./wallet-daemon-client"; -export * from "./helpers/helpers"; -// Copyright 2023 The Tari Project -// SPDX-License-Identifier: BSD-3-Clause - -export * from "./types/AccessRule"; -export * from "./types/Account"; -export * from "./types/Amount"; -export * from "./types/ArgDef"; -export * from "./types/Arg"; -export * from "./types/AuthHook"; -export * from "./types/Block"; -export * from "./types/BucketId"; -export * from "./types/Claims"; -export * from "./types/Command"; -export * from "./types/CommitteeInfo"; -export * from "./types/CommitteeShardInfo"; -export * from "./types/Committee"; -export * from "./types/ComponentAccessRules"; -export * from "./types/ComponentAddress"; -export * from "./types/ComponentBody"; -export * from "./types/ComponentHeader"; -export * from "./types/ComponentKey"; -export * from "./types/ConfidentialClaim"; -export * from "./types/ConfidentialOutputStatement"; -export * from "./types/ConfidentialOutput"; -export * from "./types/ConfidentialStatement"; -export * from "./types/ConfidentialTransferInputSelection"; -export * from "./types/ConfidentialWithdrawProof"; -export * from "./types/Decision"; -export * from "./types/ElgamalVerifiableBalance"; -export * from "./types/EntityId"; -export * from "./types/Epoch"; -export * from "./types/Event"; -export * from "./types/Evidence"; -export * from "./types/ExecutedTransaction"; -export * from "./types/ExecuteResult"; -export * from "./types/FeeBreakdown"; -export * from "./types/FeeClaimAddress"; -export * from "./types/FeeClaim"; -export * from "./types/FeeCostBreakdown"; -export * from "./types/FeeReceipt"; -export * from "./types/FeeSource"; -export * from "./types/FinalizeResult"; -export * from "./types/ForeignProposalAtom"; -export * from "./types/ForeignProposalState"; -export * from "./types/ForeignProposal"; -export * from "./types/FunctionDef"; -export * from "./types/IndexedValue"; -export * from "./types/IndexedWellKnownTypes"; -export * from "./types/InstructionResult"; -export * from "./types/Instruction"; -export * from "./types/JrpcPermissions"; -export * from "./types/JrpcPermission"; -export * from "./types/LeaderFee"; -export * from "./types/LockFlag"; -export * from "./types/LogEntry"; -export * from "./types/LogLevel"; -export * from "./types/Metadata"; -export * from "./types/MintConfidentialOutputAtom"; -export * from "./types/NetworkCommitteeInfo"; -export * from "./types/NodeHeight"; -export * from "./types/NonFungibleAddressContents"; -export * from "./types/NonFungibleAddress"; -export * from "./types/NonFungibleContainer"; -export * from "./types/NonFungibleId"; -export * from "./types/NonFungibleIndexAddress"; -export * from "./types/NonFungibleIndex"; -export * from "./types/NonFungibleToken"; -export * from "./types/NonFungible"; -export * from "./types/NumPreshards"; -export * from "./types/Ordering"; -export * from "./types/OwnerRule"; -export * from "./types/PeerAddress"; -export * from "./types/ProofId"; -export * from "./types/QuorumCertificate"; -export * from "./types/QuorumDecision"; -export * from "./types/RejectReason"; -export * from "./types/RequireRule"; -export * from "./types/ResourceAccessRules"; -export * from "./types/ResourceAddress"; -export * from "./types/ResourceContainer"; -export * from "./types/Resource"; -export * from "./types/ResourceType"; -export * from "./types/RestrictedAccessRule"; -export * from "./types/RuleRequirement"; -export * from "./types/ShardEvidence"; -export * from "./types/ShardGroup"; -export * from "./types/Shard"; -export * from "./types/SubstateAddress"; -export * from "./types/SubstateDestroyed"; -export * from "./types/SubstateDiff"; -export * from "./types/SubstateId"; -export * from "./types/SubstateLockFlag"; -export * from "./types/SubstateLockType"; -export * from "./types/SubstateRecord"; -export * from "./types/SubstateRequirement"; -export * from "./types/Substate"; -export * from "./types/SubstateType"; -export * from "./types/SubstateValue"; -export * from "./types/TemplateDef"; -export * from "./types/TemplateDefV1"; -export * from "./types/TransactionAtom"; -export * from "./types/TransactionPoolRecord"; -export * from "./types/TransactionPoolStage"; -export * from "./types/TransactionReceiptAddress"; -export * from "./types/TransactionReceipt"; -export * from "./types/TransactionResult"; -export * from "./types/TransactionSignature"; -export * from "./types/TransactionStatus"; -export * from "./types/Transaction"; -export * from "./types/Type"; -export * from "./types/UnclaimedConfidentialOutputAddress"; -export * from "./types/UnclaimedConfidentialOutput"; -export * from "./types/UnsignedTransaction"; -export * from "./types/ValidatorSignature"; -export * from "./types/VaultId"; -export * from "./types/Vault"; -export * from "./types/VersionedSubstateIdLockIntent"; -export * from "./types/VersionedSubstateId"; -export * from "./types/ViewableBalanceProof"; -export * from "./base-node-client"; -export * from "./tari-indexer-client"; -export * from "./validator-node-client"; -export * from "./wallet-daemon-client"; -export * from "./helpers/helpers"; -// Copyright 2023 The Tari Project -// SPDX-License-Identifier: BSD-3-Clause - export * from "./types/AccessRule"; export * from "./types/Account"; export * from "./types/Amount"; @@ -1135,8 +41,6 @@ export * from "./types/FeeReceipt"; export * from "./types/FeeSource"; export * from "./types/FinalizeResult"; export * from "./types/ForeignProposalAtom"; -export * from "./types/ForeignProposalState"; -export * from "./types/ForeignProposal"; export * from "./types/FunctionDef"; export * from "./types/IndexedValue"; export * from "./types/IndexedWellKnownTypes"; @@ -1183,7 +87,6 @@ export * from "./types/SubstateAddress"; export * from "./types/SubstateDestroyed"; export * from "./types/SubstateDiff"; export * from "./types/SubstateId"; -export * from "./types/SubstateLockFlag"; export * from "./types/SubstateLockType"; export * from "./types/SubstateRecord"; export * from "./types/SubstateRequirement"; diff --git a/bindings/src/types/ForeignProposal.ts b/bindings/src/types/ForeignProposal.ts deleted file mode 100644 index d8e47eab3..000000000 --- a/bindings/src/types/ForeignProposal.ts +++ /dev/null @@ -1,12 +0,0 @@ -// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually. -import type { ForeignProposalState } from "./ForeignProposalState"; -import type { NodeHeight } from "./NodeHeight"; - -export interface ForeignProposal { - shard_group: number; - block_id: string; - state: ForeignProposalState; - proposed_height: NodeHeight | null; - transactions: Array; - base_layer_block_height: number; -} diff --git a/bindings/src/types/ForeignProposalState.ts b/bindings/src/types/ForeignProposalState.ts deleted file mode 100644 index a7fe60bf3..000000000 --- a/bindings/src/types/ForeignProposalState.ts +++ /dev/null @@ -1,3 +0,0 @@ -// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually. - -export type ForeignProposalState = "New" | "Proposed" | "Deleted"; diff --git a/bindings/src/types/ShardEvidence.ts b/bindings/src/types/ShardEvidence.ts index 0e1664a17..e82ef84bc 100644 --- a/bindings/src/types/ShardEvidence.ts +++ b/bindings/src/types/ShardEvidence.ts @@ -2,6 +2,7 @@ import type { SubstateLockType } from "./SubstateLockType"; export interface ShardEvidence { - qc_ids: Array; + prepare_justify: string | null; + accept_justify: string | null; lock: SubstateLockType; } diff --git a/bindings/src/types/SubstateLockFlag.ts b/bindings/src/types/SubstateLockFlag.ts deleted file mode 100644 index 5f345a02d..000000000 --- a/bindings/src/types/SubstateLockFlag.ts +++ /dev/null @@ -1,3 +0,0 @@ -// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually. - -export type SubstateLockFlag = "Read" | "Write" | "Output"; diff --git a/bindings/src/types/TransactionPoolRecord.ts b/bindings/src/types/TransactionPoolRecord.ts index 1a36cdab2..533d96108 100644 --- a/bindings/src/types/TransactionPoolRecord.ts +++ b/bindings/src/types/TransactionPoolRecord.ts @@ -7,7 +7,6 @@ import type { TransactionPoolStage } from "./TransactionPoolStage"; export interface TransactionPoolRecord { transaction_id: string; evidence: Evidence; - remote_evidence: Evidence | null; transaction_fee: number; leader_fee: LeaderFee | null; stage: TransactionPoolStage; diff --git a/dan_layer/common_types/src/substate_address.rs b/dan_layer/common_types/src/substate_address.rs index 130da7787..ccaf2035d 100644 --- a/dan_layer/common_types/src/substate_address.rs +++ b/dan_layer/common_types/src/substate_address.rs @@ -280,6 +280,18 @@ impl FromStr for SubstateAddress { } } +impl ToSubstateAddress for SubstateAddress { + fn to_substate_address(&self) -> SubstateAddress { + *self + } +} + +impl ToSubstateAddress for &SubstateAddress { + fn to_substate_address(&self) -> SubstateAddress { + **self + } +} + #[cfg(test)] mod tests { use std::{ diff --git a/dan_layer/common_types/src/versioned_substate_id.rs b/dan_layer/common_types/src/versioned_substate_id.rs index 587a6a201..4c3a871ad 100644 --- a/dan_layer/common_types/src/versioned_substate_id.rs +++ b/dan_layer/common_types/src/versioned_substate_id.rs @@ -59,11 +59,6 @@ impl SubstateRequirement { .map(|v| SubstateAddress::from_substate_id(self.substate_id(), v)) } - pub fn to_substate_address_default_version(&self, default: u32) -> SubstateAddress { - let v = self.version.unwrap_or(default); - SubstateAddress::from_substate_id(self.substate_id(), v) - } - /// Calculates and returns the shard number that this SubstateAddress belongs. /// A shard is a fixed division of the 256-bit shard space. /// If the substate version is not known, None is returned. diff --git a/dan_layer/consensus/src/hotstuff/block_change_set.rs b/dan_layer/consensus/src/hotstuff/block_change_set.rs index 6897809a2..d809b8321 100644 --- a/dan_layer/consensus/src/hotstuff/block_change_set.rs +++ b/dan_layer/consensus/src/hotstuff/block_change_set.rs @@ -1,11 +1,11 @@ // Copyright 2024 The Tari Project // SPDX-License-Identifier: BSD-3-Clause -use std::ops::Deref; +use std::{collections::HashMap, ops::Deref}; use indexmap::IndexMap; use log::*; -use tari_dan_common_types::{shard::Shard, Epoch}; +use tari_dan_common_types::{optional::Optional, shard::Shard, Epoch, ShardGroup}; use tari_dan_storage::{ consensus_models::{ Block, @@ -15,16 +15,18 @@ use tari_dan_storage::{ BurntUtxo, ForeignProposal, LeafBlock, + LockedBlock, PendingShardStateTreeDiff, QuorumCertificate, QuorumDecision, SubstateChange, SubstateLock, + SubstatePledge, + SubstatePledges, SubstateRecord, TransactionExecution, TransactionPoolError, TransactionPoolRecord, - TransactionPoolStage, TransactionPoolStatusUpdate, VersionedStateHashTreeDiff, }, @@ -73,8 +75,10 @@ impl ProposedBlockChangeSet { } } - pub fn no_vote(mut self) -> Self { + pub fn no_vote(&mut self) -> &mut Self { + // This means no vote self.quorum_decision = None; + // The remaining info discarded (not strictly necessary) self.block_diff = Vec::new(); self.transaction_changes = IndexMap::new(); self.state_tree_diffs = IndexMap::new(); @@ -109,16 +113,51 @@ impl ProposedBlockChangeSet { self } + pub fn proposed_foreign_proposals(&self) -> &[BlockId] { + &self.proposed_foreign_proposals + } + pub fn set_utxo_mint_proposed_in(&mut self, mint: SubstateId) -> &mut Self { self.proposed_utxo_mints.push(mint); self } - // TODO: this is a hack to allow the update to be modified after the fact. This should be removed. - pub fn next_update_mut(&mut self, transaction_id: &TransactionId) -> Option<&mut TransactionPoolStatusUpdate> { + pub fn apply_evidence(&self, tx_rec_mut: &mut TransactionPoolRecord) { + if let Some(update) = self.transaction_changes.get(tx_rec_mut.transaction_id()) { + update.apply_evidence(tx_rec_mut); + } + } + + #[allow(clippy::mutable_key_type)] + pub fn add_foreign_pledges( + &mut self, + transaction_id: &TransactionId, + shard_group: ShardGroup, + foreign_pledges: SubstatePledges, + ) -> &mut Self { + let change_mut = self.transaction_changes.entry(*transaction_id).or_default(); + if change_mut + .foreign_pledges + .insert(shard_group, foreign_pledges) + .is_some() + { + warn!( + target: LOG_TARGET, + "⚠️ NEVER HAPPEN: Foreign pledges for transaction {} in shard group {} already exist in block {}", + transaction_id, + shard_group, + self.block.block_id + ); + } + self + } + + pub fn get_foreign_pledges(&self, transaction_id: &TransactionId) -> impl Iterator + Clone { self.transaction_changes - .get_mut(transaction_id) - .and_then(|change| change.next_update.as_mut()) + .get(transaction_id) + .into_iter() + .flat_map(|change| change.foreign_pledges.values()) + .flatten() } pub fn is_accept(&self) -> bool { @@ -146,42 +185,36 @@ impl ProposedBlockChangeSet { Ok(self) } + pub fn get_transaction( + &self, + tx: &TTx, + locked_block: &LockedBlock, + leaf_block: &LeafBlock, + transaction_id: &TransactionId, + ) -> Result, TransactionPoolError> { + self.transaction_changes + .get(transaction_id) + .and_then(|change| change.next_update.as_ref().map(|u| &u.transaction)) + .cloned() + .map(Ok) + .or_else(|| { + TransactionPoolRecord::get(tx, locked_block.block_id(), leaf_block.block_id(), transaction_id) + .optional() + .transpose() + }) + .transpose() + } + pub fn set_next_transaction_update( &mut self, - transaction: &TransactionPoolRecord, - next_stage: TransactionPoolStage, - is_ready: bool, + transaction: TransactionPoolRecord, ) -> Result<&mut Self, TransactionPoolError> { - transaction.check_pending_status_update(next_stage, is_ready)?; - let change_mut = self .transaction_changes .entry(*transaction.transaction_id()) .or_default(); - if change_mut.next_update.is_some() { - return Err(TransactionPoolError::TransactionAlreadyUpdated { - transaction_id: *transaction.transaction_id(), - block_id: self.block.block_id, - }); - } - info!( - target: LOG_TARGET, - "📝 Setting next update for transaction {} to {:?},{},is_ready={} in block {}", - transaction.transaction_id(), - next_stage, - transaction.current_decision(), - is_ready, - self.block.block_id - ); - - change_mut.next_update = Some(TransactionPoolStatusUpdate { - block_id: self.block.block_id, - transaction_id: *transaction.transaction_id(), - stage: next_stage, - evidence: transaction.evidence().clone(), - is_ready, - local_decision: transaction.current_decision(), - }); + + change_mut.next_update = Some(TransactionPoolStatusUpdate { transaction }); Ok(self) } } @@ -205,7 +238,7 @@ impl ProposedBlockChangeSet { // Save locks SubstateRecord::lock_all(tx, self.block.block_id, self.substate_locks)?; - for change in self.transaction_changes.values() { + for (transaction_id, change) in self.transaction_changes { // Save any transaction executions for the block if let Some(ref execution) = change.execution { // This may already exist if we proposed the block @@ -228,7 +261,11 @@ impl ProposedBlockChangeSet { // Save any transaction pool updates if let Some(ref update) = change.next_update { - update.insert(tx)?; + update.insert_for_block(tx, self.block.block_id())?; + } + + for (shard_group, pledges) in change.foreign_pledges { + tx.foreign_substate_pledges_save(transaction_id, shard_group, pledges)?; } } @@ -245,7 +282,16 @@ impl ProposedBlockChangeSet { } #[derive(Debug, Clone, Default)] -pub struct TransactionChangeSet { +struct TransactionChangeSet { execution: Option, next_update: Option, + foreign_pledges: HashMap, +} + +impl TransactionChangeSet { + pub fn apply_evidence(&self, tx_rec_mut: &mut TransactionPoolRecord) { + if let Some(update) = self.next_update.as_ref() { + update.apply_evidence(tx_rec_mut); + } + } } diff --git a/dan_layer/consensus/src/hotstuff/foreign_proposal_processor.rs b/dan_layer/consensus/src/hotstuff/foreign_proposal_processor.rs new file mode 100644 index 000000000..e73176337 --- /dev/null +++ b/dan_layer/consensus/src/hotstuff/foreign_proposal_processor.rs @@ -0,0 +1,481 @@ +// Copyright 2024 The Tari Project +// SPDX-License-Identifier: BSD-3-Clause + +use log::*; +use tari_dan_common_types::{committee::CommitteeInfo, ToSubstateAddress}; +use tari_dan_storage::{ + consensus_models::{ + BlockId, + BlockPledge, + Command, + ForeignProposal, + LeafBlock, + LockedBlock, + TransactionAtom, + TransactionPoolRecord, + TransactionPoolStage, + }, + StateStoreReadTransaction, +}; +use tari_transaction::TransactionId; + +use crate::hotstuff::{block_change_set::ProposedBlockChangeSet, error::HotStuffError, ProposalValidationError}; + +const LOG_TARGET: &str = "tari::dan::consensus::hotstuff::foreign_proposal_processor"; + +#[allow(clippy::too_many_lines)] +pub fn process_foreign_block( + tx: &TTx, + local_leaf: &LeafBlock, + locked_block: &LockedBlock, + proposal: ForeignProposal, + foreign_committee_info: &CommitteeInfo, + local_committee_info: &CommitteeInfo, + proposed_block_change_set: &mut ProposedBlockChangeSet, +) -> Result<(), HotStuffError> { + assert_eq!( + proposal.block.shard_group(), + foreign_committee_info.shard_group(), + "Foreign proposal shard group does not match the foreign committee shard group" + ); + info!( + target: LOG_TARGET, + "🧩 Processing FOREIGN PROPOSAL for block {}, justify_qc: {}", + proposal.block(), + proposal.justify_qc(), + ); + + let ForeignProposal { + block, + justify_qc, + mut block_pledge, + .. + } = proposal; + let mut command_count = 0usize; + + for cmd in block.commands() { + match cmd { + Command::LocalPrepare(atom) => { + if !local_committee_info.includes_any_address(atom.evidence.substate_addresses_iter()) { + continue; + } + + debug!( + target: LOG_TARGET, + "🧩 FOREIGN PROPOSAL: Command: LocalPrepare({}, {}), block: {}", + atom.id,atom.decision, block.id(), + ); + + let Some(mut tx_rec) = + proposed_block_change_set.get_transaction(tx, locked_block, local_leaf, &atom.id)? + else { + // If this happens, it could be a bug in the foreign missing transaction handling + warn!( + target: LOG_TARGET, + "⚠️ NEVER HAPPEN: Foreign proposal received for transaction {} but this transaction is not in the pool.", + atom.id + ); + continue; + }; + + let is_shard_group_output_only = tx_rec.evidence().is_committee_output_only(foreign_committee_info); + if is_shard_group_output_only { + // If the shard group is only involved in the outputs, we can ignore Prepare commands. + debug!( + target: LOG_TARGET, + "❓️ Foreign LocalPrepare proposal ({}) received LOCAL_PREPARE for transaction {} stage: {} but the foreign shard group is only involved in outputs. Ignoring.", + block, + tx_rec.transaction_id(), + tx_rec.current_stage() + ); + + continue; + } + + if tx_rec.current_stage() > TransactionPoolStage::LocalPrepared { + warn!( + target: LOG_TARGET, + "⚠️ Foreign LocalPrepare proposal ({}) received LOCAL_PREPARE for transaction {} but current transaction stage is {}. Ignoring.", + block, + tx_rec.transaction_id(), tx_rec.current_stage() + ); + continue; + } + + command_count += 1; + + let remote_decision = atom.decision; + let local_decision = tx_rec.current_decision(); + if remote_decision.is_abort() && local_decision.is_commit() { + info!( + target: LOG_TARGET, + "⚠️ Foreign committee ABORT transaction {}. Update overall decision to ABORT. Local stage: {}, Leaf: {}", + tx_rec.transaction_id(), tx_rec.current_stage(), local_leaf + ); + } + + // We need to add the justify QC to the evidence because the all prepare block could not include it + // yet + let foreign_evidence = atom.evidence.clone(); + + // Update the transaction record with any new information provided by this foreign block + tx_rec + .evidence_mut() + .update(foreign_evidence.iter().map(|(addr, e)| (*addr, e.lock))) + .add_prepare_qc_evidence(foreign_committee_info, *justify_qc.id()); + tx_rec.set_remote_decision(remote_decision); + + validate_and_add_pledges( + tx_rec.transaction_id(), + block.id(), + atom, + &mut block_pledge, + foreign_committee_info, + proposed_block_change_set, + )?; + + // tx_rec.evidence().iter().for_each(|(addr, ev)| { + // let includes_local = local_committee_info.includes_substate_address(addr); + // log::error!( + // target: LOG_TARGET, + // "🐞 LOCALPREPARE EVIDENCE (l={}, f={}) {}: {}", includes_local, !includes_local, addr, ev + // ); + // }); + + if tx_rec.current_stage().is_new() { + info!( + target: LOG_TARGET, + "🧩 FOREIGN PROPOSAL: (Initial sequence from LocalPrepare) Transaction is ready for Prepare({}, {}) Local Stage: {}", + tx_rec.transaction_id(), + tx_rec.current_decision(), + tx_rec.current_stage() + ); + // If the transaction is New, we're waiting for all foreign pledges. Propose transaction once we + // have them. + + // CASE: One foreign SG is involved in all inputs and executed the transaction, local SG is + // involved in the outputs + let is_ready = local_committee_info.includes_substate_id(&tx_rec.to_receipt_id().into()) || + tx_rec.has_any_local_inputs(local_committee_info) || + has_all_foreign_input_pledges(tx, &tx_rec, local_committee_info, proposed_block_change_set)?; + + if is_ready { + info!( + target: LOG_TARGET, + "🧩 FOREIGN PROPOSAL: (Initial sequence from LocalPrepare) Transaction is ready for Prepare({}, {}) Local Stage: {}", + tx_rec.transaction_id(), + tx_rec.current_decision(), + tx_rec.current_stage() + ); + tx_rec.set_next_stage(TransactionPoolStage::New, true)?; + proposed_block_change_set.set_next_transaction_update(tx_rec)?; + } else { + info!( + target: LOG_TARGET, + "🧩 FOREIGN PROPOSAL: (Initial sequence from LocalPrepare) Transaction is NOT ready for Prepare({}, {}) Local Stage: {}", + tx_rec.transaction_id(), + tx_rec.current_decision(), + tx_rec.current_stage() + ); + } + } else if tx_rec.current_stage().is_local_prepared() && tx_rec.evidence().all_input_addresses_prepared() + { + // If all shards are complete, and we've already received our LocalPrepared, we can set out + // LocalPrepared transaction as ready to propose ACCEPT. If we have not received + // the local LocalPrepared, the transition will happen when we receive the local + // block. + info!( + target: LOG_TARGET, + "🧩 FOREIGN PROPOSAL: Transaction is ready for propose AllPrepared({}, {}) Local Stage: {}", + tx_rec.transaction_id(), + tx_rec.current_decision(), + tx_rec.current_stage() + ); + + tx_rec.set_next_stage(TransactionPoolStage::LocalPrepared, true)?; + proposed_block_change_set.set_next_transaction_update(tx_rec)?; + } else { + info!( + target: LOG_TARGET, + "🧩 FOREIGN PROPOSAL: Transaction is NOT ready for AllPrepared({}, {}) Local Stage: {}, All Justified: {}. Waiting for local proposal.", + tx_rec.transaction_id(), + tx_rec.current_decision(), + tx_rec.current_stage(), + tx_rec.evidence().all_input_addresses_prepared() + ); + // Update the evidence + proposed_block_change_set.set_next_transaction_update(tx_rec)?; + } + }, + Command::LocalAccept(atom) => { + if !local_committee_info.includes_any_address(atom.evidence.substate_addresses_iter()) { + continue; + } + + debug!( + target: LOG_TARGET, + "🧩 FOREIGN PROPOSAL: Command: LocalAccept({}, {}), block: {}", + atom.id, atom.decision, block.id(), + ); + + let Some(mut tx_rec) = + proposed_block_change_set.get_transaction(tx, locked_block, local_leaf, &atom.id)? + else { + warn!( + target: LOG_TARGET, + "⚠️ NEVER HAPPEN: Foreign proposal received for transaction {} but this transaction is not in the pool.", + atom.id + ); + continue; + }; + + if tx_rec.current_stage() > TransactionPoolStage::LocalAccepted { + warn!( + target: LOG_TARGET, + "⚠️ Foreign proposal {} received LOCAL_ACCEPT for transaction {} but current transaction stage is {}. Ignoring.", + block, + tx_rec.transaction_id(), + tx_rec.current_stage(), + ); + continue; + } + + command_count += 1; + + let remote_decision = atom.decision; + let local_decision = tx_rec.current_local_decision(); + if remote_decision.is_abort() && local_decision.is_commit() { + info!( + target: LOG_TARGET, + "⚠️ Foreign ABORT {}. Update overall decision to ABORT. Local stage: {}, Leaf: {}", + tx_rec.transaction_id(), tx_rec.current_stage(), local_leaf + ); + } + + // We need to add the justify QC to the evidence because the all prepare block could not include it + // yet + let foreign_evidence = atom.evidence.clone(); + + // Update the transaction record with any new information provided by this foreign block + tx_rec + .evidence_mut() + .update(foreign_evidence.iter().map(|(addr, e)| (*addr, e.lock))) + .add_accept_qc_evidence(foreign_committee_info, *justify_qc.id()); + tx_rec.set_remote_decision(remote_decision); + + validate_and_add_pledges( + tx_rec.transaction_id(), + block.id(), + atom, + &mut block_pledge, + foreign_committee_info, + proposed_block_change_set, + )?; + + // Good debug info + // tx_rec.evidence().iter().for_each(|(addr, ev)| { + // let includes_local = local_committee_info.includes_substate_address(addr); + // log::error!( + // target: LOG_TARGET, + // "🐞 LOCALACCEPT EVIDENCE (l={}, f={}) {}: {}", includes_local, !includes_local, addr, ev + // ); + // }); + + if tx_rec.current_stage().is_new() { + // If the transaction is New, we're waiting for all foreign pledges. Propose transaction once we + // have them. + // CASE: Foreign SGs have pledged all inputs and executed the transaction, local SG is involved + // in the outputs + let is_ready = local_committee_info.includes_substate_id(&tx_rec.to_receipt_id().into()) || + tx_rec.has_any_local_inputs(local_committee_info) || + has_all_foreign_input_pledges(tx, &tx_rec, local_committee_info, proposed_block_change_set)?; + if is_ready { + info!( + target: LOG_TARGET, + "🧩 FOREIGN PROPOSAL: (Initial sequence from LocalAccept) Transaction is ready for Prepare({}, {}) Local Stage: {}", + tx_rec.transaction_id(), + tx_rec.current_decision(), + tx_rec.current_stage() + ); + + tx_rec.set_next_stage(TransactionPoolStage::New, true)?; + proposed_block_change_set.set_next_transaction_update(tx_rec)?; + } else { + info!( + target: LOG_TARGET, + "🧩 FOREIGN PROPOSAL: (Initial sequence from LocalAccept) Transaction is NOT ready for Prepare({}, {}) Local Stage: {}", + tx_rec.transaction_id(), + tx_rec.current_decision(), + tx_rec.current_stage() + ); + + proposed_block_change_set.set_next_transaction_update(tx_rec)?; + } + } else if tx_rec.current_stage().is_local_accepted() && tx_rec.evidence().all_addresses_justified() { + info!( + target: LOG_TARGET, + "🧩 FOREIGN PROPOSAL: Transaction is ready for propose ALL_ACCEPT({}, {}) Local Stage: {}", + tx_rec.transaction_id(), + tx_rec.current_decision(), + tx_rec.current_stage() + ); + + tx_rec.set_next_stage(TransactionPoolStage::LocalAccepted, true)?; + proposed_block_change_set.set_next_transaction_update(tx_rec)?; + } else { + info!( + target: LOG_TARGET, + "🧩 FOREIGN PROPOSAL: Transaction is NOT ready for ALL_ACCEPT({}, {}) Local Stage: {}, All Justified: {}. Waiting for local proposal.", + tx_rec.transaction_id(), + tx_rec.current_decision(), + tx_rec.current_stage(), + tx_rec.evidence().all_addresses_justified() + ); + // Still need to update the evidence + proposed_block_change_set.set_next_transaction_update(tx_rec)?; + } + }, + // Should never receive this + Command::EndEpoch => { + warn!( + target: LOG_TARGET, + "❓️ NEVER HAPPEN: Foreign proposal received for block {} contains an EndEpoch command. This is invalid behaviour.", + block.id() + ); + continue; + }, + // TODO(perf): Can we find a way to exclude these unused commands to reduce message size? + Command::AllAccept(_) | + Command::SomeAccept(_) | + Command::AllPrepare(_) | + Command::SomePrepare(_) | + Command::Prepare(_) | + Command::LocalOnly(_) | + Command::ForeignProposal(_) | + Command::MintConfidentialOutput(_) => { + // Disregard + continue; + }, + } + } + + info!( + target: LOG_TARGET, + "🧩 FOREIGN PROPOSAL: Processed {} commands from foreign block {}", + command_count, + block.id() + ); + if command_count == 0 { + warn!( + target: LOG_TARGET, + "⚠️ FOREIGN PROPOSAL: No commands were applicable for foreign block {}. Ignoring.", + block.id() + ); + } + + Ok(()) +} + +fn validate_and_add_pledges( + transaction_id: &TransactionId, + block_id: &BlockId, + atom: &TransactionAtom, + block_pledge: &mut BlockPledge, + foreign_committee_info: &CommitteeInfo, + proposed_block_change_set: &mut ProposedBlockChangeSet, +) -> Result<(), HotStuffError> { + #[allow(clippy::mutable_key_type)] + let maybe_pledges = if atom.decision.is_commit() { + let pledges = block_pledge.remove_transaction_pledges(&atom.id).ok_or_else(|| { + HotStuffError::ForeignNodeOmittedTransactionPledges { + foreign_block_id: *block_id, + transaction_id: atom.id, + } + })?; + + // Validate that provided evidence is correct + // TODO: there are a lot of validations to be done on evidence and the foreign block in general, + // this is here as a sanity check and should change to not be a fatal error in consensus + for pledge in &pledges { + let address = pledge.versioned_substate_id().to_substate_address(); + let evidence = + atom.evidence + .get(&address) + .ok_or_else(|| ProposalValidationError::ForeignInvalidPledge { + block_id: *block_id, + transaction_id: atom.id, + details: format!("Pledge {pledge} for address {address} not found in evidence"), + })?; + if evidence.lock.is_output() && pledge.is_input() { + return Err(ProposalValidationError::ForeignInvalidPledge { + block_id: *block_id, + transaction_id: atom.id, + details: format!("Pledge {pledge} is an input but evidence is an output for address {address}"), + } + .into()); + } + if !evidence.lock.is_output() && pledge.is_output() { + return Err(ProposalValidationError::ForeignInvalidPledge { + block_id: *block_id, + transaction_id: atom.id, + details: format!("Pledge {pledge} is an output but evidence is an input for address {address}"), + } + .into()); + } + } + Some(pledges) + } else { + if block_pledge.contains(&atom.id) { + return Err(ProposalValidationError::ForeignInvalidPledge { + block_id: *block_id, + transaction_id: atom.id, + details: "Remote decided ABORT but provided pledges".to_string(), + } + .into()); + } + None + }; + + if let Some(pledges) = maybe_pledges { + // If the foreign shard has committed the transaction, we can add the pledges to the transaction + // record + proposed_block_change_set.add_foreign_pledges(transaction_id, foreign_committee_info.shard_group(), pledges); + } + + Ok(()) +} + +fn has_all_foreign_input_pledges( + tx: &TTx, + tx_rec: &TransactionPoolRecord, + local_committee_info: &CommitteeInfo, + proposed_block_change_set: &ProposedBlockChangeSet, +) -> Result { + let foreign_inputs = tx_rec + .evidence() + .iter() + .filter(|(addr, ev)| !ev.lock.is_output() && !local_committee_info.includes_substate_address(addr)) + .map(|(addr, _)| addr); + + let current_pledges = proposed_block_change_set.get_foreign_pledges(tx_rec.transaction_id()); + + for addr in foreign_inputs { + // Check the current block change set to see if the pledge is included + if current_pledges.clone().any(|pledge| pledge.satisfies_address(addr)) { + continue; + } + + if tx.foreign_substate_pledges_exists_for_address(tx_rec.transaction_id(), addr)? { + continue; + } + debug!( + target: LOG_TARGET, + "Transaction {} is missing a pledge for input {}", + tx_rec.transaction_id(), + addr + ); + return Ok(false); + } + + Ok(true) +} diff --git a/dan_layer/consensus/src/hotstuff/mod.rs b/dan_layer/consensus/src/hotstuff/mod.rs index 430e02589..95c083339 100644 --- a/dan_layer/consensus/src/hotstuff/mod.rs +++ b/dan_layer/consensus/src/hotstuff/mod.rs @@ -21,6 +21,7 @@ mod on_receive_vote; mod on_sync_request; // mod on_sync_response; mod block_change_set; +mod foreign_proposal_processor; mod on_catch_up_sync; mod on_message_validate; mod pacemaker; diff --git a/dan_layer/consensus/src/hotstuff/on_message_validate.rs b/dan_layer/consensus/src/hotstuff/on_message_validate.rs index fc9d852d9..b67fe8bd9 100644 --- a/dan_layer/consensus/src/hotstuff/on_message_validate.rs +++ b/dan_layer/consensus/src/hotstuff/on_message_validate.rs @@ -214,6 +214,12 @@ impl OnMessageValidate { from: TConsensusSpec::Addr, proposal: ProposalMessage, ) -> Result, HotStuffError> { + // TODO: we need to check foreign proposals for missing transactions as well + // for proposal in proposal.foreign_proposals.iter() { + // self.process_foreign_proposal(&CommitteeInfo::default(), from.clone(), proposal.clone()) + // .await?; + // } + let missing_tx_ids = self .store .with_write_tx(|tx| self.check_for_missing_transactions(tx, &proposal))?; diff --git a/dan_layer/consensus/src/hotstuff/on_propose.rs b/dan_layer/consensus/src/hotstuff/on_propose.rs index cc29c22ef..ce3185f0b 100644 --- a/dan_layer/consensus/src/hotstuff/on_propose.rs +++ b/dan_layer/consensus/src/hotstuff/on_propose.rs @@ -32,6 +32,7 @@ use tari_dan_storage::{ HighQc, LastProposed, LeafBlock, + LockedBlock, PendingShardStateTreeDiff, QuorumCertificate, SubstateChange, @@ -51,6 +52,7 @@ use tari_transaction::TransactionId; use crate::{ hotstuff::{ + block_change_set::ProposedBlockChangeSet, calculate_state_merkle_root, error::HotStuffError, filter_diff_for_committee, @@ -169,6 +171,7 @@ where TConsensusSpec: ConsensusSpec let (next_block, foreign_proposals) = self.store.with_write_tx(|tx| { let high_qc = HighQc::get(&**tx, epoch)?; let high_qc_cert = high_qc.get_quorum_certificate(&**tx)?; + let (next_block, foreign_proposals, executed_transactions) = self.build_next_block( tx, epoch, @@ -263,29 +266,28 @@ where TConsensusSpec: ConsensusSpec substate_store, executed_transactions, ), + // Leader thinks all local nodes have prepared TransactionPoolStage::Prepared => Ok(Some(Command::LocalPrepare(tx_rec.get_local_transaction_atom()))), - TransactionPoolStage::LocalPrepared => { - if tx_rec.current_decision().is_commit() { - Ok(Some(Command::AllPrepare(tx_rec.get_local_transaction_atom()))) - } else { - Ok(Some(Command::SomePrepare(tx_rec.get_local_transaction_atom()))) - } - }, + // Leader thinks all foreign PREPARE pledges have been received (condition for LocalPrepared stage to be + // ready) + TransactionPoolStage::LocalPrepared => self.all_or_some_prepare_transaction( + tx, + parent_block, + local_committee_info, + &mut tx_rec, + substate_store, + executed_transactions, + ), - TransactionPoolStage::AllPrepared => { - // We have received all foreign pledges and are ready to propose LocalAccept - self.local_accept_transaction( - tx, - parent_block, - local_committee_info, - &mut tx_rec, - substate_store, - executed_transactions, - ) - }, + // Leader thinks that all local nodes agree that all shard groups have prepared, we are ready to accept + // locally + TransactionPoolStage::AllPrepared => self.local_accept_transaction(local_committee_info, &mut tx_rec), + // Leader thinks local nodes are ready to accept an ABORT TransactionPoolStage::SomePrepared => Ok(Some(Command::LocalAccept( self.get_current_transaction_atom(local_committee_info, &mut tx_rec)?, ))), + // Leader thinks that all foreign ACCEPT pledges have been received and, we are ready to accept the result + // (COMMIT/ABORT) TransactionPoolStage::LocalAccepted => { self.accept_transaction(tx, parent_block, &mut tx_rec, local_committee_info, substate_store) }, @@ -303,13 +305,77 @@ where TConsensusSpec: ConsensusSpec } } + fn process_newly_justified_block( + &self, + tx: &::ReadTransaction<'_>, + new_leaf_block: &Block, + high_qc: HighQc, + local_committee_info: &CommitteeInfo, + change_set: &mut ProposedBlockChangeSet, + ) -> Result<(), HotStuffError> { + let locked_block = LockedBlock::get(tx)?; + info!( + target: LOG_TARGET, + "✅ New leaf block {} is justified. Updating evidence for transactions", + new_leaf_block, + ); + + let leaf = new_leaf_block.as_leaf_block(); + for cmd in new_leaf_block.commands() { + if !cmd.is_local_prepare() && !cmd.is_local_accept() { + continue; + } + + let atom = cmd.transaction().expect("Command must be a transaction"); + + let Some(mut pool_tx) = change_set.get_transaction(tx, &locked_block, &leaf, atom.id())? else { + return Err(HotStuffError::InvariantError(format!( + "Transaction {} in newly justified block {} not found in the pool", + atom.id(), + leaf, + ))); + }; + + if cmd.is_local_prepare() { + pool_tx.add_prepare_qc_evidence(local_committee_info, high_qc.qc_id); + } else if cmd.is_local_accept() { + pool_tx.add_accept_qc_evidence(local_committee_info, high_qc.qc_id); + } else { + // Nothing + } + + debug!( + target: LOG_TARGET, + "ON PROPOSE: process_newly_justified_block {} {} {}, QC[{}]", + pool_tx.transaction_id(), + pool_tx.current_stage(), + local_committee_info.shard_group(), + high_qc.qc_id + ); + + if !pool_tx.is_ready() { + if pool_tx.current_stage().is_local_prepared() && pool_tx.evidence().all_input_addresses_prepared() { + pool_tx.set_next_stage(TransactionPoolStage::LocalPrepared, true)?; + } else if pool_tx.current_stage().is_local_accepted() && pool_tx.evidence().all_addresses_justified() { + pool_tx.set_next_stage(TransactionPoolStage::LocalAccepted, true)?; + } else { + // Nothing + } + } + + change_set.set_next_transaction_update(pool_tx)?; + } + + Ok(()) + } + #[allow(clippy::too_many_lines)] fn build_next_block( &self, tx: &::ReadTransaction<'_>, epoch: Epoch, parent_block: &LeafBlock, - high_qc: QuorumCertificate, + high_qc_certificate: QuorumCertificate, proposed_by: PublicKey, local_committee_info: &CommitteeInfo, dont_propose_transactions: bool, @@ -335,11 +401,32 @@ where TConsensusSpec: ConsensusSpec )? }; - debug!( - target: LOG_TARGET, - "🌿 Found {} foreign proposals for next block", - foreign_proposals.len() - ); + if !foreign_proposals.is_empty() { + debug!( + target: LOG_TARGET, + "🌿 Found {} foreign proposals for next block", + foreign_proposals.len() + ); + } + + let burnt_utxos = if dont_propose_transactions || propose_epoch_end { + vec![] + } else { + TARGET_BLOCK_SIZE + .checked_sub(foreign_proposals.len() * 4) + .filter(|n| *n > 0) + .map(|size| BurntUtxo::get_all_unproposed(tx, parent_block.block_id(), size)) + .transpose()? + .unwrap_or_default() + }; + + if !burnt_utxos.is_empty() { + debug!( + target: LOG_TARGET, + "🌿 Found {} burnt utxos for next block", + burnt_utxos.len() + ); + } let burnt_utxos = if dont_propose_transactions || propose_epoch_end { vec![] @@ -385,10 +472,46 @@ where TConsensusSpec: ConsensusSpec ) }; + let mut change_set = ProposedBlockChangeSet::new(high_qc_certificate.as_leaf_block()); + + // No need to include evidence from justified block if no transactions are included in the next block + if !batch.is_empty() { + // TODO(protocol-efficiency): We should process any foreign proposals included in this block to include + // evidence. And that should determine if they are ready. However this is difficult because we + // get the batch from the database which isnt aware of which foreign proposals we're going to + // propose. This is why the system currently never proposes foreign proposals affecting a + // transaction in the same block as LocalPrepare/LocalAccept for fp in foreign_proposals { + // process_foreign_block( + // tx, + // &high_qc_certificate.as_leaf_block(), + // locked_block, + // fp, + // foreign_committee_info, + // local_committee_info, + // &mut change_set, + // )?; + // } + + let justified_block = high_qc_certificate.get_block(tx)?; + if !justified_block.is_justified() { + // TODO: we dont need to process transactions here that are not in the batch + self.process_newly_justified_block( + tx, + &justified_block, + high_qc_certificate.as_high_qc(), + local_committee_info, + &mut change_set, + )?; + } + } + // batch is empty for is_empty, is_epoch_end and is_epoch_start blocks let mut substate_store = PendingSubstateStore::new(tx, *parent_block.block_id(), self.config.num_preshards); let mut executed_transactions = HashMap::new(); - for transaction in batch { + for mut transaction in batch { + // Apply the transaction updates (if any) that occurred as a result of the justified block. + // This allows us to propose evidence in the next block that relates to transactions in the justified block. + change_set.apply_evidence(&mut transaction); if let Some(command) = self.transaction_pool_record_to_command( tx, parent_block, @@ -427,7 +550,8 @@ where TConsensusSpec: ConsensusSpec commands.iter().map(|c| c.to_string()).collect::>().join(",") ); - let pending_tree_diffs = PendingShardStateTreeDiff::get_all_up_to_commit_block(tx, high_qc.block_id())?; + let pending_tree_diffs = + PendingShardStateTreeDiff::get_all_up_to_commit_block(tx, high_qc_certificate.block_id())?; let (state_root, _) = calculate_state_merkle_root( tx, @@ -450,7 +574,7 @@ where TConsensusSpec: ConsensusSpec let mut next_block = Block::new( self.config.network, *parent_block.block_id(), - high_qc, + high_qc_certificate, next_height, epoch, local_committee_info.shard_group(), @@ -608,7 +732,7 @@ where TConsensusSpec: ConsensusSpec Ok(Some(command)) } - fn local_accept_transaction( + fn all_or_some_prepare_transaction( &self, tx: &::ReadTransaction<'_>, parent_block: &LeafBlock, @@ -617,6 +741,11 @@ where TConsensusSpec: ConsensusSpec substate_store: &mut PendingSubstateStore, executed_transactions: &mut HashMap, ) -> Result, HotStuffError> { + // Only set to abort if either the local or one or more foreign shards decided to ABORT + if tx_rec.current_decision().is_abort() { + return Ok(Some(Command::SomePrepare(tx_rec.get_local_transaction_atom()))); + } + let mut execution = self.execute_transaction(tx, &parent_block.block_id, parent_block.epoch, tx_rec.transaction_id())?; @@ -637,11 +766,12 @@ where TConsensusSpec: ConsensusSpec tx_rec.transaction_id(), err, ); + // If the transaction does not lock, we propose to abort it execution.set_abort_reason(RejectReason::FailedToLockOutputs(err.to_string())); tx_rec.update_from_execution(&execution); + executed_transactions.insert(*tx_rec.transaction_id(), execution); - // If the transaction does not lock, we propose to abort it - return Ok(Some(Command::LocalAccept( + return Ok(Some(Command::AllPrepare( self.get_current_transaction_atom(local_committee_info, tx_rec)?, ))); } @@ -650,6 +780,17 @@ where TConsensusSpec: ConsensusSpec let atom = self.get_current_transaction_atom(local_committee_info, tx_rec)?; executed_transactions.insert(*tx_rec.transaction_id(), execution); + // If we locally decided to ABORT, we are still saying that we think all prepared. When we enter the acceptance + // phase, we will propose SomeAccept for this case. + Ok(Some(Command::AllPrepare(atom))) + } + + fn local_accept_transaction( + &self, + local_committee_info: &CommitteeInfo, + tx_rec: &mut TransactionPoolRecord, + ) -> Result, HotStuffError> { + let atom = self.get_current_transaction_atom(local_committee_info, tx_rec)?; Ok(Some(Command::LocalAccept(atom))) } diff --git a/dan_layer/consensus/src/hotstuff/on_ready_to_vote_on_local_block.rs b/dan_layer/consensus/src/hotstuff/on_ready_to_vote_on_local_block.rs index 76a809b75..6844a2dc4 100644 --- a/dan_layer/consensus/src/hotstuff/on_ready_to_vote_on_local_block.rs +++ b/dan_layer/consensus/src/hotstuff/on_ready_to_vote_on_local_block.rs @@ -1,8 +1,7 @@ // Copyright 2023 The Tari Project // SPDX-License-Identifier: BSD-3-Clause -#![allow(dead_code)] -use std::num::NonZeroU64; +use std::{collections::HashMap, num::NonZeroU64}; use log::*; use tari_crypto::ristretto::RistrettoPublicKey; @@ -22,6 +21,7 @@ use tari_dan_storage::{ Command, Decision, ForeignProposalAtom, + ForeignProposalStatus, LastExecuted, LastVoted, LockedBlock, @@ -50,6 +50,7 @@ use crate::{ error::HotStuffError, event::HotstuffEvent, filter_diff_for_committee, + foreign_proposal_processor::process_foreign_block, substate_store::{PendingSubstateStore, ShardedStateTree}, transaction_manager::{ ConsensusTransactionManager, @@ -105,6 +106,7 @@ where TConsensusSpec: ConsensusSpec valid_block: &ValidBlock, local_committee_info: &CommitteeInfo, can_propose_epoch_end: bool, + foreign_committee_infos: HashMap, ) -> Result { debug!( target: LOG_TARGET, @@ -113,8 +115,22 @@ where TConsensusSpec: ConsensusSpec ); self.store.with_write_tx(|tx| { - let mut change_set = - self.decide_on_block(&**tx, local_committee_info, valid_block, can_propose_epoch_end)?; + let mut change_set = ProposedBlockChangeSet::new(valid_block.block().as_leaf_block()); + let mut justified_block = valid_block.justify().get_block(&**tx)?; + // This comes before decide so that all evidence can be in place before LocalPrepare and LocalAccept + if !justified_block.is_justified() { + self.process_newly_justified_block(tx, &justified_block, local_committee_info, &mut change_set)?; + justified_block.set_as_justified(tx)?; + } + + self.decide_on_block( + tx, + local_committee_info, + valid_block, + can_propose_epoch_end, + &foreign_committee_infos, + &mut change_set, + )?; let mut locked_blocks = Vec::new(); let mut finalized_transactions = Vec::new(); @@ -122,13 +138,13 @@ where TConsensusSpec: ConsensusSpec if change_set.is_accept() { // Update nodes - let leaf_block = valid_block.block().update_nodes( + valid_block.block().update_nodes( tx, - |tx, locked, block, justify_qc| { + |tx, _prev_locked, block, justify_qc| { if !block.is_dummy() { locked_blocks.push((block.clone(), justify_qc.clone())); } - self.on_lock_block(tx, locked, block) + self.on_lock_block(tx, block) }, |tx, last_exec, commit_block| { let committed = self.on_commit(tx, last_exec, commit_block, local_committee_info)?; @@ -142,10 +158,6 @@ where TConsensusSpec: ConsensusSpec }, )?; - if !leaf_block.is_justified() { - self.process_newly_justified_block(tx, leaf_block, local_committee_info, &mut change_set)?; - } - valid_block.block().as_last_voted().set(tx)?; } @@ -163,124 +175,54 @@ where TConsensusSpec: ConsensusSpec fn process_newly_justified_block( &self, - tx: &mut ::WriteTransaction<'_>, - mut new_leaf_block: Block, + tx: &::ReadTransaction<'_>, + new_leaf_block: &Block, local_committee_info: &CommitteeInfo, change_set: &mut ProposedBlockChangeSet, ) -> Result<(), HotStuffError> { + let locked_block = LockedBlock::get(tx)?; info!( target: LOG_TARGET, "✅ New leaf block {} is justified. Updating evidence for transactions", new_leaf_block, ); - new_leaf_block.set_as_justified(tx)?; let leaf = new_leaf_block.as_leaf_block(); let justify_id = *new_leaf_block.justify().id(); for cmd in new_leaf_block.commands() { - let Some(atom) = cmd.progressing() else { + if !cmd.is_local_prepare() && !cmd.is_local_accept() { continue; - }; + } - // CASE: This code checks if the new leaf block causes the transaction to be ready. - // For example, suppose a transaction is LocalPrepared in the currently proposed block, however it - // is not yet the leaf block (because it has not been justified). If we then - // receive the foreign LocalPrepared for this transaction, we evaluate the - // foreign LocalPrepare using the transaction state as it "was" without - // considering data from the as yet unjustified block. This means that we do not - // recognise that the transaction is ready for AllPrepared, and we never propose - // it. This code reevaluates the new leaf blocks and sets any transactions to - // ready that have the required evidence. - - if let Some(update_mut) = change_set.next_update_mut(atom.id()) { - // The leaf block already approved finalising this transaction (i.e. the justify block proposed - // LocalAccept, the leaf proposed (some|all)Accept therefore we already have all evidence). This - // transaction will not be proposed again and will be finalised. - if update_mut.stage.is_finalising() { - continue; - } + let atom = cmd.transaction().expect("Command must be a transaction"); - update_mut - .evidence_mut() - .add_qc_evidence(local_committee_info, justify_id); - - if !update_mut.is_ready { - let local_prepare_is_justified = - update_mut.stage.is_local_prepared() && update_mut.evidence().all_input_addresses_justified(); - let local_accept_is_justified = - update_mut.stage.is_local_accepted() && update_mut.evidence().all_addresses_justified(); - if local_prepare_is_justified { - info!( - target: LOG_TARGET, - "✅ All inputs justified for transaction {} in block {} is now ready for AllPrepared", - atom.id(), - leaf, - ); - update_mut.is_ready = true; - } else if local_accept_is_justified { - info!( - target: LOG_TARGET, - "✅ All inputs justified for transaction {} in block {} is now ready for AllAccepted", - atom.id(), - leaf, - ); - update_mut.is_ready = true; - } else { - // Nothing - we've updated the evidence and is_ready remains false - debug!( - target: LOG_TARGET, - "Transaction {} stage: {} still not ready", - atom.id(), - update_mut.stage - ); - } - } + let Some(mut pool_tx) = change_set.get_transaction(tx, &locked_block, &leaf, atom.id())? else { + return Err(HotStuffError::InvariantError(format!( + "Transaction {} in newly justified block {} not found in the pool", + atom.id(), + leaf, + ))); + }; + + if cmd.is_local_prepare() { + pool_tx.add_prepare_qc_evidence(local_committee_info, justify_id); + } else if cmd.is_local_accept() { + pool_tx.add_accept_qc_evidence(local_committee_info, justify_id); } else { - // No update from current leaf, so the current pool data is the latest - let Some(mut pool_tx) = self.transaction_pool.get(tx, leaf, atom.id()).optional()? else { - return Err(HotStuffError::InvariantError(format!( - "Transaction {} in newly justified block {} not found in the pool", - atom.id(), - leaf, - ))); - }; - - pool_tx.add_qc_evidence(local_committee_info, justify_id); - - if pool_tx.is_ready() { - change_set.set_next_transaction_update(&pool_tx, pool_tx.current_stage(), true)?; + // Nothing + } + + if !pool_tx.is_ready() { + if pool_tx.current_stage().is_local_prepared() && pool_tx.evidence().all_input_addresses_prepared() { + pool_tx.set_next_stage(TransactionPoolStage::LocalPrepared, true)?; + } else if pool_tx.current_stage().is_local_accepted() && pool_tx.evidence().all_addresses_justified() { + pool_tx.set_next_stage(TransactionPoolStage::LocalAccepted, true)?; } else { - let local_prepare_is_justified = cmd - .local_prepare() - .map(|_| pool_tx.evidence().all_input_addresses_justified()) - .unwrap_or(false); - let local_accept_is_justified = cmd - .local_accept() - .map(|_| pool_tx.evidence().all_addresses_justified()) - .unwrap_or(false); - let is_ready = local_prepare_is_justified || local_accept_is_justified; - - // Some logs - if local_prepare_is_justified { - info!( - target: LOG_TARGET, - "✅ All inputs justified for transaction {} in block {} is now ready for AllPrepared", - atom.id(), - leaf, - ); - } else if local_accept_is_justified { - info!( - target: LOG_TARGET, - "✅ All inputs justified for transaction {} in block {} is now ready for AllAccepted", - atom.id(), - leaf, - ); - } else { - // Nothing - we'll still update the evidence with is_ready = false - } - change_set.set_next_transaction_update(&pool_tx, pool_tx.current_stage(), is_ready)?; + // Nothing } } + + change_set.set_next_transaction_update(pool_tx)?; } Ok(()) @@ -292,12 +234,22 @@ where TConsensusSpec: ConsensusSpec local_committee_info: &CommitteeInfo, valid_block: &ValidBlock, can_propose_epoch_end: bool, - ) -> Result { + foreign_committee_infos: &HashMap, + proposed_block_change_set: &mut ProposedBlockChangeSet, + ) -> Result<(), HotStuffError> { if !self.should_vote(tx, valid_block.block())? { - return Ok(ProposedBlockChangeSet::new(valid_block.block().as_leaf_block()).no_vote()); + proposed_block_change_set.no_vote(); + return Ok(()); } - self.decide_what_to_vote(tx, valid_block.block(), local_committee_info, can_propose_epoch_end) + self.decide_what_to_vote( + tx, + valid_block.block(), + local_committee_info, + can_propose_epoch_end, + foreign_committee_infos, + proposed_block_change_set, + ) } /// if b_new .height > vheight && (b_new extends b_lock || b_new .justify.node.height > b_lock .height) @@ -334,12 +286,14 @@ where TConsensusSpec: ConsensusSpec block: &Block, local_committee_info: &CommitteeInfo, can_propose_epoch_end: bool, - ) -> Result { + foreign_committee_infos: &HashMap, + proposed_block_change_set: &mut ProposedBlockChangeSet, + ) -> Result<(), HotStuffError> { // Store used for transactions that have inputs without specific versions. // It lives through the entire block so multiple transactions can be sequenced together in the same block let mut substate_store = PendingSubstateStore::new(tx, *block.parent(), self.config.num_preshards); - let mut proposed_block_change_set = ProposedBlockChangeSet::new(block.as_leaf_block()); let mut total_leader_fee = 0; + let locked_block = LockedBlock::get(tx)?; for cmd in block.commands() { match cmd { @@ -347,74 +301,112 @@ where TConsensusSpec: ConsensusSpec if !self.evaluate_local_only_command( tx, block, + &locked_block, atom, local_committee_info, &mut substate_store, - &mut proposed_block_change_set, + proposed_block_change_set, &mut total_leader_fee, )? { - return Ok(proposed_block_change_set.no_vote()); + proposed_block_change_set.no_vote(); + return Ok(()); } }, Command::Prepare(atom) => { if !self.evaluate_prepare_command( tx, block, + &locked_block, atom, local_committee_info, &mut substate_store, - &mut proposed_block_change_set, + proposed_block_change_set, )? { - return Ok(proposed_block_change_set.no_vote()); + proposed_block_change_set.no_vote(); + return Ok(()); } }, Command::LocalPrepare(atom) => { - if !self.evaluate_local_prepare_command(tx, block, atom, &mut proposed_block_change_set)? { - return Ok(proposed_block_change_set.no_vote()); + if !self.evaluate_local_prepare_command( + tx, + block, + &locked_block, + atom, + proposed_block_change_set, + )? { + proposed_block_change_set.no_vote(); + return Ok(()); } }, Command::AllPrepare(atom) => { - if !self.evaluate_all_prepare_command(tx, block, atom, &mut proposed_block_change_set)? { - return Ok(proposed_block_change_set.no_vote()); - } - }, - Command::SomePrepare(atom) => { - if !self.evaluate_some_prepare_command(tx, block, atom, &mut proposed_block_change_set)? { - return Ok(proposed_block_change_set.no_vote()); - } - }, - Command::LocalAccept(atom) => { - if !self.evaluate_local_accept_command( + // Execute here + if !self.evaluate_all_prepare_command( tx, block, + &locked_block, atom, local_committee_info, &mut substate_store, - &mut proposed_block_change_set, + proposed_block_change_set, )? { - return Ok(proposed_block_change_set.no_vote()); + proposed_block_change_set.no_vote(); + return Ok(()); + } + }, + Command::SomePrepare(atom) => { + if !self.evaluate_some_prepare_command(tx, block, &locked_block, atom, proposed_block_change_set)? { + proposed_block_change_set.no_vote(); + return Ok(()); + } + }, + Command::LocalAccept(atom) => { + if !self.evaluate_local_accept_command(tx, block, &locked_block, atom, proposed_block_change_set)? { + proposed_block_change_set.no_vote(); + return Ok(()); } }, Command::AllAccept(atom) => { if !self.evaluate_all_accept_command( tx, block, + &locked_block, atom, local_committee_info, &mut substate_store, - &mut proposed_block_change_set, + proposed_block_change_set, )? { - return Ok(proposed_block_change_set.no_vote()); + proposed_block_change_set.no_vote(); + return Ok(()); } }, Command::SomeAccept(atom) => { - if !self.evaluate_some_accept_command(tx, block, atom, &mut proposed_block_change_set)? { - return Ok(proposed_block_change_set.no_vote()); + if !self.evaluate_some_accept_command(tx, block, &locked_block, atom, proposed_block_change_set)? { + proposed_block_change_set.no_vote(); + return Ok(()); } }, Command::ForeignProposal(fp_atom) => { - if !self.evaluate_foreign_proposal_command(tx, fp_atom, &mut proposed_block_change_set)? { - return Ok(proposed_block_change_set.no_vote()); + let Some(foreign_committee_info) = foreign_committee_infos.get(&fp_atom.block_id) else { + warn!( + target: LOG_TARGET, + "❌ NO VOTE: ForeignProposal command in block {} but no foreign proposal found", + fp_atom.block_id, + ); + proposed_block_change_set.no_vote(); + return Ok(()); + }; + + if !self.evaluate_foreign_proposal_command( + tx, + block, + &locked_block, + fp_atom, + local_committee_info, + foreign_committee_info, + proposed_block_change_set, + )? { + proposed_block_change_set.no_vote(); + return Ok(()); } continue; @@ -425,9 +417,10 @@ where TConsensusSpec: ConsensusSpec atom, local_committee_info, &mut substate_store, - &mut proposed_block_change_set, + proposed_block_change_set, )? { - return Ok(proposed_block_change_set.no_vote()); + proposed_block_change_set.no_vote(); + return Ok(()); } }, Command::EndEpoch => { @@ -437,7 +430,8 @@ where TConsensusSpec: ConsensusSpec "❌ EpochEvent::End command received for block {} but it is not the next epoch", block.id(), ); - return Ok(proposed_block_change_set.no_vote()); + proposed_block_change_set.no_vote(); + return Ok(()); } if block.commands().len() > 1 { warn!( @@ -445,7 +439,8 @@ where TConsensusSpec: ConsensusSpec "❌ EpochEvent::End command in block {} but block contains other commands", block.id() ); - return Ok(proposed_block_change_set.no_vote()); + proposed_block_change_set.no_vote(); + return Ok(()); } continue; @@ -461,7 +456,8 @@ where TConsensusSpec: ConsensusSpec block.total_leader_fee(), total_leader_fee ); - return Ok(proposed_block_change_set.no_vote()); + proposed_block_change_set.no_vote(); + return Ok(()); } let pending = PendingShardStateTreeDiff::get_all_up_to_commit_block(tx, block.justify().block_id())?; @@ -483,7 +479,8 @@ where TConsensusSpec: ConsensusSpec block.merkle_root(), expected_merkle_root ); - return Ok(proposed_block_change_set.no_vote()); + proposed_block_change_set.no_vote(); + return Ok(()); } let (diff, locks) = substate_store.into_parts(); @@ -493,7 +490,7 @@ where TConsensusSpec: ConsensusSpec .set_substate_locks(locks) .set_quorum_decision(QuorumDecision::Accept); - Ok(proposed_block_change_set) + Ok(()) } #[allow(clippy::too_many_lines)] @@ -501,16 +498,15 @@ where TConsensusSpec: ConsensusSpec &self, tx: &::ReadTransaction<'_>, block: &Block, + locked_block: &LockedBlock, atom: &TransactionAtom, local_committee_info: &CommitteeInfo, substate_store: &mut PendingSubstateStore, proposed_block_change_set: &mut ProposedBlockChangeSet, total_leader_fee: &mut u64, ) -> Result { - let Some(mut tx_rec) = self - .transaction_pool - .get(tx, block.as_leaf_block(), atom.id()) - .optional()? + let Some(mut tx_rec) = + proposed_block_change_set.get_transaction(tx, locked_block, &block.as_leaf_block(), atom.id())? else { warn!( target: LOG_TARGET, @@ -656,7 +652,8 @@ where TConsensusSpec: ConsensusSpec }, } - proposed_block_change_set.set_next_transaction_update(&tx_rec, TransactionPoolStage::LocalOnly, false)?; + tx_rec.set_next_stage(TransactionPoolStage::LocalOnly, false)?; + proposed_block_change_set.set_next_transaction_update(tx_rec)?; Ok(true) } @@ -664,15 +661,14 @@ where TConsensusSpec: ConsensusSpec &self, tx: &::ReadTransaction<'_>, block: &Block, + locked_block: &LockedBlock, atom: &TransactionAtom, local_committee_info: &CommitteeInfo, substate_store: &mut PendingSubstateStore, proposed_block_change_set: &mut ProposedBlockChangeSet, ) -> Result { - let Some(mut tx_rec) = self - .transaction_pool - .get(tx, block.as_leaf_block(), atom.id()) - .optional()? + let Some(mut tx_rec) = + proposed_block_change_set.get_transaction(tx, locked_block, &block.as_leaf_block(), atom.id())? else { warn!( target: LOG_TARGET, @@ -754,7 +750,8 @@ where TConsensusSpec: ConsensusSpec }, } - proposed_block_change_set.set_next_transaction_update(&tx_rec, TransactionPoolStage::Prepared, true)?; + tx_rec.set_next_stage(TransactionPoolStage::Prepared, true)?; + proposed_block_change_set.set_next_transaction_update(tx_rec)?; Ok(true) } @@ -763,13 +760,12 @@ where TConsensusSpec: ConsensusSpec &self, tx: &::ReadTransaction<'_>, block: &Block, + locked_block: &LockedBlock, atom: &TransactionAtom, proposed_block_change_set: &mut ProposedBlockChangeSet, ) -> Result { - let Some(tx_rec) = self - .transaction_pool - .get(tx, block.as_leaf_block(), atom.id()) - .optional()? + let Some(mut tx_rec) = + proposed_block_change_set.get_transaction(tx, locked_block, &block.as_leaf_block(), atom.id())? else { warn!( target: LOG_TARGET, @@ -818,35 +814,28 @@ where TConsensusSpec: ConsensusSpec return Ok(false); } - proposed_block_change_set.set_next_transaction_update( - &tx_rec, + tx_rec.set_next_stage( TransactionPoolStage::LocalPrepared, - tx_rec.evidence().all_input_addresses_justified(), + tx_rec.evidence().all_input_addresses_prepared(), )?; + proposed_block_change_set.set_next_transaction_update(tx_rec)?; Ok(true) } + #[allow(clippy::too_many_lines)] fn evaluate_all_prepare_command( &self, tx: &::ReadTransaction<'_>, block: &Block, + locked_block: &LockedBlock, atom: &TransactionAtom, + local_committee_info: &CommitteeInfo, + substate_store: &mut PendingSubstateStore, proposed_block_change_set: &mut ProposedBlockChangeSet, ) -> Result { - if atom.decision.is_abort() { - warn!( - target: LOG_TARGET, - "❌ AllPrepare command received for block {} but requires that the transaction is COMMIT", - block.id(), - ); - return Ok(false); - } - - let Some(tx_rec) = self - .transaction_pool - .get(tx, block.as_leaf_block(), atom.id()) - .optional()? + let Some(mut tx_rec) = + proposed_block_change_set.get_transaction(tx, locked_block, &block.as_leaf_block(), atom.id())? else { warn!( target: LOG_TARGET, @@ -860,7 +849,7 @@ where TConsensusSpec: ConsensusSpec if !tx_rec.current_stage().is_local_prepared() { warn!( target: LOG_TARGET, - "{} ❌ Stage disagreement in block {} for transaction {}. Leader proposed AllPrepare, but local stage is {}", + "{} ❌ Stage disagreement in block {} for transaction {}. Leader proposed AllPrepare, but current stage is {}", self.local_validator_pk, block, tx_rec.transaction_id(), @@ -869,16 +858,110 @@ where TConsensusSpec: ConsensusSpec return Ok(false); } - if tx_rec.current_decision().is_abort() { + // If we've already decided to abort, we cannot change to commit in LocalPrepared phase so proposing AllPrepared + // is invalid + if tx_rec.current_decision().is_abort() && atom.decision.is_commit() { + warn!( + target: LOG_TARGET, + "❌ NO VOTE AllPrepare: decision disagreement for transaction {} in block {}. Leader proposed {}, we decided {}", + tx_rec.transaction_id(), + block, + atom.decision, + tx_rec.current_decision() + ); + return Ok(false); + } + + if !tx_rec.evidence().all_input_addresses_prepared() { warn!( target: LOG_TARGET, - "❌ AllPrepare decision disagreement for transaction {} in block {}. Leader proposed COMMIT, we decided ABORT", + "❌ NO VOTE: AllPrepare disagreement for transaction {} in block {}. Leader proposed that all inputs are justified, but not all inputs are justified", tx_rec.transaction_id(), block, ); return Ok(false); } + let maybe_execution = if tx_rec.current_decision().is_commit() { + let execution = self.execute_transaction(tx, block.id(), block.epoch(), tx_rec.transaction_id())?; + let mut execution = execution.into_transaction_execution(); + + // TODO: can we modify the locks at this point? For multi-shard input transactions, we locked all inputs + // as Write due to lack of information. We now know what locks are necessary, and this + // block has the correct evidence (TODO: verify the atom) so this should be fine. + tx_rec.update_from_execution(&execution); + + if execution.decision().is_commit() { + // Lock all local outputs + let local_outputs = execution.resulting_outputs().iter().filter(|o| { + o.substate_id().is_transaction_receipt() || + local_committee_info.includes_substate_address(&o.to_substate_address()) + }); + let lock_status = substate_store.try_lock_all(*tx_rec.transaction_id(), local_outputs, false)?; + if let Some(err) = lock_status.failures().first() { + if atom.decision.is_commit() { + // If we disagree with any local decision we abstain from voting + warn!( + target: LOG_TARGET, + "❌ NO VOTE LocalAccept: Lock failure: {} but leader decided COMMIT for tx {} in block {}. Leader proposed COMMIT, we decided ABORT", + err, + tx_rec.transaction_id(), + block, + ); + return Ok(false); + } + + info!( + target: LOG_TARGET, + "⚠️ Failed to lock outputs for transaction {} in block {}. Error: {}", + block, + tx_rec.transaction_id(), + err + ); + + tx_rec.set_local_decision(Decision::Abort); + execution.set_abort_reason(RejectReason::FailedToLockOutputs(err.to_string())); + + tx_rec.set_next_stage(TransactionPoolStage::AllPrepared, true)?; + proposed_block_change_set + .set_next_transaction_update(tx_rec)? + .add_transaction_execution(execution)?; + + return Ok(true); + } + } + + Some(execution) + } else { + // If we already locally decided to abort, there is no purpose in executing the transaction + None + }; + + // We check that the leader decision is the same as our local decision. + if tx_rec.current_decision() != atom.decision { + warn!( + target: LOG_TARGET, + "❌ NO VOTE LocalAccept: decision disagreement for transaction {} in block {}. Leader proposed {}, we decided {}", + tx_rec.transaction_id(), + block, + atom.decision, + tx_rec.current_decision() + ); + return Ok(false); + } + + if tx_rec.transaction_fee() != atom.transaction_fee { + warn!( + target: LOG_TARGET, + "❌ NO VOTE LocalAccept: transaction fee disagreement tx {} in block {}. Leader proposed {}, we calculated {}", + tx_rec.transaction_id(), + block, + atom.transaction_fee, + tx_rec.transaction_fee() + ); + return Ok(false); + } + if tx_rec.transaction_fee() != atom.transaction_fee { warn!( target: LOG_TARGET, @@ -890,22 +973,14 @@ where TConsensusSpec: ConsensusSpec ); return Ok(false); } - // TODO: there is a race condition between the local node receiving the foreign LocalPrepare and the leader - // proposing AllPrepare. If the latter comes first (because the leader received the foreign LocalPrepare), - // this node will not vote on this block which leads inevitably to erroneous leader failures. For this reason, - // this is commented out for now. - - // if !tx_rec.evidence().all_input_addresses_justified() { - // warn!( - // target: LOG_TARGET, - // "❌ LocalPrepare disagreement for transaction {} in block {}. Leader proposed that all committees - // have justified, but local evidence is not all justified", tx_rec.transaction_id(), - // block, - // ); - // return Ok(false); - // } - // - proposed_block_change_set.set_next_transaction_update(&tx_rec, TransactionPoolStage::AllPrepared, true)?; + + // maybe_execution is only None if the transaction is not committed + if let Some(execution) = maybe_execution { + proposed_block_change_set.add_transaction_execution(execution)?; + } + + tx_rec.set_next_stage(TransactionPoolStage::AllPrepared, true)?; + proposed_block_change_set.set_next_transaction_update(tx_rec)?; Ok(true) } @@ -914,6 +989,7 @@ where TConsensusSpec: ConsensusSpec &self, tx: &::ReadTransaction<'_>, block: &Block, + locked_block: &LockedBlock, atom: &TransactionAtom, proposed_block_change_set: &mut ProposedBlockChangeSet, ) -> Result { @@ -926,10 +1002,8 @@ where TConsensusSpec: ConsensusSpec return Ok(false); } - let Some(tx_rec) = self - .transaction_pool - .get(tx, block.as_leaf_block(), atom.id()) - .optional()? + let Some(mut tx_rec) = + proposed_block_change_set.get_transaction(tx, locked_block, &block.as_leaf_block(), atom.id())? else { warn!( target: LOG_TARGET, @@ -940,6 +1014,8 @@ where TConsensusSpec: ConsensusSpec return Ok(false); }; + // If the local node would decide SomePrepare too, we should have already ABORTed due to foreign prepare abort + // or local input lock conflict if tx_rec.current_decision().is_commit() { warn!( target: LOG_TARGET, @@ -974,25 +1050,22 @@ where TConsensusSpec: ConsensusSpec return Ok(false); } - proposed_block_change_set.set_next_transaction_update(&tx_rec, TransactionPoolStage::SomePrepared, true)?; + tx_rec.set_next_stage(TransactionPoolStage::SomePrepared, true)?; + proposed_block_change_set.set_next_transaction_update(tx_rec)?; Ok(true) } - #[allow(clippy::too_many_lines)] fn evaluate_local_accept_command( &self, tx: &::ReadTransaction<'_>, block: &Block, + locked_block: &LockedBlock, atom: &TransactionAtom, - local_committee_info: &CommitteeInfo, - substate_store: &mut PendingSubstateStore, proposed_block_change_set: &mut ProposedBlockChangeSet, ) -> Result { - let Some(mut tx_rec) = self - .transaction_pool - .get(tx, block.as_leaf_block(), atom.id()) - .optional()? + let Some(mut tx_rec) = + proposed_block_change_set.get_transaction(tx, locked_block, &block.as_leaf_block(), atom.id())? else { warn!( target: LOG_TARGET, @@ -1015,60 +1088,6 @@ where TConsensusSpec: ConsensusSpec return Ok(false); } - let maybe_execution = if tx_rec.current_decision().is_commit() { - let execution = self.execute_transaction(tx, block.id(), block.epoch(), tx_rec.transaction_id())?; - let mut execution = execution.into_transaction_execution(); - - // TODO: can we modify the locks at this point? For multi-shard input transactions, we locked all inputs as - // Write due to lack of information. We now know what locks are necessary, and this block has the correct - // evidence (TODO: verify the atom) so this should be fine. - tx_rec.update_from_execution(&execution); - - // Lock all local outputs - let local_outputs = execution.resulting_outputs().iter().filter(|o| { - o.substate_id().is_transaction_receipt() || - local_committee_info.includes_substate_address(&o.to_substate_address()) - }); - let lock_status = substate_store.try_lock_all(*tx_rec.transaction_id(), local_outputs, false)?; - if let Some(err) = lock_status.failures().first() { - if atom.decision.is_commit() { - // If we disagree with any local decision we abstain from voting - warn!( - target: LOG_TARGET, - "❌ NO VOTE LocalAccept: Lock failure: {} but leader decided COMMIT for tx {} in block {}. Leader proposed COMMIT, we decided ABORT", - err, - tx_rec.transaction_id(), - block, - ); - return Ok(false); - } - - info!( - target: LOG_TARGET, - "⚠️ Failed to lock outputs for transaction {} in block {}. Error: {}", - block, - tx_rec.transaction_id(), - err - ); - - tx_rec.set_local_decision(Decision::Abort); - execution.set_abort_reason(RejectReason::FailedToLockOutputs(err.to_string())); - proposed_block_change_set - .set_next_transaction_update( - &tx_rec, - TransactionPoolStage::LocalAccepted, - tx_rec.evidence().all_addresses_justified(), - )? - .add_transaction_execution(execution)?; - - return Ok(true); - } - Some(execution) - } else { - // If we already locally decided to abort, there is no purpose in executing the transaction - None - }; - // We check that the leader decision is the same as our local decision. // We disregard the remote decision because not all validators may have received the foreign // LocalPrepared yet. We will never accept a decision disagreement for the Accept command. @@ -1096,16 +1115,11 @@ where TConsensusSpec: ConsensusSpec return Ok(false); } - // maybe_execution is only None if the transaction is not committed - if let Some(execution) = maybe_execution { - proposed_block_change_set.add_transaction_execution(execution)?; - } - - proposed_block_change_set.set_next_transaction_update( - &tx_rec, + tx_rec.set_next_stage( TransactionPoolStage::LocalAccepted, tx_rec.evidence().all_addresses_justified(), )?; + proposed_block_change_set.set_next_transaction_update(tx_rec)?; Ok(true) } @@ -1114,6 +1128,7 @@ where TConsensusSpec: ConsensusSpec &self, tx: &::ReadTransaction<'_>, block: &Block, + locked_block: &LockedBlock, atom: &TransactionAtom, local_committee_info: &CommitteeInfo, substate_store: &mut PendingSubstateStore, @@ -1128,10 +1143,8 @@ where TConsensusSpec: ConsensusSpec return Ok(false); } - let Some(tx_rec) = self - .transaction_pool - .get(tx, block.as_leaf_block(), atom.id()) - .optional()? + let Some(mut tx_rec) = + proposed_block_change_set.get_transaction(tx, locked_block, &block.as_leaf_block(), atom.id())? else { warn!( target: LOG_TARGET, @@ -1197,7 +1210,8 @@ where TConsensusSpec: ConsensusSpec &filter_diff_for_committee(local_committee_info, diff), )?; - proposed_block_change_set.set_next_transaction_update(&tx_rec, TransactionPoolStage::AllAccepted, false)?; + tx_rec.set_next_stage(TransactionPoolStage::AllAccepted, false)?; + proposed_block_change_set.set_next_transaction_update(tx_rec)?; Ok(true) } @@ -1206,6 +1220,7 @@ where TConsensusSpec: ConsensusSpec &self, tx: &::ReadTransaction<'_>, block: &Block, + locked_block: &LockedBlock, atom: &TransactionAtom, proposed_block_change_set: &mut ProposedBlockChangeSet, ) -> Result { @@ -1218,10 +1233,8 @@ where TConsensusSpec: ConsensusSpec return Ok(false); } - let Some(tx_rec) = self - .transaction_pool - .get(tx, block.as_leaf_block(), atom.id()) - .optional()? + let Some(mut tx_rec) = + proposed_block_change_set.get_transaction(tx, locked_block, &block.as_leaf_block(), atom.id())? else { warn!( target: LOG_TARGET, @@ -1293,7 +1306,8 @@ where TConsensusSpec: ConsensusSpec } } - proposed_block_change_set.set_next_transaction_update(&tx_rec, TransactionPoolStage::SomeAccepted, false)?; + tx_rec.set_next_stage(TransactionPoolStage::SomeAccepted, false)?; + proposed_block_change_set.set_next_transaction_update(tx_rec)?; Ok(true) } @@ -1301,16 +1315,66 @@ where TConsensusSpec: ConsensusSpec fn evaluate_foreign_proposal_command( &self, tx: &::ReadTransaction<'_>, + block: &Block, + locked_block: &LockedBlock, fp_atom: &ForeignProposalAtom, + local_committee_info: &CommitteeInfo, + foreign_committee_info: &CommitteeInfo, proposed_block_change_set: &mut ProposedBlockChangeSet, ) -> Result { - if !fp_atom.exists(tx)? { + if proposed_block_change_set + .proposed_foreign_proposals() + .contains(&fp_atom.block_id) + { + warn!( + target: LOG_TARGET, + "❌ NO VOTE: Foreign proposal for block {block_id} has already been proposed in this block.", + block_id = fp_atom.block_id, + ); + return Ok(false); + } + + let Some(fp) = fp_atom.get_proposal(tx).optional()? else { warn!( target: LOG_TARGET, "❌ NO VOTE: Foreign proposal for block {block_id} has not been received.", block_id = fp_atom.block_id, ); return Ok(false); + }; + + // Case: cannot re-propose if it is already committed + // TODO: if this is already proposed we need to reject if it is already proposed in the current block's + // commit->leaf chain Currently we allow it to be proposed again + if matches!(fp.status(), ForeignProposalStatus::Confirmed) { + warn!( + target: LOG_TARGET, + "❌ NO VOTE: Foreign proposal for block {block_id} has status {status}.", + block_id = fp_atom.block_id, + status = fp.status(), + ); + return Ok(false); + } + + if let Err(err) = process_foreign_block( + tx, + &block.as_leaf_block(), + locked_block, + fp, + // NB: dont put these args in the wrong order + foreign_committee_info, + local_committee_info, + proposed_block_change_set, + ) { + // TODO: split validation errors from HotStuff errors so that we can selectively crash or not vote + warn!( + target: LOG_TARGET, + "❌ NO VOTE: Failed to process foreign proposal for block {block_id} (shard group: {shard_group}). Error: {error}", + block_id = fp_atom.block_id, + error = err, + shard_group = foreign_committee_info.shard_group(), + ); + return Ok(false); } proposed_block_change_set.set_foreign_proposal_proposed_in(fp_atom.block_id); @@ -1416,25 +1480,20 @@ where TConsensusSpec: ConsensusSpec fn on_lock_block( &self, tx: &mut ::WriteTransaction<'_>, - locked: &LockedBlock, - block: &Block, + new_locked_block: &Block, ) -> Result<(), HotStuffError> { info!( target: LOG_TARGET, "🔒️ LOCKED BLOCK: {}", - block, + new_locked_block, ); // Release all locks for SomePrepare transactions since these can never be committed - SubstateRecord::unlock_all(tx, block.all_some_prepare().map(|t| &t.id).peekable())?; + SubstateRecord::unlock_all(tx, new_locked_block.all_some_prepare().map(|t| &t.id).peekable())?; // This moves the stage update from pending to current for all transactions on the locked block - self.transaction_pool.confirm_all_transitions( - tx, - locked, - &block.as_locked_block(), - block.all_transaction_ids(), - )?; + self.transaction_pool + .confirm_all_transitions(tx, &new_locked_block.as_locked_block())?; Ok(()) } @@ -1462,7 +1521,8 @@ where TConsensusSpec: ConsensusSpec ); for atom in block.all_foreign_proposals() { - atom.delete(tx)?; + // TODO: we need to keep these ATM to send them if a node needs to catch up + atom.set_status(tx, ForeignProposalStatus::Confirmed)?; } for atom in block.all_confidential_output_mints() { diff --git a/dan_layer/consensus/src/hotstuff/on_receive_foreign_proposal.rs b/dan_layer/consensus/src/hotstuff/on_receive_foreign_proposal.rs index 87f8ce65f..f74ef6ef9 100644 --- a/dan_layer/consensus/src/hotstuff/on_receive_foreign_proposal.rs +++ b/dan_layer/consensus/src/hotstuff/on_receive_foreign_proposal.rs @@ -2,21 +2,9 @@ // SPDX-License-Identifier: BSD-3-Clause use log::*; -use tari_dan_common_types::{committee::CommitteeInfo, optional::Optional, ShardGroup, ToSubstateAddress}; +use tari_dan_common_types::{committee::CommitteeInfo, ShardGroup}; use tari_dan_storage::{ - consensus_models::{ - Block, - BlockId, - BlockPledge, - Command, - ForeignProposal, - ForeignReceiveCounters, - LeafBlock, - TransactionAtom, - TransactionPool, - TransactionPoolRecord, - TransactionPoolStage, - }, + consensus_models::{Block, ForeignProposal, ForeignReceiveCounters}, StateStore, }; use tari_epoch_manager::EpochManagerReader; @@ -29,10 +17,10 @@ use crate::{ const LOG_TARGET: &str = "tari::dan::consensus::hotstuff::on_receive_foreign_proposal"; +#[derive(Clone)] pub struct OnReceiveForeignProposalHandler { store: TConsensusSpec::StateStore, epoch_manager: TConsensusSpec::EpochManager, - transaction_pool: TransactionPool, pacemaker: PaceMakerHandle, } @@ -42,40 +30,51 @@ where TConsensusSpec: ConsensusSpec pub fn new( store: TConsensusSpec::StateStore, epoch_manager: TConsensusSpec::EpochManager, - transaction_pool: TransactionPool, pacemaker: PaceMakerHandle, ) -> Self { Self { store, epoch_manager, - transaction_pool, pacemaker, } } - #[allow(clippy::too_many_lines)] pub async fn handle( &mut self, - from: TConsensusSpec::Addr, message: ForeignProposalMessage, local_committee_info: &CommitteeInfo, + ) -> Result<(), HotStuffError> { + let foreign_committee_info = self + .epoch_manager + .get_committee_info_by_validator_public_key(message.block.epoch(), message.block.proposed_by()) + .await?; + self.validate_and_save(message, local_committee_info, &foreign_committee_info)?; + Ok(()) + } + + pub fn validate_and_save( + &mut self, + message: ForeignProposalMessage, + local_committee_info: &CommitteeInfo, + foreign_committee_info: &CommitteeInfo, ) -> Result<(), HotStuffError> { let proposal = ForeignProposal::from(message); + if self.store.with_read_tx(|tx| proposal.exists(tx))? { + // This is expected behaviour, we may receive the same foreign proposal multiple times + debug!( + target: LOG_TARGET, + "FOREIGN PROPOSAL: Already received proposal for block {}", + proposal.block().id(), + ); + return Ok(()); + } + // TODO: validate justify_qc let mut foreign_receive_counter = self .store .with_read_tx(|tx| ForeignReceiveCounters::get_or_default(tx))?; - let vn = self - .epoch_manager - .get_validator_node_by_public_key(proposal.block().epoch(), proposal.block().proposed_by()) - .await?; - let foreign_committee_info = self - .epoch_manager - .get_committee_info_for_substate(proposal.block().epoch(), vn.shard_key) - .await?; - if let Err(err) = self.validate_proposed_block( proposal.block(), foreign_committee_info.shard_group(), @@ -84,8 +83,7 @@ where TConsensusSpec: ConsensusSpec ) { warn!( target: LOG_TARGET, - "⚠️ FOREIGN PROPOSAL: Invalid proposal from {}: {}. Ignoring.", - from, + "⚠️ FOREIGN PROPOSAL: Invalid proposal: {}. Ignoring.", err ); // Invalid blocks should not cause the state machine to transition to Error @@ -105,460 +103,419 @@ where TConsensusSpec: ConsensusSpec return Ok(()); } - if self.store.with_read_tx(|tx| proposal.exists(tx))? { - // This is expected behaviour, we may receive the same foreign proposal multiple times - debug!( - target: LOG_TARGET, - "FOREIGN PROPOSAL: Already received proposal for block {}", - proposal.block().id(), - ); - return Ok(()); - } - info!( target: LOG_TARGET, - "🧩 Receive FOREIGN PROPOSAL for block {}, justify_qc: {} from {}", + "🧩 Receive FOREIGN PROPOSAL for block {}, justify_qc: {}", proposal.block(), proposal.justify_qc(), - from, ); - let block_id = *proposal.block().id(); - let result = self.store.with_write_tx(|tx| { + self.store.with_write_tx(|tx| { foreign_receive_counter.save(tx)?; - proposal.upsert(tx, None)?; - self.on_receive_foreign_block(tx, proposal, &foreign_committee_info, local_committee_info) - }); - - match result { - Ok(_) => { - // We could have ready transactions at this point, so if we're the leader for the next block we can - // propose - self.pacemaker.beat(); - }, - Err(err) => { - error!( - target: LOG_TARGET, - "⚠️ FOREIGN PROPOSAL: Failed to process foreign proposal for block {}: {}", - block_id, - err - ); - }, - } - - Ok(()) - } - - #[allow(clippy::too_many_lines)] - fn on_receive_foreign_block( - &self, - tx: &mut ::WriteTransaction<'_>, - foreign_proposal: ForeignProposal, - foreign_committee_info: &CommitteeInfo, - local_committee_info: &CommitteeInfo, - ) -> Result<(), HotStuffError> { - let ForeignProposal { - block, - justify_qc, - mut block_pledge, - .. - } = foreign_proposal; - let local_leaf = LeafBlock::get(&**tx)?; - // We only want to save the QC once if applicable - let mut is_qc_saved = false; - let mut command_count = 0usize; - - for cmd in block.commands() { - match cmd { - Command::LocalPrepare(atom) => { - if !local_committee_info.includes_any_address(atom.evidence.substate_addresses_iter()) { - continue; - } - - debug!( - target: LOG_TARGET, - "🧩 FOREIGN PROPOSAL: Command: LocalPrepare({}, {}), block: {}", - atom.id,atom.decision, block.id(), - ); - - let Some(mut tx_rec) = self.transaction_pool.get(tx, local_leaf, &atom.id).optional()? else { - // If this happens, it could be a bug in the foreign missing transaction handling - warn!( - target: LOG_TARGET, - "⚠️ NEVER HAPPEN: Foreign proposal received for transaction {} but this transaction is not in the pool.", - atom.id - ); - continue; - }; - - if tx_rec.current_stage() > TransactionPoolStage::LocalPrepared { - // TODO: This can happen if the foreign shard group is only responsible for outputs (the input - // SGs have already progressed to LocalAccept) in which case it is safe to ignore this command. - // However we should not send the proposal in the first place (assuming it does not involve any - // other shard-applicable transactions). - warn!( - target: LOG_TARGET, - "⚠️ Foreign LocalPrepare proposal ({}) received LOCAL_PREPARE for transaction {} but current transaction stage is {}. Ignoring.", - block, - tx_rec.transaction_id(), tx_rec.current_stage() - ); - continue; - } - - command_count += 1; - - let remote_decision = atom.decision; - let local_decision = tx_rec.current_decision(); - if remote_decision.is_abort() && local_decision.is_commit() { - info!( - target: LOG_TARGET, - "⚠️ Foreign committee ABORT transaction {}. Update overall decision to ABORT. Local stage: {}, Leaf: {}", - tx_rec.transaction_id(), tx_rec.current_stage(), local_leaf - ); - } - - if !is_qc_saved { - // Save the QCs if it doesnt exist already, we'll reference the QC in subsequent blocks - block.justify().save(tx)?; - justify_qc.save(tx)?; - is_qc_saved = true; - } - - // We need to add the justify QC to the evidence because the all prepare block could not include it - // yet - let mut foreign_evidence = atom.evidence.clone(); - foreign_evidence.add_qc_evidence(foreign_committee_info, *justify_qc.id()); - - // Update the transaction record with any new information provided by this foreign block - tx_rec.update_remote_data( - tx, - remote_decision, - *justify_qc.id(), - foreign_committee_info, - foreign_evidence, - )?; - - self.validate_and_add_pledges( - tx, - &tx_rec, - block.id(), - atom, - &mut block_pledge, - foreign_committee_info, - )?; - - if tx_rec.current_stage().is_new() { - info!( - target: LOG_TARGET, - "🧩 FOREIGN PROPOSAL: (Initial sequence from LocalPrepare) Transaction is ready for Prepare({}, {}) Local Stage: {}", - tx_rec.transaction_id(), - tx_rec.current_decision(), - tx_rec.current_stage() - ); - // If the transaction is New, we're waiting for all foreign pledges. Propose transaction once we - // have them. - - // CASE: One foreign SG is involved in all inputs and executed the transaction, local SG is - // involved in the outputs - let transaction = tx_rec.get_transaction(&**tx)?; - let is_ready = local_committee_info.includes_substate_id(&transaction.to_receipt_id().into()) || - transaction.has_any_local_inputs(local_committee_info) || - transaction.has_all_foreign_input_pledges(&**tx, local_committee_info)?; - - if is_ready { - info!( - target: LOG_TARGET, - "🧩 FOREIGN PROPOSAL: (Initial sequence from LocalPrepare) Transaction is ready for Prepare({}, {}) Local Stage: {}", - tx_rec.transaction_id(), - tx_rec.current_decision(), - tx_rec.current_stage() - ); - tx_rec.add_pending_status_update(tx, local_leaf, TransactionPoolStage::New, true)?; - } else { - info!( - target: LOG_TARGET, - "🧩 FOREIGN PROPOSAL: (Initial sequence from LocalPrepare) Transaction is NOT ready for Prepare({}, {}) Local Stage: {}", - tx_rec.transaction_id(), - tx_rec.current_decision(), - tx_rec.current_stage() - ); - } - } else if tx_rec.current_stage().is_local_prepared() && - tx_rec.evidence().all_input_addresses_justified() - { - // If all shards are complete, and we've already received our LocalPrepared, we can set out - // LocalPrepared transaction as ready to propose ACCEPT. If we have not received - // the local LocalPrepared, the transition will happen when we receive the local - // block. - info!( - target: LOG_TARGET, - "🧩 FOREIGN PROPOSAL: Transaction is ready for propose AllPrepared({}, {}) Local Stage: {}", - tx_rec.transaction_id(), - tx_rec.current_decision(), - tx_rec.current_stage() - ); - - tx_rec.add_pending_status_update(tx, local_leaf, TransactionPoolStage::LocalPrepared, true)?; - // TODO: there is a race condition between the local node receiving the foreign LocalPrepare and - // the leader proposing AllPrepare. If the latter comes first, this node - // will not vote on this block which leads inevitably to erroneous - // leader failures. Currently we simply vote ACCEPT on the block, with is ready == false, so we - // need to handle this here. When we confirm foreign proposals correctly, we can remove this. - } else { - info!( - target: LOG_TARGET, - "🧩 FOREIGN PROPOSAL: Transaction is NOT ready for AllPrepared({}, {}) Local Stage: {}, All Justified: {}. Waiting for local proposal.", - tx_rec.transaction_id(), - tx_rec.current_decision(), - tx_rec.current_stage(), - tx_rec.evidence().all_input_addresses_justified() - ); - tx_rec.add_pending_status_update(tx, local_leaf, tx_rec.current_stage(), tx_rec.is_ready())?; - } - }, - Command::LocalAccept(atom) => { - if !local_committee_info.includes_any_address(atom.evidence.substate_addresses_iter()) { - continue; - } - - debug!( - target: LOG_TARGET, - "🧩 FOREIGN PROPOSAL: Command: LocalAccept({}, {}), block: {}", - atom.id, atom.decision, block.id(), - ); - - let Some(mut tx_rec) = self.transaction_pool.get(tx, local_leaf, &atom.id).optional()? else { - warn!( - target: LOG_TARGET, - "⚠️ NEVER HAPPEN: Foreign proposal received for transaction {} but this transaction is not in the pool.", - atom.id - ); - continue; - }; - - if tx_rec.current_stage() > TransactionPoolStage::LocalAccepted { - warn!( - target: LOG_TARGET, - "⚠️ Foreign proposal {} received LOCAL_ACCEPT for transaction {} but current transaction stage is {}. Ignoring.", - block, - tx_rec.transaction_id(), - tx_rec.current_stage(), - ); - continue; - } - - command_count += 1; - - let remote_decision = atom.decision; - let local_decision = tx_rec.current_local_decision(); - if remote_decision.is_abort() && local_decision.is_commit() { - info!( - target: LOG_TARGET, - "⚠️ Foreign ABORT {}. Update overall decision to ABORT. Local stage: {}, Leaf: {}", - tx_rec.transaction_id(), tx_rec.current_stage(), local_leaf - ); - } - - if !is_qc_saved { - // Save the QCs if it doesn't exist already, we'll reference the QC in subsequent blocks - block.justify().save(tx)?; - justify_qc.save(tx)?; - is_qc_saved = true; - } - - // We need to add the justify QC to the evidence because the all prepare block could not include it - // yet - let mut foreign_evidence = atom.evidence.clone(); - foreign_evidence.add_qc_evidence(foreign_committee_info, *justify_qc.id()); + proposal.upsert(tx, None) + })?; - // Update the transaction record with any new information provided by this foreign block - tx_rec.update_remote_data( - tx, - remote_decision, - *justify_qc.id(), - foreign_committee_info, - foreign_evidence, - )?; - - self.validate_and_add_pledges( - tx, - &tx_rec, - block.id(), - atom, - &mut block_pledge, - foreign_committee_info, - )?; - - // Good debug info - // tx_rec.evidence().iter().for_each(|(addr, ev)| { - // let includes_local = local_committee_info.includes_substate_address(addr); - // log::error!( - // target: LOG_TARGET, - // "🐞 LOCALACCEPT EVIDENCE (l={}, f={}) {}: {}", includes_local, !includes_local, addr, ev - // ); - // }); - - if tx_rec.current_stage().is_new() { - // If the transaction is New, we're waiting for all foreign pledges. Propose transaction once we - // have them. - // CASE: Foreign SGs have pledged all inputs and executed the transaction, local SG is involved - // in the outputs - let transaction = tx_rec.get_transaction(&**tx)?; - let is_ready = local_committee_info.includes_substate_id(&transaction.to_receipt_id().into()) || - transaction.has_any_local_inputs(local_committee_info) || - transaction.has_all_foreign_input_pledges(&**tx, local_committee_info)?; - if is_ready { - info!( - target: LOG_TARGET, - "🧩 FOREIGN PROPOSAL: (Initial sequence from LocalAccept) Transaction is ready for Prepare({}, {}) Local Stage: {}", - tx_rec.transaction_id(), - tx_rec.current_decision(), - tx_rec.current_stage() - ); - tx_rec.add_pending_status_update(tx, local_leaf, TransactionPoolStage::New, true)?; - } else { - info!( - target: LOG_TARGET, - "🧩 FOREIGN PROPOSAL: (Initial sequence from LocalAccept) Transaction is NOT ready for Prepare({}, {}) Local Stage: {}", - tx_rec.transaction_id(), - tx_rec.current_decision(), - tx_rec.current_stage() - ); - } - } else if tx_rec.current_stage().is_local_accepted() && tx_rec.evidence().all_addresses_justified() - { - info!( - target: LOG_TARGET, - "🧩 FOREIGN PROPOSAL: Transaction is ready for propose ALL_ACCEPT({}, {}) Local Stage: {}", - tx_rec.transaction_id(), - tx_rec.current_decision(), - tx_rec.current_stage() - ); - - tx_rec.add_pending_status_update(tx, local_leaf, TransactionPoolStage::LocalAccepted, true)?; - } else { - info!( - target: LOG_TARGET, - "🧩 FOREIGN PROPOSAL: Transaction is NOT ready for ALL_ACCEPT({}, {}) Local Stage: {}, All Justified: {}. Waiting for local proposal.", - tx_rec.transaction_id(), - tx_rec.current_decision(), - tx_rec.current_stage(), - tx_rec.evidence().all_addresses_justified() - ); - // Still need to update the evidence - tx_rec.add_pending_status_update(tx, local_leaf, tx_rec.current_stage(), tx_rec.is_ready())?; - } - }, - // Should never receive this - Command::EndEpoch => { - warn!( - target: LOG_TARGET, - "❓️ NEVER HAPPEN: Foreign proposal received for block {} contains an EndEpoch command. This is invalid behaviour.", - block.id() - ); - continue; - }, - // TODO(perf): Can we find a way to exclude these unused commands to reduce message size? - Command::AllAccept(_) | - Command::SomeAccept(_) | - Command::AllPrepare(_) | - Command::SomePrepare(_) | - Command::Prepare(_) | - Command::LocalOnly(_) | - Command::ForeignProposal(_) | - Command::MintConfidentialOutput(_) => { - // Disregard - continue; - }, - } - } - - info!( - target: LOG_TARGET, - "🧩 FOREIGN PROPOSAL: Processed {} commands from foreign block {}", - command_count, - block.id() - ); - if command_count == 0 { - warn!( - target: LOG_TARGET, - "⚠️ FOREIGN PROPOSAL: No commands were applicable for foreign block {}. Ignoring.", - block.id() - ); - } + // Foreign proposals to propose + self.pacemaker.on_beat(); Ok(()) } - fn validate_and_add_pledges( - &self, - tx: &mut ::WriteTransaction<'_>, - tx_rec: &TransactionPoolRecord, - block_id: &BlockId, - atom: &TransactionAtom, - block_pledge: &mut BlockPledge, - foreign_committee_info: &CommitteeInfo, - ) -> Result<(), HotStuffError> { - #[allow(clippy::mutable_key_type)] - let maybe_pledges = if atom.decision.is_commit() { - let pledges = block_pledge.remove_transaction_pledges(&atom.id).ok_or_else(|| { - HotStuffError::ForeignNodeOmittedTransactionPledges { - foreign_block_id: *block_id, - transaction_id: atom.id, - } - })?; - - // Validate that provided evidence is correct - // TODO: there are a lot of validations to be done on evidence and the foreign block in general, - // this is here as a sanity check and should change to not be a fatal error in consensus - for pledge in &pledges { - let address = pledge.versioned_substate_id().to_substate_address(); - let evidence = - atom.evidence - .get(&address) - .ok_or_else(|| ProposalValidationError::ForeignInvalidPledge { - block_id: *block_id, - transaction_id: atom.id, - details: format!("Pledge {pledge} for address {address} not found in evidence"), - })?; - if evidence.lock.is_output() && pledge.is_input() { - return Err(ProposalValidationError::ForeignInvalidPledge { - block_id: *block_id, - transaction_id: atom.id, - details: format!("Pledge {pledge} is an input but evidence is an output for address {address}"), - } - .into()); - } - if !evidence.lock.is_output() && pledge.is_output() { - return Err(ProposalValidationError::ForeignInvalidPledge { - block_id: *block_id, - transaction_id: atom.id, - details: format!("Pledge {pledge} is an output but evidence is an input for address {address}"), - } - .into()); - } - } - Some(pledges) - } else { - if block_pledge.remove_transaction_pledges(&atom.id).is_some() { - return Err(ProposalValidationError::ForeignInvalidPledge { - block_id: *block_id, - transaction_id: atom.id, - details: "Remote decided ABORT but provided pledges".to_string(), - } - .into()); - } - None - }; - - if let Some(pledges) = maybe_pledges { - // If the foreign shard has committed the transaction, we can add the pledges to the transaction - // record - tx_rec.add_foreign_pledges(tx, foreign_committee_info.shard_group(), pledges)?; - } - - Ok(()) - } + // #[allow(clippy::too_many_lines)] + // fn process_foreign_block( + // &self, + // tx: &mut ::WriteTransaction<'_>, + // foreign_proposal: ForeignProposal, + // foreign_committee_info: &CommitteeInfo, + // local_committee_info: &CommitteeInfo, + // ) -> Result<(), HotStuffError> { + // let ForeignProposal { + // block, + // justify_qc, + // mut block_pledge, + // .. + // } = foreign_proposal; + // let local_leaf = LeafBlock::get(&**tx)?; + // // We only want to save the QC once if applicable + // let mut command_count = 0usize; + // + // for cmd in block.commands() { + // match cmd { + // Command::LocalPrepare(atom) => { + // if !local_committee_info.includes_any_address(atom.evidence.substate_addresses_iter()) { + // continue; + // } + // + // debug!( + // target: LOG_TARGET, + // "🧩 FOREIGN PROPOSAL: Command: LocalPrepare({}, {}), block: {}", + // atom.id,atom.decision, block.id(), + // ); + // + // let Some(mut tx_rec) = self.transaction_pool.get(tx, local_leaf, &atom.id).optional()? else { + // // If this happens, it could be a bug in the foreign missing transaction handling + // warn!( + // target: LOG_TARGET, + // "⚠️ NEVER HAPPEN: Foreign proposal received for transaction {} but this transaction is + // not in the pool.", atom.id + // ); + // continue; + // }; + // + // if tx_rec.current_stage() > TransactionPoolStage::LocalPrepared { + // // TODO: This can happen if the foreign shard group is only responsible for outputs (the + // input // SGs have already progressed to LocalAccept) in which case it is safe to ignore + // this command. // However we should not send the proposal in the first place (assuming it + // does not involve any // other shard-applicable transactions). + // warn!( + // target: LOG_TARGET, + // "⚠️ Foreign LocalPrepare proposal ({}) received LOCAL_PREPARE for transaction {} but + // current transaction stage is {}. Ignoring.", block, + // tx_rec.transaction_id(), tx_rec.current_stage() + // ); + // continue; + // } + // + // command_count += 1; + // + // let remote_decision = atom.decision; + // let local_decision = tx_rec.current_decision(); + // if remote_decision.is_abort() && local_decision.is_commit() { + // info!( + // target: LOG_TARGET, + // "⚠️ Foreign committee ABORT transaction {}. Update overall decision to ABORT. Local + // stage: {}, Leaf: {}", tx_rec.transaction_id(), tx_rec.current_stage(), local_leaf + // ); + // } + // + // // We need to add the justify QC to the evidence because the all prepare block could not include + // it // yet + // let mut foreign_evidence = atom.evidence.clone(); + // foreign_evidence.add_qc_evidence(foreign_committee_info, *justify_qc.id()); + // + // // Update the transaction record with any new information provided by this foreign block + // tx_rec.update_remote_data( + // tx, + // remote_decision, + // *justify_qc.id(), + // foreign_committee_info, + // foreign_evidence, + // )?; + // + // self.validate_and_add_pledges( + // tx, + // &tx_rec, + // block.id(), + // atom, + // &mut block_pledge, + // foreign_committee_info, + // )?; + // + // if tx_rec.current_stage().is_new() { + // info!( + // target: LOG_TARGET, + // "🧩 FOREIGN PROPOSAL: (Initial sequence from LocalPrepare) Transaction is ready for + // Prepare({}, {}) Local Stage: {}", tx_rec.transaction_id(), + // tx_rec.current_decision(), + // tx_rec.current_stage() + // ); + // // If the transaction is New, we're waiting for all foreign pledges. Propose transaction once + // we // have them. + // + // // CASE: One foreign SG is involved in all inputs and executed the transaction, local SG is + // // involved in the outputs + // let transaction = tx_rec.get_transaction(&**tx)?; + // let is_ready = local_committee_info.includes_substate_id(&transaction.to_receipt_id().into()) + // || transaction.has_any_local_inputs(local_committee_info) || + // transaction.has_all_foreign_input_pledges(&**tx, local_committee_info)?; + // + // if is_ready { + // info!( + // target: LOG_TARGET, + // "🧩 FOREIGN PROPOSAL: (Initial sequence from LocalPrepare) Transaction is ready for + // Prepare({}, {}) Local Stage: {}", tx_rec.transaction_id(), + // tx_rec.current_decision(), + // tx_rec.current_stage() + // ); + // tx_rec.add_pending_status_update(tx, local_leaf, TransactionPoolStage::New, true)?; + // } else { + // info!( + // target: LOG_TARGET, + // "🧩 FOREIGN PROPOSAL: (Initial sequence from LocalPrepare) Transaction is NOT ready + // for Prepare({}, {}) Local Stage: {}", tx_rec.transaction_id(), + // tx_rec.current_decision(), + // tx_rec.current_stage() + // ); + // } + // } else if tx_rec.current_stage().is_local_prepared() && + // tx_rec.evidence().all_input_addresses_justified() + // { + // // If all shards are complete, and we've already received our LocalPrepared, we can set out + // // LocalPrepared transaction as ready to propose ACCEPT. If we have not received + // // the local LocalPrepared, the transition will happen when we receive the local + // // block. + // info!( + // target: LOG_TARGET, + // "🧩 FOREIGN PROPOSAL: Transaction is ready for propose AllPrepared({}, {}) Local Stage: + // {}", tx_rec.transaction_id(), + // tx_rec.current_decision(), + // tx_rec.current_stage() + // ); + // + // tx_rec.add_pending_status_update(tx, local_leaf, TransactionPoolStage::LocalPrepared, true)?; + // // TODO: there is a race condition between the local node receiving the foreign LocalPrepare + // and // the leader proposing AllPrepare. If the latter comes first, this node + // // will not vote on this block which leads inevitably to erroneous + // // leader failures. Currently we simply vote ACCEPT on the block, with is ready == false, so + // we // need to handle this here. When we confirm foreign proposals correctly, we can + // remove this. } else { + // info!( + // target: LOG_TARGET, + // "🧩 FOREIGN PROPOSAL: Transaction is NOT ready for AllPrepared({}, {}) Local Stage: {}, + // All Justified: {}. Waiting for local proposal.", tx_rec.transaction_id(), + // tx_rec.current_decision(), + // tx_rec.current_stage(), + // tx_rec.evidence().all_input_addresses_justified() + // ); + // tx_rec.add_pending_status_update(tx, local_leaf, tx_rec.current_stage(), tx_rec.is_ready())?; + // } + // }, + // Command::LocalAccept(atom) => { + // if !local_committee_info.includes_any_address(atom.evidence.substate_addresses_iter()) { + // continue; + // } + // + // debug!( + // target: LOG_TARGET, + // "🧩 FOREIGN PROPOSAL: Command: LocalAccept({}, {}), block: {}", + // atom.id, atom.decision, block.id(), + // ); + // + // let Some(mut tx_rec) = self.transaction_pool.get(tx, local_leaf, &atom.id).optional()? else { + // warn!( + // target: LOG_TARGET, + // "⚠️ NEVER HAPPEN: Foreign proposal received for transaction {} but this transaction is + // not in the pool.", atom.id + // ); + // continue; + // }; + // + // if tx_rec.current_stage() > TransactionPoolStage::LocalAccepted { + // warn!( + // target: LOG_TARGET, + // "⚠️ Foreign proposal {} received LOCAL_ACCEPT for transaction {} but current transaction + // stage is {}. Ignoring.", block, + // tx_rec.transaction_id(), + // tx_rec.current_stage(), + // ); + // continue; + // } + // + // command_count += 1; + // + // let remote_decision = atom.decision; + // let local_decision = tx_rec.current_local_decision(); + // if remote_decision.is_abort() && local_decision.is_commit() { + // info!( + // target: LOG_TARGET, + // "⚠️ Foreign ABORT {}. Update overall decision to ABORT. Local stage: {}, Leaf: {}", + // tx_rec.transaction_id(), tx_rec.current_stage(), local_leaf + // ); + // } + // + // // We need to add the justify QC to the evidence because the all prepare block could not include + // it // yet + // let mut foreign_evidence = atom.evidence.clone(); + // foreign_evidence.add_qc_evidence(foreign_committee_info, *justify_qc.id()); + // + // // Update the transaction record with any new information provided by this foreign block + // tx_rec.update_remote_data( + // tx, + // remote_decision, + // *justify_qc.id(), + // foreign_committee_info, + // foreign_evidence, + // )?; + // + // self.validate_and_add_pledges( + // tx, + // &tx_rec, + // block.id(), + // atom, + // &mut block_pledge, + // foreign_committee_info, + // )?; + // + // // Good debug info + // // tx_rec.evidence().iter().for_each(|(addr, ev)| { + // // let includes_local = local_committee_info.includes_substate_address(addr); + // // log::error!( + // // target: LOG_TARGET, + // // "🐞 LOCALACCEPT EVIDENCE (l={}, f={}) {}: {}", includes_local, !includes_local, addr, + // ev // ); + // // }); + // + // if tx_rec.current_stage().is_new() { + // // If the transaction is New, we're waiting for all foreign pledges. Propose transaction once + // we // have them. + // // CASE: Foreign SGs have pledged all inputs and executed the transaction, local SG is + // involved // in the outputs + // let transaction = tx_rec.get_transaction(&**tx)?; + // let is_ready = local_committee_info.includes_substate_id(&transaction.to_receipt_id().into()) + // || transaction.has_any_local_inputs(local_committee_info) || + // transaction.has_all_foreign_input_pledges(&**tx, local_committee_info)?; + // if is_ready { + // info!( + // target: LOG_TARGET, + // "🧩 FOREIGN PROPOSAL: (Initial sequence from LocalAccept) Transaction is ready for + // Prepare({}, {}) Local Stage: {}", tx_rec.transaction_id(), + // tx_rec.current_decision(), + // tx_rec.current_stage() + // ); + // tx_rec.add_pending_status_update(tx, local_leaf, TransactionPoolStage::New, true)?; + // } else { + // info!( + // target: LOG_TARGET, + // "🧩 FOREIGN PROPOSAL: (Initial sequence from LocalAccept) Transaction is NOT ready + // for Prepare({}, {}) Local Stage: {}", tx_rec.transaction_id(), + // tx_rec.current_decision(), + // tx_rec.current_stage() + // ); + // } + // } else if tx_rec.current_stage().is_local_accepted() && + // tx_rec.evidence().all_addresses_justified() { + // info!( + // target: LOG_TARGET, + // "🧩 FOREIGN PROPOSAL: Transaction is ready for propose ALL_ACCEPT({}, {}) Local Stage: + // {}", tx_rec.transaction_id(), + // tx_rec.current_decision(), + // tx_rec.current_stage() + // ); + // + // tx_rec.add_pending_status_update(tx, local_leaf, TransactionPoolStage::LocalAccepted, true)?; + // } else { + // info!( + // target: LOG_TARGET, + // "🧩 FOREIGN PROPOSAL: Transaction is NOT ready for ALL_ACCEPT({}, {}) Local Stage: {}, + // All Justified: {}. Waiting for local proposal.", tx_rec.transaction_id(), + // tx_rec.current_decision(), + // tx_rec.current_stage(), + // tx_rec.evidence().all_addresses_justified() + // ); + // // Still need to update the evidence + // tx_rec.add_pending_status_update(tx, local_leaf, tx_rec.current_stage(), tx_rec.is_ready())?; + // } + // }, + // // Should never receive this + // Command::EndEpoch => { + // warn!( + // target: LOG_TARGET, + // "❓️ NEVER HAPPEN: Foreign proposal received for block {} contains an EndEpoch command. This + // is invalid behaviour.", block.id() + // ); + // continue; + // }, + // // TODO(perf): Can we find a way to exclude these unused commands to reduce message size? + // Command::AllAccept(_) | + // Command::SomeAccept(_) | + // Command::AllPrepare(_) | + // Command::SomePrepare(_) | + // Command::Prepare(_) | + // Command::LocalOnly(_) | + // Command::ForeignProposal(_) | + // Command::MintConfidentialOutput(_) => { + // // Disregard + // continue; + // }, + // } + // } + // + // info!( + // target: LOG_TARGET, + // "🧩 FOREIGN PROPOSAL: Processed {} commands from foreign block {}", + // command_count, + // block.id() + // ); + // if command_count == 0 { + // warn!( + // target: LOG_TARGET, + // "⚠️ FOREIGN PROPOSAL: No commands were applicable for foreign block {}. Ignoring.", + // block.id() + // ); + // } + // + // Ok(()) + // } + // + // fn validate_and_add_pledges( + // &self, + // tx: &mut ::WriteTransaction<'_>, + // tx_rec: &TransactionPoolRecord, + // block_id: &BlockId, + // atom: &TransactionAtom, + // block_pledge: &mut BlockPledge, + // foreign_committee_info: &CommitteeInfo, + // ) -> Result<(), HotStuffError> { + // #[allow(clippy::mutable_key_type)] + // let maybe_pledges = if atom.decision.is_commit() { + // let pledges = block_pledge.remove_transaction_pledges(&atom.id).ok_or_else(|| { + // HotStuffError::ForeignNodeOmittedTransactionPledges { + // foreign_block_id: *block_id, + // transaction_id: atom.id, + // } + // })?; + // + // // Validate that provided evidence is correct + // // TODO: there are a lot of validations to be done on evidence and the foreign block in general, + // // this is here as a sanity check and should change to not be a fatal error in consensus + // for pledge in &pledges { + // let address = pledge.versioned_substate_id().to_substate_address(); + // let evidence = + // atom.evidence + // .get(&address) + // .ok_or_else(|| ProposalValidationError::ForeignInvalidPledge { + // block_id: *block_id, + // transaction_id: atom.id, + // details: format!("Pledge {pledge} for address {address} not found in evidence"), + // })?; + // if evidence.lock.is_output() && pledge.is_input() { + // return Err(ProposalValidationError::ForeignInvalidPledge { + // block_id: *block_id, + // transaction_id: atom.id, + // details: format!("Pledge {pledge} is an input but evidence is an output for address + // {address}"), } + // .into()); + // } + // if !evidence.lock.is_output() && pledge.is_output() { + // return Err(ProposalValidationError::ForeignInvalidPledge { + // block_id: *block_id, + // transaction_id: atom.id, + // details: format!("Pledge {pledge} is an output but evidence is an input for address + // {address}"), } + // .into()); + // } + // } + // Some(pledges) + // } else { + // if block_pledge.remove_transaction_pledges(&atom.id).is_some() { + // return Err(ProposalValidationError::ForeignInvalidPledge { + // block_id: *block_id, + // transaction_id: atom.id, + // details: "Remote decided ABORT but provided pledges".to_string(), + // } + // .into()); + // } + // None + // }; + // + // if let Some(pledges) = maybe_pledges { + // // If the foreign shard has committed the transaction, we can add the pledges to the transaction + // // record + // tx_rec.add_foreign_pledges(tx, foreign_committee_info.shard_group(), pledges)?; + // } + // + // Ok(()) + // } fn validate_proposed_block( &self, diff --git a/dan_layer/consensus/src/hotstuff/on_receive_local_proposal.rs b/dan_layer/consensus/src/hotstuff/on_receive_local_proposal.rs index 504c4ab00..d3c6e4159 100644 --- a/dan_layer/consensus/src/hotstuff/on_receive_local_proposal.rs +++ b/dan_layer/consensus/src/hotstuff/on_receive_local_proposal.rs @@ -1,7 +1,7 @@ // Copyright 2023 The Tari Project // SPDX-License-Identifier: BSD-3-Clause -use std::collections::HashSet; +use std::collections::{HashMap, HashSet}; use log::*; use tari_dan_common_types::{ @@ -11,7 +11,16 @@ use tari_dan_common_types::{ NodeHeight, }; use tari_dan_storage::{ - consensus_models::{Block, HighQc, LastSentVote, QuorumCertificate, QuorumDecision, TransactionPool, ValidBlock}, + consensus_models::{ + Block, + BlockId, + HighQc, + LastSentVote, + QuorumCertificate, + QuorumDecision, + TransactionPool, + ValidBlock, + }, StateStore, }; use tari_epoch_manager::EpochManagerReader; @@ -23,13 +32,14 @@ use crate::{ create_epoch_checkpoint, error::HotStuffError, on_ready_to_vote_on_local_block::OnReadyToVoteOnLocalBlock, + on_receive_foreign_proposal::OnReceiveForeignProposalHandler, pacemaker_handle::PaceMakerHandle, transaction_manager::ConsensusTransactionManager, HotstuffConfig, HotstuffEvent, ProposalValidationError, }, - messages::{ForeignProposalMessage, HotstuffMessage, VoteMessage}, + messages::{ForeignProposalMessage, HotstuffMessage, ProposalMessage, VoteMessage}, traits::{ hooks::ConsensusHooks, ConsensusSpec, @@ -51,6 +61,7 @@ pub struct OnReceiveLocalProposalHandler { on_ready_to_vote_on_local_block: OnReadyToVoteOnLocalBlock, outbound_messaging: TConsensusSpec::OutboundMessaging, vote_signing_service: TConsensusSpec::SignatureService, + on_receive_foreign_proposal: OnReceiveForeignProposalHandler, hooks: TConsensusSpec::Hooks, } @@ -76,12 +87,13 @@ impl OnReceiveLocalProposalHandler OnReceiveLocalProposalHandler Result<(), HotStuffError> { + pub async fn handle( + &mut self, + current_epoch: Epoch, + local_committee_info: &CommitteeInfo, + msg: ProposalMessage, + ) -> Result<(), HotStuffError> { debug!( target: LOG_TARGET, "🔥 LOCAL PROPOSAL: block {} from {}", - block, - block.proposed_by() + msg.block, + msg.block.proposed_by() ); + // First validate and save the attached foreign proposals + let mut foreign_committees = HashMap::with_capacity(msg.foreign_proposals.len()); + for foreign_proposal in msg.foreign_proposals { + let block_id = *foreign_proposal.block.id(); + let foreign_committee_info = self + .epoch_manager + .get_committee_info_by_validator_public_key( + foreign_proposal.block.epoch(), + foreign_proposal.block.proposed_by(), + ) + .await?; + + self.on_receive_foreign_proposal.validate_and_save( + foreign_proposal.into(), + local_committee_info, + &foreign_committee_info, + )?; + foreign_committees.insert(block_id, foreign_committee_info); + } - match self.process_block(current_epoch, block).await { + match self + .process_block(current_epoch, local_committee_info, msg.block, foreign_committees) + .await + { Ok(()) => Ok(()), Err(err @ HotStuffError::ProposalValidationError(_)) => { self.hooks.on_block_validation_failed(&err); @@ -112,7 +151,13 @@ impl OnReceiveLocalProposalHandler Result<(), HotStuffError> { + async fn process_block( + &mut self, + current_epoch: Epoch, + local_committee_info: &CommitteeInfo, + block: Block, + foreign_committees: HashMap, + ) -> Result<(), HotStuffError> { if !self.epoch_manager.is_epoch_active(block.epoch()).await? { return Err(HotStuffError::EpochNotActive { epoch: block.epoch(), @@ -124,10 +169,6 @@ impl OnReceiveLocalProposalHandler OnReceiveLocalProposalHandler OnReceiveLocalProposalHandler current_epoch; let mut on_ready_to_vote_on_local_block = self.on_ready_to_vote_on_local_block.clone(); - let (block_decision, valid_block) = task::spawn_blocking(move || { - let decision = on_ready_to_vote_on_local_block.handle( - &valid_block, - &local_committee_info, - can_propose_epoch_end, - )?; - Ok::<_, HotStuffError>((decision, valid_block)) + let (block_decision, valid_block) = task::spawn_blocking({ + // Move into task + let local_committee_info = *local_committee_info; + move || { + let decision = on_ready_to_vote_on_local_block.handle( + &valid_block, + &local_committee_info, + can_propose_epoch_end, + foreign_committees, + )?; + Ok::<_, HotStuffError>((decision, valid_block)) + } }) .await??; diff --git a/dan_layer/consensus/src/hotstuff/worker.rs b/dan_layer/consensus/src/hotstuff/worker.rs index c95dfe199..e7e8ab8ce 100644 --- a/dan_layer/consensus/src/hotstuff/worker.rs +++ b/dan_layer/consensus/src/hotstuff/worker.rs @@ -6,7 +6,7 @@ use std::fmt::{Debug, Formatter}; use log::*; use tari_dan_common_types::{committee::CommitteeInfo, Epoch, NodeHeight, ShardGroup}; use tari_dan_storage::{ - consensus_models::{Block, BlockDiff, BurntUtxo, HighQc, LeafBlock, TransactionPool}, + consensus_models::{Block, BlockDiff, BurntUtxo, ForeignProposal, HighQc, LeafBlock, TransactionPool}, StateStore, }; use tari_epoch_manager::{EpochManagerEvent, EpochManagerReader}; @@ -142,7 +142,6 @@ impl HotstuffWorker { on_receive_foreign_proposal: OnReceiveForeignProposalHandler::new( state_store.clone(), epoch_manager.clone(), - transaction_pool.clone(), pacemaker.clone_handle(), ), on_receive_vote: OnReceiveVoteHandler::new(vote_receiver.clone()), @@ -584,10 +583,13 @@ impl HotstuffWorker { async fn on_beat(&mut self, epoch: Epoch, local_committee_info: &CommitteeInfo) -> Result<(), HotStuffError> { self.hooks.on_beat(); + let (base_layer_block_height, _) = self.epoch_manager.current_base_layer_block_info().await?; if !self.state_store.with_read_tx(|tx| { // Propose quickly if there are UTXOs to mint or transactions to propose Ok::<_, HotStuffError>( - BurntUtxo::has_unproposed(tx)? || self.transaction_pool.has_uncommitted_transactions(tx)?, + ForeignProposal::has_unconfirmed(tx, base_layer_block_height)? || + BurntUtxo::has_unproposed(tx)? || + self.transaction_pool.has_uncommitted_transactions(tx)?, ) })? { let current_epoch = self.epoch_manager.current_epoch().await?; @@ -673,19 +675,11 @@ impl HotstuffWorker { .await, ), HotstuffMessage::Proposal(msg) => { - // First process attached foreign proposals - for foreign_proposal in msg.foreign_proposals { - log_err( - "on_receive_foreign_proposal", - self.on_receive_foreign_proposal - .handle(from.clone(), foreign_proposal.into(), local_committee_info) - .await, - )?; - } - match log_err( "on_receive_local_proposal", - self.on_receive_local_proposal.handle(current_epoch, msg.block).await, + self.on_receive_local_proposal + .handle(current_epoch, local_committee_info, msg) + .await, ) { Ok(_) => Ok(()), Err( @@ -705,9 +699,7 @@ impl HotstuffWorker { }, HotstuffMessage::ForeignProposal(msg) => log_err( "on_receive_foreign_proposal", - self.on_receive_foreign_proposal - .handle(from, msg, local_committee_info) - .await, + self.on_receive_foreign_proposal.handle(msg, local_committee_info).await, ), HotstuffMessage::Vote(msg) => log_err( "on_receive_vote", diff --git a/dan_layer/consensus_tests/src/consensus.rs b/dan_layer/consensus_tests/src/consensus.rs index ff909255a..af1407220 100644 --- a/dan_layer/consensus_tests/src/consensus.rs +++ b/dan_layer/consensus_tests/src/consensus.rs @@ -437,8 +437,6 @@ async fn multishard_local_inputs_foreign_outputs() { async fn multishard_local_inputs_and_outputs_foreign_outputs() { setup_logger(); let mut test = Test::builder() - // TODO: investigate - .with_test_timeout(Duration::from_secs(60)) .add_committee(0, vec!["1", "2"]) .add_committee(1, vec!["3", "4"]) .add_committee(2, vec!["5", "6"]) diff --git a/dan_layer/state_store_sqlite/migrations/2023-06-08-091819_create_state_store/up.sql b/dan_layer/state_store_sqlite/migrations/2023-06-08-091819_create_state_store/up.sql index c059ecf19..a316065c6 100644 --- a/dan_layer/state_store_sqlite/migrations/2023-06-08-091819_create_state_store/up.sql +++ b/dan_layer/state_store_sqlite/migrations/2023-06-08-091819_create_state_store/up.sql @@ -1,10 +1,11 @@ create table quorum_certificates ( - id integer not null primary key AUTOINCREMENT, - qc_id text not NULL, - block_id text not NULL, - json text not NULL, - created_at timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP + id integer not null primary key AUTOINCREMENT, + qc_id text not NULL, + block_id text not NULL, + shard_group integer not NULL, + json text not NULL, + created_at timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ); -- fetching by qc_id is a very common operation @@ -81,12 +82,12 @@ CREATE TABLE missing_transactions create table foreign_parked_blocks ( - id integer not null primary key AUTOINCREMENT, - block_id text not NULL, - block text not NULL, - block_pledges text not NULL, - justify_qc text not NULL, - created_at timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP + id integer not null primary key AUTOINCREMENT, + block_id text not NULL, + block text not NULL, + block_pledges text not NULL, + justify_qc text not NULL, + created_at timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ); -- block_id must be unique. Optimise fetching by block_id @@ -94,10 +95,10 @@ create unique index foreign_parked_blocks_uniq_idx_id on parked_blocks (block_id CREATE TABLE foreign_missing_transactions ( - id integer not NULL primary key AUTOINCREMENT, - parked_block_id integer not NULL, - transaction_id text not NULL, - created_at timestamp not NULL DEFAULT CURRENT_TIMESTAMP, + id integer not NULL primary key AUTOINCREMENT, + parked_block_id integer not NULL, + transaction_id text not NULL, + created_at timestamp not NULL DEFAULT CURRENT_TIMESTAMP, FOREIGN KEY (parked_block_id) REFERENCES foreign_parked_blocks (id) ); @@ -166,6 +167,7 @@ create table foreign_substate_pledges ( id integer NOT NULL primary key AUTOINCREMENT, transaction_id text NOT NULL, + address text NOT NULL, substate_id text NOT NULL, version int NOT NULL, substate_value text NULL, @@ -304,7 +306,6 @@ create table transaction_pool local_decision text null, remote_decision text null, evidence text null, - remote_evidence text null, transaction_fee bigint null, leader_fee bigint null, global_exhaust_burn bigint null, @@ -321,19 +322,22 @@ create index transaction_pool_idx_is_ready on transaction_pool (is_ready); create table transaction_pool_state_updates ( - id integer not null primary key AUTOINCREMENT, - block_id text not null, - block_height bigint not null, - transaction_id text not null, - stage text not null, - evidence text not null, - is_ready boolean not null, - local_decision text not null, - created_at timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, + id integer not null primary key AUTOINCREMENT, + block_id text not null, + block_height bigint not null, + transaction_id text not null, + stage text not null, + evidence text not null, + is_ready boolean not null, + local_decision text not null, + remote_decision text null, + is_applied boolean not null DEFAULT '0', + created_at timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, FOREIGN KEY (block_id) REFERENCES blocks (block_id), FOREIGN KEY (transaction_id) REFERENCES transactions (transaction_id) ); -create unique index transaction_pool_uniq_block_id_transaction_id on transaction_pool_state_updates (block_id, transaction_id); +create unique index transaction_pool_state_updates_uniq_block_id_transaction_id on transaction_pool_state_updates (block_id, transaction_id); +create index transaction_pool_state_updates_idx_is_applied on transaction_pool_state_updates (is_applied); create table votes ( @@ -349,29 +353,30 @@ create table votes CREATE TABLE foreign_proposals ( - id integer not null primary key AUTOINCREMENT, - block_id text not NULL, - parent_block_id text not NULL, - merkle_root text not NULL, - network text not NULL, - height bigint not NULL, - epoch bigint not NULL, - shard_group integer not NULL, - proposed_by text not NULL, - qc text not NULL, - command_count bigint not NULL, - commands text not NULL, - total_leader_fee bigint not NULL, - foreign_indexes text not NULL, - signature text NULL, - timestamp bigint not NULL, - base_layer_block_height bigint not NULL, - base_layer_block_hash text not NULL, - justify_qc_id text not NULL REFERENCES quorum_certificates (qc_id), - block_pledge text not NULL, - proposed_in_block text NULL REFERENCES blocks (block_id), - proposed_in_block_height bigint NULL, - created_at timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, + id integer not null primary key AUTOINCREMENT, + block_id text not NULL, + parent_block_id text not NULL, + merkle_root text not NULL, + network text not NULL, + height bigint not NULL, + epoch bigint not NULL, + shard_group integer not NULL, + proposed_by text not NULL, + qc text not NULL, + command_count bigint not NULL, + commands text not NULL, + total_leader_fee bigint not NULL, + foreign_indexes text not NULL, + signature text NULL, + timestamp bigint not NULL, + base_layer_block_height bigint not NULL, + base_layer_block_hash text not NULL, + justify_qc_id text not NULL REFERENCES quorum_certificates (qc_id), + block_pledge text not NULL, + proposed_in_block text NULL REFERENCES blocks (block_id), + proposed_in_block_height bigint NULL, + status text not NULL, + created_at timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, UNIQUE (block_id) ); @@ -392,12 +397,12 @@ CREATE TABLE foreign_receive_counters CREATE TABLE burnt_utxos ( - id integer not null primary key AUTOINCREMENT, - substate_id text not NULL, - substate text not NULL, - base_layer_block_height bigint not NULL, - proposed_in_block text NULL REFERENCES blocks (block_id), - proposed_in_block_height bigint NULL, + id integer not null primary key AUTOINCREMENT, + substate_id text not NULL, + substate text not NULL, + base_layer_block_height bigint not NULL, + proposed_in_block text NULL REFERENCES blocks (block_id), + proposed_in_block_height bigint NULL, created_at timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, UNIQUE (substate_id) ); @@ -445,12 +450,12 @@ CREATE UNIQUE INDEX pending_state_tree_diffs_uniq_idx_block_id_shard on pending_ CREATE TABLE epoch_checkpoints ( - id integer not NULL primary key AUTOINCREMENT, - epoch bigint not NULL, - commit_block text not NULL, - qcs text not NULL, - shard_roots text not NULL, - created_at timestamp not NULL DEFAULT CURRENT_TIMESTAMP + id integer not NULL primary key AUTOINCREMENT, + epoch bigint not NULL, + commit_block text not NULL, + qcs text not NULL, + shard_roots text not NULL, + created_at timestamp not NULL DEFAULT CURRENT_TIMESTAMP ); -- An append-only store of state transitions @@ -491,6 +496,8 @@ CREATE TABLE transaction_pool_history global_exhaust_burn bigint null, stage text not null, new_stage text not null, + pending_stage text null, + new_pending_stage text null, is_ready boolean not null, new_is_ready boolean not null, confirm_stage text null, @@ -517,6 +524,8 @@ BEGIN global_exhaust_burn, stage, new_stage, + pending_stage, + new_pending_stage, is_ready, new_is_ready, confirm_stage, @@ -535,6 +544,8 @@ BEGIN OLD.global_exhaust_burn, OLD.stage, NEW.stage, + OLD.pending_stage, + NEW.pending_stage, OLD.is_ready, NEW.is_ready, OLD.confirm_stage, diff --git a/dan_layer/state_store_sqlite/src/reader.rs b/dan_layer/state_store_sqlite/src/reader.rs index 31c2259b5..43bc607fa 100644 --- a/dan_layer/state_store_sqlite/src/reader.rs +++ b/dan_layer/state_store_sqlite/src/reader.rs @@ -51,6 +51,7 @@ use tari_dan_storage::{ EpochCheckpoint, ForeignProposal, ForeignProposalAtom, + ForeignProposalStatus, ForeignReceiveCounters, ForeignSendCounters, HighQc, @@ -123,7 +124,7 @@ impl<'a, TAddr> SqliteStateStoreReadTransaction<'a, TAddr> { } impl<'a, TAddr: NodeAddressable + Serialize + DeserializeOwned + 'a> SqliteStateStoreReadTransaction<'a, TAddr> { - pub fn get_transaction_atom_state_updates_between_blocks<'i, ITx>( + pub(crate) fn get_transaction_atom_state_updates_between_blocks<'i, ITx>( &self, from_block_id: &BlockId, to_block_id: &BlockId, @@ -136,7 +137,9 @@ impl<'a, TAddr: NodeAddressable + Serialize + DeserializeOwned + 'a> SqliteState return Ok(IndexMap::new()); } - let applicable_block_ids = self.get_block_ids_with_commands_between(from_block_id, to_block_id)?; + // Blocks without commands may change pending transaction state because they justify a + // block that proposes a change. So we cannot only use blocks that have commands. + let applicable_block_ids = self.get_block_ids_between(from_block_id, to_block_id)?; debug!( target: LOG_TARGET, @@ -164,6 +167,7 @@ impl<'a, TAddr: NodeAddressable + Serialize + DeserializeOwned + 'a> SqliteState } /// Creates a query to select the latest transaction pool state updates for the given transaction ids and block ids. + /// If no transaction ids are provided, all updates for the given block ids are returned. /// WARNING: This method does not protect against SQL-injection, Be sure that the transaction ids and block ids /// strings are what they are meant to be. fn create_transaction_atom_updates_query< @@ -176,6 +180,15 @@ impl<'a, TAddr: NodeAddressable + Serialize + DeserializeOwned + 'a> SqliteState transaction_ids: ITx, block_ids: IBlk, ) -> SqlQuery { + // Query all updates if the transaction_ids are empty + let in_transactions = if transaction_ids.len() == 0 { + String::new() + } else { + format!( + "AND tpsu.transaction_id in ({})", + self.sql_frag_for_in_statement(transaction_ids, TransactionId::byte_size() * 2) + ) + }; // Unfortunate hack. Binding array types in diesel is only supported for postgres. sql_query(format!( r#" @@ -186,8 +199,9 @@ impl<'a, TAddr: NodeAddressable + Serialize + DeserializeOwned + 'a> SqliteState FROM transaction_pool_state_updates AS tpsu WHERE + is_applied = 0 AND tpsu.block_id in ({}) - AND tpsu.transaction_id in ({}) + {} ) SELECT id, @@ -198,6 +212,8 @@ impl<'a, TAddr: NodeAddressable + Serialize + DeserializeOwned + 'a> SqliteState evidence, is_ready, local_decision, + remote_decision, + is_applied, created_at FROM RankedResults @@ -205,7 +221,7 @@ impl<'a, TAddr: NodeAddressable + Serialize + DeserializeOwned + 'a> SqliteState rank = 1; "#, self.sql_frag_for_in_statement(block_ids, BlockId::byte_size() * 2), - self.sql_frag_for_in_statement(transaction_ids, TransactionId::byte_size() * 2), + in_transactions )) } @@ -524,6 +540,23 @@ impl<'tx, TAddr: NodeAddressable + Serialize + DeserializeOwned + 'tx> StateStor Ok(foreign_proposals > 0) } + fn foreign_proposals_has_unconfirmed(&self, max_base_layer_block_height: u64) -> Result { + use crate::schema::foreign_proposals; + + let foreign_proposals = foreign_proposals::table + .filter(foreign_proposals::base_layer_block_height.le(max_base_layer_block_height as i64)) + .filter(foreign_proposals::status.ne(ForeignProposalStatus::Confirmed.to_string())) + .count() + .limit(1) + .get_result::(self.connection()) + .map_err(|e| SqliteStorageError::DieselError { + operation: "foreign_proposals_has_unproposed", + source: e, + })?; + + Ok(foreign_proposals > 0) + } + fn foreign_proposals_get_all_new( &self, max_base_layer_block_height: u64, @@ -539,6 +572,9 @@ impl<'tx, TAddr: NodeAddressable + Serialize + DeserializeOwned + 'tx> StateStor .left_join(quorum_certificates::table.on(foreign_proposals::justify_qc_id.eq(quorum_certificates::qc_id))) // Only propose the Foreign proposal if we have reached the base layer block height specified in the block .filter(foreign_proposals::base_layer_block_height.le(max_base_layer_block_height as i64)) + .filter( + foreign_proposals::status.ne(ForeignProposalStatus::Confirmed.to_string()) + ) .filter( foreign_proposals::proposed_in_block.is_null() .or(foreign_proposals::proposed_in_block.ne_all(pending_block_ids) @@ -1406,7 +1442,7 @@ impl<'tx, TAddr: NodeAddressable + Serialize + DeserializeOwned + 'tx> StateStor .filter(transaction_pool::transaction_id.eq(&transaction_id)) .first::(self.connection()) .map_err(|e| SqliteStorageError::DieselError { - operation: "transaction_pool_get", + operation: "transaction_pool_get_for_blocks", source: e, })?; @@ -1421,7 +1457,7 @@ impl<'tx, TAddr: NodeAddressable + Serialize + DeserializeOwned + 'tx> StateStor .filter(transaction_pool::transaction_id.eq(serialize_hex(transaction_id))) .first::(self.connection()) .map_err(|e| SqliteStorageError::DieselError { - operation: "transaction_pool_get", + operation: "transaction_pool_exists", source: e, })?; @@ -1468,7 +1504,7 @@ impl<'tx, TAddr: NodeAddressable + Serialize + DeserializeOwned + 'tx> StateStor debug!( target: LOG_TARGET, - "transaction_pool_get: from_block_id={}, to_block_id={}, len(ready_txs)={}, updates={}", + "transaction_pool_get_many_ready: locked.block_id={}, leaf.block_id={}, len(ready_txs)={}, updates={}", locked.block_id, leaf.block_id, ready_txs.len(), @@ -2150,6 +2186,28 @@ impl<'tx, TAddr: NodeAddressable + Serialize + DeserializeOwned + 'tx> StateStor checkpoint.try_into() } + fn foreign_substate_pledges_exists_for_address( + &self, + transaction_id: &TransactionId, + address: T, + ) -> Result { + use crate::schema::foreign_substate_pledges; + + let address = address.to_substate_address(); + let count = foreign_substate_pledges::table + .count() + .filter(foreign_substate_pledges::transaction_id.eq(serialize_hex(transaction_id))) + .filter(foreign_substate_pledges::address.eq(serialize_hex(address))) + .limit(1) + .get_result::(self.connection()) + .map_err(|e| SqliteStorageError::DieselError { + operation: "foreign_substate_pledges_exists", + source: e, + })?; + + Ok(count > 0) + } + fn foreign_substate_pledges_get_all_by_transaction_id( &self, transaction_id: &TransactionId, diff --git a/dan_layer/state_store_sqlite/src/schema.rs b/dan_layer/state_store_sqlite/src/schema.rs index 1c3ace3fc..0c93c7306 100644 --- a/dan_layer/state_store_sqlite/src/schema.rs +++ b/dan_layer/state_store_sqlite/src/schema.rs @@ -109,6 +109,7 @@ diesel::table! { block_pledge -> Text, proposed_in_block -> Nullable, proposed_in_block_height -> Nullable, + status -> Text, created_at -> Timestamp, } } @@ -134,6 +135,7 @@ diesel::table! { foreign_substate_pledges (id) { id -> Integer, transaction_id -> Text, + address -> Text, substate_id -> Text, version -> Integer, substate_value -> Nullable, @@ -269,6 +271,7 @@ diesel::table! { id -> Integer, qc_id -> Text, block_id -> Text, + shard_group -> Integer, json -> Text, created_at -> Timestamp, } @@ -368,7 +371,6 @@ diesel::table! { local_decision -> Nullable, remote_decision -> Nullable, evidence -> Nullable, - remote_evidence -> Nullable, transaction_fee -> Nullable, leader_fee -> Nullable, global_exhaust_burn -> Nullable, @@ -396,6 +398,8 @@ diesel::table! { global_exhaust_burn -> Nullable, stage -> Text, new_stage -> Text, + pending_stage -> Nullable, + new_pending_stage -> Nullable, is_ready -> Bool, new_is_ready -> Bool, confirm_stage -> Nullable, @@ -416,6 +420,8 @@ diesel::table! { evidence -> Text, is_ready -> Bool, local_decision -> Text, + remote_decision -> Nullable, + is_applied -> Bool, created_at -> Timestamp, } } diff --git a/dan_layer/state_store_sqlite/src/sql_models/foreign_proposal.rs b/dan_layer/state_store_sqlite/src/sql_models/foreign_proposal.rs index 24d1f8ab7..13c4a0f3c 100644 --- a/dan_layer/state_store_sqlite/src/sql_models/foreign_proposal.rs +++ b/dan_layer/state_store_sqlite/src/sql_models/foreign_proposal.rs @@ -1,6 +1,8 @@ // Copyright 2024 The Tari Project // SPDX-License-Identifier: BSD-3-Clause +use std::str::FromStr; + use diesel::Queryable; use tari_common_types::types::PublicKey; use tari_dan_common_types::{Epoch, NodeHeight, ShardGroup}; @@ -37,6 +39,7 @@ pub struct ForeignProposal { pub block_pledge: String, pub proposed_in_block: Option, pub proposed_in_block_height: Option, + pub status: String, pub created_at: PrimitiveDateTime, } @@ -83,6 +86,8 @@ impl ForeignProposal { deserialize_hex_try_from(&self.base_layer_block_hash)?, ); + let status = consensus_models::ForeignProposalStatus::from_str(&self.status)?; + Ok(consensus_models::ForeignProposal { block, block_pledge: deserialize_json(&self.block_pledge)?, @@ -92,6 +97,7 @@ impl ForeignProposal { .as_deref() .map(deserialize_hex_try_from) .transpose()?, + status, }) } } diff --git a/dan_layer/state_store_sqlite/src/sql_models/foreign_substate_pledge.rs b/dan_layer/state_store_sqlite/src/sql_models/foreign_substate_pledge.rs index 78e36764a..f9f69bff3 100644 --- a/dan_layer/state_store_sqlite/src/sql_models/foreign_substate_pledge.rs +++ b/dan_layer/state_store_sqlite/src/sql_models/foreign_substate_pledge.rs @@ -8,6 +8,7 @@ use time::PrimitiveDateTime; pub struct ForeignSubstatePledge { pub id: i32, pub transaction_id: String, + pub address: String, pub substate_id: String, pub version: i32, pub substate_value: Option, diff --git a/dan_layer/state_store_sqlite/src/sql_models/quorum_certificate.rs b/dan_layer/state_store_sqlite/src/sql_models/quorum_certificate.rs index 7cd3ed085..1e165c78c 100644 --- a/dan_layer/state_store_sqlite/src/sql_models/quorum_certificate.rs +++ b/dan_layer/state_store_sqlite/src/sql_models/quorum_certificate.rs @@ -12,6 +12,7 @@ pub struct QuorumCertificate { pub id: i32, pub qc_id: String, pub block_id: String, + pub shard_group: i32, pub json: String, pub created_at: PrimitiveDateTime, } diff --git a/dan_layer/state_store_sqlite/src/sql_models/transaction_pool.rs b/dan_layer/state_store_sqlite/src/sql_models/transaction_pool.rs index 56ec782b2..a47afda4b 100644 --- a/dan_layer/state_store_sqlite/src/sql_models/transaction_pool.rs +++ b/dan_layer/state_store_sqlite/src/sql_models/transaction_pool.rs @@ -19,7 +19,6 @@ pub struct TransactionPoolRecord { pub local_decision: Option, pub remote_decision: Option, pub evidence: Option, - pub remote_evidence: Option, pub transaction_fee: Option, pub leader_fee: Option, pub global_exhaust_burn: Option, @@ -48,21 +47,17 @@ impl TransactionPoolRecord { let mut pending_stage = None; let mut local_decision = self.local_decision; let mut is_ready = self.is_ready; + let mut remote_decision = self.remote_decision; + if let Some(update) = update { evidence.merge(deserialize_json(&update.evidence)?); is_ready = update.is_ready; pending_stage = Some(parse_from_string(&update.stage)?); - local_decision = update.local_decision; + local_decision = Some(update.local_decision); + remote_decision = update.remote_decision; } - let remote_evidence = self - .remote_evidence - .as_deref() - .map(deserialize_json::) - .transpose()?; - if let Some(ref remote_evidence) = remote_evidence { - evidence.merge(remote_evidence.clone()); - } + let remote_decision = remote_decision.as_deref().map(parse_from_string).transpose()?; let leader_fee = self .leader_fee @@ -81,12 +76,10 @@ impl TransactionPoolRecord { }) .transpose()?; let original_decision = parse_from_string(&self.original_decision)?; - let remote_decision = self.remote_decision.as_deref().map(parse_from_string).transpose()?; Ok(consensus_models::TransactionPoolRecord::load( deserialize_hex_try_from(&self.transaction_id)?, evidence, - remote_evidence, self.transaction_fee.map(|f| f as u64), leader_fee, parse_from_string(&self.stage)?, @@ -116,8 +109,12 @@ pub struct TransactionPoolStateUpdate { pub evidence: String, #[diesel(sql_type = diesel::sql_types::Bool)] pub is_ready: bool, + #[diesel(sql_type = diesel::sql_types::Text)] + pub local_decision: String, #[diesel(sql_type = diesel::sql_types::Nullable < diesel::sql_types::Text >)] - pub local_decision: Option, + pub remote_decision: Option, + #[diesel(sql_type = diesel::sql_types::Bool)] + pub is_applied: bool, #[diesel(sql_type = diesel::sql_types::Timestamp)] pub created_at: PrimitiveDateTime, } diff --git a/dan_layer/state_store_sqlite/src/writer.rs b/dan_layer/state_store_sqlite/src/writer.rs index d461c79e5..0a044de5f 100644 --- a/dan_layer/state_store_sqlite/src/writer.rs +++ b/dan_layer/state_store_sqlite/src/writer.rs @@ -36,9 +36,9 @@ use tari_dan_storage::{ BurntUtxo, Decision, EpochCheckpoint, - Evidence, ForeignParkedProposal, ForeignProposal, + ForeignProposalStatus, ForeignReceiveCounters, ForeignSendCounters, HighQc, @@ -352,6 +352,7 @@ impl<'tx, TAddr: NodeAddressable + 'tx> StateStoreWriteTransaction for SqliteSta let insert = ( quorum_certificates::qc_id.eq(serialize_hex(qc.id())), + quorum_certificates::shard_group.eq(qc.shard_group().encode_as_u32() as i32), quorum_certificates::block_id.eq(serialize_hex(qc.block_id())), quorum_certificates::json.eq(serialize_json(qc)?), ); @@ -568,6 +569,7 @@ impl<'tx, TAddr: NodeAddressable + 'tx> StateStoreWriteTransaction for SqliteSta // Extra foreign_proposals::justify_qc_id.eq(serialize_hex(foreign_proposal.justify_qc().id())), foreign_proposals::block_pledge.eq(serialize_json(foreign_proposal.block_pledge())?), + foreign_proposals::status.eq(ForeignProposalStatus::New.to_string()), ); diesel::insert_into(foreign_proposals::table) @@ -600,6 +602,25 @@ impl<'tx, TAddr: NodeAddressable + 'tx> StateStoreWriteTransaction for SqliteSta Ok(()) } + fn foreign_proposals_set_status( + &mut self, + block_id: &BlockId, + status: ForeignProposalStatus, + ) -> Result<(), StorageError> { + use crate::schema::foreign_proposals; + + diesel::update(foreign_proposals::table) + .filter(foreign_proposals::block_id.eq(serialize_hex(block_id))) + .set(foreign_proposals::status.eq(status.to_string())) + .execute(self.connection()) + .map_err(|e| SqliteStorageError::DieselError { + operation: "foreign_proposals_set_status", + source: e, + })?; + + Ok(()) + } + fn foreign_proposals_set_proposed_in( &mut self, block_id: &BlockId, @@ -615,6 +636,7 @@ impl<'tx, TAddr: NodeAddressable + 'tx> StateStoreWriteTransaction for SqliteSta .select(blocks::height) .filter(blocks::block_id.eq(serialize_hex(proposed_in_block))) .single_value()), + foreign_proposals::status.eq(ForeignProposalStatus::Proposed.to_string()), )) .execute(self.connection()) .map_err(|e| SqliteStorageError::DieselError { @@ -908,23 +930,13 @@ impl<'tx, TAddr: NodeAddressable + 'tx> StateStoreWriteTransaction for SqliteSta fn transaction_pool_add_pending_update( &mut self, + block_id: &BlockId, update: &TransactionPoolStatusUpdate, ) -> Result<(), StorageError> { use crate::schema::{blocks, transaction_pool, transaction_pool_state_updates}; let transaction_id = serialize_hex(update.transaction_id()); - let block_id = serialize_hex(update.block_id()); - - // Check if update exists for block and transaction - let count = transaction_pool_state_updates::table - .count() - .filter(transaction_pool_state_updates::block_id.eq(&block_id)) - .filter(transaction_pool_state_updates::transaction_id.eq(&transaction_id)) - .first::(self.connection()) - .map_err(|e| SqliteStorageError::DieselError { - operation: "transaction_pool_add_pending_update", - source: e, - })?; + let block_id = serialize_hex(block_id); let values = ( transaction_pool_state_updates::block_id.eq(&block_id), @@ -936,29 +948,18 @@ impl<'tx, TAddr: NodeAddressable + 'tx> StateStoreWriteTransaction for SqliteSta transaction_pool_state_updates::transaction_id.eq(&transaction_id), transaction_pool_state_updates::evidence.eq(serialize_json(update.evidence())?), transaction_pool_state_updates::stage.eq(update.stage().to_string()), - transaction_pool_state_updates::local_decision.eq(update.local_decision().to_string()), + transaction_pool_state_updates::local_decision.eq(update.decision().to_string()), + transaction_pool_state_updates::remote_decision.eq(update.remote_decision().map(|d| d.to_string())), transaction_pool_state_updates::is_ready.eq(update.is_ready()), ); - if count == 0 { - diesel::insert_into(transaction_pool_state_updates::table) - .values(values) - .execute(self.connection()) - .map_err(|e| SqliteStorageError::DieselError { - operation: "transaction_pool_add_pending_update", - source: e, - })?; - } else { - diesel::update(transaction_pool_state_updates::table) - .filter(transaction_pool_state_updates::block_id.eq(&block_id)) - .filter(transaction_pool_state_updates::transaction_id.eq(&transaction_id)) - .set(values) - .execute(self.connection()) - .map_err(|e| SqliteStorageError::DieselError { - operation: "transaction_pool_add_pending_update", - source: e, - })?; - } + diesel::insert_into(transaction_pool_state_updates::table) + .values(values) + .execute(self.connection()) + .map_err(|e| SqliteStorageError::DieselError { + operation: "transaction_pool_add_pending_update", + source: e, + })?; // Set is_ready to the last value we set here. Bit of a hack to get has_uncommitted_transactions to return a // more accurate value without querying the updates table @@ -977,58 +978,6 @@ impl<'tx, TAddr: NodeAddressable + 'tx> StateStoreWriteTransaction for SqliteSta Ok(()) } - fn transaction_pool_update( - &mut self, - transaction_id: &TransactionId, - is_ready: Option, - local_decision: Option, - local_evidence: Option<&Evidence>, - remote_decision: Option, - remote_evidence: Option<&Evidence>, - ) -> Result<(), StorageError> { - use crate::schema::transaction_pool; - - let transaction_id = serialize_hex(transaction_id); - - #[derive(AsChangeset)] - #[diesel(table_name = transaction_pool)] - struct Changes { - is_ready: Option, - evidence: Option, - remote_evidence: Option, - local_decision: Option>, - remote_decision: Option>, - updated_at: PrimitiveDateTime, - } - - let change_set = Changes { - is_ready, - remote_evidence: remote_evidence.map(serialize_json).transpose()?, - evidence: local_evidence.map(serialize_json).transpose()?, - local_decision: local_decision.map(|d| d.to_string()).map(Some), - remote_decision: remote_decision.map(|d| d.to_string()).map(Some), - updated_at: now(), - }; - - let num_affected = diesel::update(transaction_pool::table) - .filter(transaction_pool::transaction_id.eq(&transaction_id)) - .set(change_set) - .execute(self.connection()) - .map_err(|e| SqliteStorageError::DieselError { - operation: "transaction_pool_set_remote_decision", - source: e, - })?; - - if num_affected == 0 { - return Err(StorageError::NotFound { - item: "transaction".to_string(), - key: transaction_id, - }); - } - - Ok(()) - } - fn transaction_pool_remove(&mut self, transaction_id: &TransactionId) -> Result<(), StorageError> { use crate::schema::{transaction_pool, transaction_pool_state_updates}; @@ -1099,50 +1048,30 @@ impl<'tx, TAddr: NodeAddressable + 'tx> StateStoreWriteTransaction for SqliteSta txs.into_iter().map(|tx| tx.try_convert(None)).collect() } - fn transaction_pool_confirm_all_transitions<'a, I: IntoIterator>( - &mut self, - locked_block: &LockedBlock, - new_locked_block: &LockedBlock, - tx_ids: I, - ) -> Result<(), StorageError> { + fn transaction_pool_confirm_all_transitions(&mut self, new_locked_block: &LockedBlock) -> Result<(), StorageError> { use crate::schema::{transaction_pool, transaction_pool_state_updates}; - let tx_ids = tx_ids.into_iter().map(serialize_hex).collect::>(); - - let count = transaction_pool::table - .count() - .filter(transaction_pool::transaction_id.eq_any(&tx_ids)) - .get_result::(self.connection()) + let updates = transaction_pool_state_updates::table + .filter(transaction_pool_state_updates::block_id.eq(serialize_hex(new_locked_block.block_id()))) + .filter(transaction_pool_state_updates::is_applied.eq(false)) + .get_results::(self.connection()) .map_err(|e| SqliteStorageError::DieselError { - operation: "transaction_pool_set_all_transitions", + operation: "transaction_pool_confirm_all_transitions", source: e, })?; - if count != tx_ids.len() as i64 { - return Err(SqliteStorageError::NotAllTransactionsFound { - operation: "transaction_pool_set_all_transitions", - details: format!("Found {} transactions, but {} were queried", count, tx_ids.len()), - } - .into()); - } - - let updates = self.get_transaction_atom_state_updates_between_blocks( - locked_block.block_id(), - new_locked_block.block_id(), - tx_ids.iter().map(|s| s.as_str()), - )?; - debug!( target: LOG_TARGET, - "transaction_pool_set_all_transitions: locked_block={}, new_locked_block={}, {} transactions, {} updates", locked_block, new_locked_block, tx_ids.len(), updates.len() + "transaction_pool_confirm_all_transitions: new_locked_block={}, {} updates", new_locked_block, updates.len() ); - diesel::delete(transaction_pool_state_updates::table) - .filter(transaction_pool_state_updates::transaction_id.eq_any(&tx_ids)) + diesel::update(transaction_pool_state_updates::table) + .filter(transaction_pool_state_updates::id.eq_any(updates.iter().map(|u| u.id))) .filter(transaction_pool_state_updates::block_height.le(new_locked_block.height().as_u64() as i64)) + .set(transaction_pool_state_updates::is_applied.eq(true)) .execute(self.connection()) .map_err(|e| SqliteStorageError::DieselError { - operation: "transaction_pool_set_all_transitions", + operation: "transaction_pool_confirm_all_transitions", source: e, })?; @@ -1154,10 +1083,11 @@ impl<'tx, TAddr: NodeAddressable + 'tx> StateStoreWriteTransaction for SqliteSta evidence: Option>, is_ready: Option, confirm_stage: Option>, + remote_decision: Option>, updated_at: Option, } - for update in updates.into_values() { + for update in updates { let confirm_stage = match update.stage.as_str() { "LocalPrepared" => Some(Some(TransactionPoolConfirmedStage::ConfirmedPrepared.to_string())), "LocalAccepted" => Some(Some(TransactionPoolConfirmedStage::ConfirmedAccepted.to_string())), @@ -1165,10 +1095,11 @@ impl<'tx, TAddr: NodeAddressable + 'tx> StateStoreWriteTransaction for SqliteSta }; let changeset = TransactionPoolChangeSet { stage: Some(update.stage), - local_decision: update.local_decision.map(|d| d.to_string()), + local_decision: Some(update.local_decision), evidence: Some(Some(update.evidence)), is_ready: Some(update.is_ready), confirm_stage, + remote_decision: Some(update.remote_decision), updated_at: Some(now()), }; @@ -1177,7 +1108,7 @@ impl<'tx, TAddr: NodeAddressable + 'tx> StateStoreWriteTransaction for SqliteSta .set(changeset) .execute(self.connection()) .map_err(|e| SqliteStorageError::DieselError { - operation: "transaction_pool_set_all_transitions", + operation: "transaction_pool_confirm_all_transitions", source: e, })?; } @@ -1628,6 +1559,7 @@ impl<'tx, TAddr: NodeAddressable + 'tx> StateStoreWriteTransaction for SqliteSta }; Ok::<_, StorageError>(( foreign_substate_pledges::transaction_id.eq(&tx_id_hex), + foreign_substate_pledges::address.eq(serialize_hex(substate_id.to_substate_address())), foreign_substate_pledges::substate_id.eq(substate_id.substate_id().to_string()), foreign_substate_pledges::version.eq(substate_id.version() as i32), foreign_substate_pledges::shard_group.eq(shard_group.encode_as_u32() as i32), @@ -1637,6 +1569,7 @@ impl<'tx, TAddr: NodeAddressable + 'tx> StateStoreWriteTransaction for SqliteSta }, SubstatePledge::Output { substate_id } => Ok::<_, StorageError>(( foreign_substate_pledges::transaction_id.eq(&tx_id_hex), + foreign_substate_pledges::address.eq(serialize_hex(substate_id.to_substate_address())), foreign_substate_pledges::substate_id.eq(substate_id.substate_id().to_string()), foreign_substate_pledges::version.eq(substate_id.version() as i32), foreign_substate_pledges::shard_group.eq(shard_group.encode_as_u32() as i32), diff --git a/dan_layer/state_store_sqlite/tests/tests.rs b/dan_layer/state_store_sqlite/tests/tests.rs index 8bbe02739..93ea0dda3 100644 --- a/dan_layer/state_store_sqlite/tests/tests.rs +++ b/dan_layer/state_store_sqlite/tests/tests.rs @@ -75,33 +75,35 @@ mod confirm_all_transitions { tx.transaction_pool_insert_new(atom3.id, atom3.decision, true).unwrap(); let block_id = *block1.id(); - tx.transaction_pool_add_pending_update(&TransactionPoolStatusUpdate { - block_id, - transaction_id: atom1.id, - stage: TransactionPoolStage::LocalPrepared, - evidence: Default::default(), - is_ready: false, - local_decision: Decision::Commit, - }) - .unwrap(); - tx.transaction_pool_add_pending_update(&TransactionPoolStatusUpdate { - block_id, - transaction_id: atom2.id, - stage: TransactionPoolStage::Prepared, - evidence: Default::default(), - is_ready: false, - local_decision: Decision::Commit, - }) - .unwrap(); - tx.transaction_pool_add_pending_update(&TransactionPoolStatusUpdate { - block_id, - transaction_id: atom3.id, - stage: TransactionPoolStage::Prepared, - evidence: Default::default(), - is_ready: false, - local_decision: Decision::Commit, - }) - .unwrap(); + let transactions = tx.transaction_pool_get_all().unwrap(); + let mut tx_1 = transactions + .iter() + .find(|tx| *tx.transaction_id() == atom1.id) + .unwrap() + .clone(); + let mut tx_2 = transactions + .iter() + .find(|tx| *tx.transaction_id() == atom2.id) + .unwrap() + .clone(); + let mut tx_3 = transactions + .iter() + .find(|tx| *tx.transaction_id() == atom3.id) + .unwrap() + .clone(); + + tx_1.set_next_stage(TransactionPoolStage::Prepared, true).unwrap(); + tx_1.set_next_stage(TransactionPoolStage::LocalPrepared, false).unwrap(); + + tx_2.set_next_stage(TransactionPoolStage::Prepared, true).unwrap(); + tx_3.set_next_stage(TransactionPoolStage::Prepared, true).unwrap(); + + tx.transaction_pool_add_pending_update(&block_id, &TransactionPoolStatusUpdate { transaction: tx_1 }) + .unwrap(); + tx.transaction_pool_add_pending_update(&block_id, &TransactionPoolStatusUpdate { transaction: tx_2 }) + .unwrap(); + tx.transaction_pool_add_pending_update(&block_id, &TransactionPoolStatusUpdate { transaction: tx_3 }) + .unwrap(); let rec = tx .transaction_pool_get_for_blocks(zero_block.id(), &block_id, &atom1.id) @@ -115,10 +117,8 @@ mod confirm_all_transitions { assert!(rec.committed_stage().is_new()); assert!(rec.pending_stage().unwrap().is_prepared()); - tx.transaction_pool_confirm_all_transitions(&zero_block.as_locked_block(), &block1.as_locked_block(), &[ - atom1.id, atom3.id, - ]) - .unwrap(); + tx.transaction_pool_confirm_all_transitions(&block1.as_locked_block()) + .unwrap(); let rec = tx .transaction_pool_get_for_blocks(zero_block.id(), &block_id, &atom1.id) @@ -129,14 +129,14 @@ mod confirm_all_transitions { let rec = tx .transaction_pool_get_for_blocks(zero_block.id(), &block_id, &atom2.id) .unwrap(); - assert!(rec.committed_stage().is_new()); - assert!(rec.pending_stage().unwrap().is_prepared()); + assert_eq!(rec.committed_stage(), TransactionPoolStage::Prepared); + assert_eq!(rec.pending_stage(), None); let rec = tx .transaction_pool_get_for_blocks(zero_block.id(), &block_id, &atom3.id) .unwrap(); - assert!(rec.committed_stage().is_prepared()); - assert!(rec.pending_stage().is_none()); + assert_eq!(rec.committed_stage(), TransactionPoolStage::Prepared); + assert_eq!(rec.pending_stage(), None); tx.rollback().unwrap(); } diff --git a/dan_layer/storage/src/consensus_models/block.rs b/dan_layer/storage/src/consensus_models/block.rs index f9424b0d1..19dd95e31 100644 --- a/dan_layer/storage/src/consensus_models/block.rs +++ b/dan_layer/storage/src/consensus_models/block.rs @@ -853,40 +853,46 @@ impl Block { { self.justify().update_high_qc(tx)?; - // b'' <- b*.justify.node i.e the newly justified block - let commit_node = self.justify().get_block(&**tx)?; + // b'' <- b*.justify.node i.e. the (possibly new) justified block + let justified_node = self.justify().get_block(&**tx)?; // b' <- b''.justify.node - let precommit_node = commit_node.justify().get_block(&**tx)?; + let prepared_node = justified_node.justify().get_block(&**tx)?; - if precommit_node.is_genesis() { - return Ok(commit_node); + if prepared_node.is_genesis() { + return Ok(justified_node); } - let locked = LockedBlock::get(&**tx)?; - if precommit_node.height() > locked.height { - on_locked_block_recurse(tx, &locked, &precommit_node, commit_node.justify(), &mut on_lock_block)?; - precommit_node.as_locked_block().set(tx)?; + let current_locked = LockedBlock::get(&**tx)?; + if prepared_node.height() > current_locked.height { + on_locked_block_recurse( + tx, + ¤t_locked, + &prepared_node, + justified_node.justify(), + &mut on_lock_block, + )?; + prepared_node.as_locked_block().set(tx)?; } // b <- b'.justify.node - let prepare_node = precommit_node.justify().block_id(); - if commit_node.parent() == precommit_node.id() && precommit_node.parent() == prepare_node { + let commit_node = prepared_node.justify().block_id(); + if justified_node.parent() == prepared_node.id() && prepared_node.parent() == commit_node { debug!( target: LOG_TARGET, "✅ Node {} {} forms a 3-chain b'' = {}, b' = {}, b = {}", self.height(), self.id(), - commit_node.id(), - precommit_node.id(), - prepare_node, + justified_node.id(), + prepared_node.id(), + commit_node, ); // Commit prepare_node (b) - if prepare_node.is_zero() { - return Ok(commit_node); + if commit_node.is_zero() { + return Ok(justified_node); } - let prepare_node = Block::get(&**tx, prepare_node)?; + let prepare_node = Block::get(&**tx, commit_node)?; let last_executed = LastExecuted::get(&**tx)?; on_commit_block_recurse(tx, &last_executed, &prepare_node, &mut on_commit)?; prepare_node.as_last_executed().set(tx)?; @@ -896,14 +902,14 @@ impl Block { "Node {} {} DOES NOT form a 3-chain b'' = {}, b' = {}, b = {}, b* = {}", self.height(), self.id(), - commit_node.id(), - precommit_node.id(), - prepare_node, + justified_node.id(), + prepared_node.id(), + commit_node, self.id() ); } - Ok(commit_node) + Ok(justified_node) } /// safeNode predicate (https://arxiv.org/pdf/1803.05069v6.pdf) diff --git a/dan_layer/storage/src/consensus_models/block_pledges.rs b/dan_layer/storage/src/consensus_models/block_pledges.rs index f6b0b0332..b91c7ec10 100644 --- a/dan_layer/storage/src/consensus_models/block_pledges.rs +++ b/dan_layer/storage/src/consensus_models/block_pledges.rs @@ -8,7 +8,13 @@ use std::{ }; use serde::{Deserialize, Serialize}; -use tari_dan_common_types::{SubstateLockType, SubstateRequirement, VersionedSubstateId}; +use tari_dan_common_types::{ + SubstateAddress, + SubstateLockType, + SubstateRequirement, + ToSubstateAddress, + VersionedSubstateId, +}; use tari_engine_types::substate::{SubstateId, SubstateValue}; use tari_transaction::TransactionId; @@ -115,6 +121,21 @@ impl SubstatePledge { pub fn substate_id(&self) -> &SubstateId { self.versioned_substate_id().substate_id() } + + pub fn to_substate_address(&self) -> SubstateAddress { + self.versioned_substate_id().to_substate_address() + } + + pub fn satisfies_requirement(&self, req: &SubstateRequirement) -> bool { + // Check if a requirement is met by this pledge. If the requirement does not specify a version, then the version + // requirement is, by definition, met. + req.version.map_or(true, |v| v == self.versioned_substate_id().version) && + self.substate_id() == req.substate_id() + } + + pub fn satisfies_address(&self, substate_address: &SubstateAddress) -> bool { + self.to_substate_address() == *substate_address + } } /// These are to detect and prevent duplicates in pledging. A pledge may only @@ -132,17 +153,6 @@ impl PartialEq for SubstatePledge { impl Eq for SubstatePledge {} -impl PartialEq for SubstatePledge { - fn eq(&self, other: &SubstateRequirement) -> bool { - // Check if a requirement is met by this pledge. If the requirement does not specify a version, then the version - // requirement is, by definition, met. - other - .version - .map_or(true, |v| v == self.versioned_substate_id().version) && - self.substate_id() == other.substate_id() - } -} - impl Display for SubstatePledge { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match self { diff --git a/dan_layer/storage/src/consensus_models/command.rs b/dan_layer/storage/src/consensus_models/command.rs index 0a6035965..22586bf74 100644 --- a/dan_layer/storage/src/consensus_models/command.rs +++ b/dan_layer/storage/src/consensus_models/command.rs @@ -111,12 +111,13 @@ pub enum Command { EndEpoch, } -#[derive(Debug, PartialEq, Eq, Ord, PartialOrd)] +#[derive(Debug, PartialEq, Eq, PartialOrd, Ord)] enum CommandOrdering<'a> { + EndEpoch, TransactionId(&'a TransactionId), MintConfidentialOutput(&'a SubstateId), + /// Foreign proposals must come first in the block ForeignProposal(&'a BlockId), - EndEpoch, } impl Command { @@ -213,23 +214,6 @@ impl Command { } } - /// Returns Some if the command should NOT result in finalising the transaction, otherwise None. - pub fn progressing(&self) -> Option<&TransactionAtom> { - match self { - Command::Prepare(tx) | - Command::LocalPrepare(tx) | - Command::AllPrepare(tx) | - Command::SomePrepare(tx) | - Command::LocalAccept(tx) => Some(tx), - Command::LocalOnly(_) | - Command::AllAccept(_) | - Command::SomeAccept(_) | - Command::EndEpoch | - Command::MintConfidentialOutput(_) | - Command::ForeignProposal(_) => None, - } - } - /// Returns Some if the command should result in finalising (COMMITing or ABORTing) the transaction, otherwise None. pub fn finalising(&self) -> Option<&TransactionAtom> { self.all_accept() @@ -290,3 +274,25 @@ impl Display for Command { } } } + +#[cfg(test)] +mod tests { + use std::str::FromStr; + + use super::*; + + #[test] + fn ordering() { + assert!( + CommandOrdering::ForeignProposal(&BlockId::zero()) > + CommandOrdering::TransactionId(&TransactionId::default()) + ); + let substate_id = + SubstateId::from_str("component_0000000000000000000000000000000000000000000000000000000000000000").unwrap(); + assert!( + CommandOrdering::MintConfidentialOutput(&substate_id) > + CommandOrdering::TransactionId(&TransactionId::default()) + ); + assert!(CommandOrdering::MintConfidentialOutput(&substate_id) > CommandOrdering::EndEpoch); + } +} diff --git a/dan_layer/storage/src/consensus_models/evidence.rs b/dan_layer/storage/src/consensus_models/evidence.rs index 205e6427c..fd3125d71 100644 --- a/dan_layer/storage/src/consensus_models/evidence.rs +++ b/dan_layer/storage/src/consensus_models/evidence.rs @@ -6,12 +6,15 @@ use std::{ fmt::{Display, Formatter}, }; -use indexmap::{IndexMap, IndexSet}; +use indexmap::IndexMap; +use log::*; use serde::{Deserialize, Serialize}; use tari_dan_common_types::{committee::CommitteeInfo, SubstateAddress, SubstateLockType, ToSubstateAddress}; use crate::consensus_models::{QcId, VersionedSubstateIdLockIntent}; +const LOG_TARGET: &str = "tari::dan::consensus_models::evidence"; + #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, Default)] #[cfg_attr( feature = "ts", @@ -43,14 +46,16 @@ impl Evidence { .map(|input| { let i = input.borrow(); (i.to_substate_address(), ShardEvidence { - qc_ids: IndexSet::new(), + prepare_justify: None, + accept_justify: None, lock: i.lock_type(), }) }) .chain(resulting_outputs.into_iter().map(|output| { let o = output.borrow(); (o.to_substate_address(), ShardEvidence { - qc_ids: IndexSet::new(), + prepare_justify: None, + accept_justify: None, lock: o.lock_type(), }) })) @@ -58,15 +63,27 @@ impl Evidence { } pub fn all_addresses_justified(&self) -> bool { - // TODO: we should check that remote has one QC and local has three - self.evidence.values().all(|qc_ids| !qc_ids.is_empty()) + // CASE: all inputs and outputs are accept justified. If they have been accept justified, they have implicitly + // been prepare justified. This may happen if the local node is only involved in outputs (and therefore + // sequences using the LocalAccept foreign proposal) + self.evidence.values().all(|e| e.is_accept_justified()) } - pub fn all_input_addresses_justified(&self) -> bool { + pub fn all_input_addresses_prepared(&self) -> bool { self.evidence .values() .filter(|e| !e.lock.is_output()) - .all(|qc_ids| !qc_ids.is_empty()) + // CASE: we use prepare OR accept because inputs can only be accept justified if they were prepared. Prepared + // may be implicit (null) if the local node is only involved in outputs (and therefore sequences using the LocalAccept + // foreign proposal) + .all(|e| e.is_prepare_justified() || e.is_accept_justified()) + } + + pub fn is_committee_output_only(&self, committee_info: &CommitteeInfo) -> bool { + self.evidence + .iter() + .filter(|(addr, _)| committee_info.includes_substate_address(addr)) + .all(|(_, e)| e.lock.is_output()) } pub fn is_empty(&self) -> bool { @@ -81,13 +98,6 @@ impl Evidence { self.evidence.get(substate_address) } - pub fn num_justified_shards(&self) -> usize { - self.evidence - .values() - .filter(|evidence| !evidence.qc_ids.is_empty()) - .count() - } - pub fn iter(&self) -> impl Iterator { self.evidence.iter() } @@ -96,16 +106,43 @@ impl Evidence { self.evidence.iter_mut() } - pub fn add_qc_evidence(&mut self, committee_info: &CommitteeInfo, qc_id: QcId) -> &mut Self { - for (address, evidence_mut) in self.iter_mut() { - if committee_info.includes_substate_address(address) { - evidence_mut.qc_ids.insert(qc_id); - } + pub fn add_prepare_qc_evidence(&mut self, committee_info: &CommitteeInfo, qc_id: QcId) -> &mut Self { + for (address, evidence_mut) in self.evidence_in_committee_iter_mut(committee_info) { + debug!( + target: LOG_TARGET, + "add_prepare_qc_evidence {} {address} QC[{qc_id}] {}", + committee_info.shard_group(), + evidence_mut.lock + ); + evidence_mut.prepare_justify = Some(qc_id); + } + + self + } + + pub fn add_accept_qc_evidence(&mut self, committee_info: &CommitteeInfo, qc_id: QcId) -> &mut Self { + for (address, evidence_mut) in self.evidence_in_committee_iter_mut(committee_info) { + debug!( + target: LOG_TARGET, + "add_accept_qc_evidence {} {address} QC[{qc_id}] {}", + committee_info.shard_group(), + evidence_mut.lock + ); + evidence_mut.accept_justify = Some(qc_id); } self } + fn evidence_in_committee_iter_mut<'a>( + &'a mut self, + committee_info: &'a CommitteeInfo, + ) -> impl Iterator { + self.evidence + .iter_mut() + .filter(|(addr, _)| committee_info.includes_substate_address(addr)) + } + /// Returns an iterator over the substate addresses in this Evidence object. /// NOTE: not all substates involved in the final transaction are necessarily included in this Evidence object until /// the transaction has reached AllAccepted state. @@ -118,7 +155,9 @@ impl Evidence { } pub fn qc_ids_iter(&self) -> impl Iterator + '_ { - self.evidence.values().flat_map(|e| e.qc_ids.iter()) + self.evidence + .values() + .flat_map(|e| e.prepare_justify.iter().chain(e.accept_justify.iter())) } /// Add or update substate addresses and locks into Evidence @@ -129,18 +168,20 @@ impl Evidence { .iter() // If the update contains an object (as in ObjectKey) that is already in the evidence, update it without duplicating the object key (inputs and outputs may have the same object key) .position(|(address, e)| { + // There may up to two matching object_key_bytes, but only if one is an input and the other is an output (lock_type.is_output() == e.lock.is_output()) && address.object_key_bytes() == substate_address.object_key_bytes() }); match maybe_pos { Some(pos) => { - let (_, mut evidence) = self.evidence.swap_remove_index(pos).expect("position is valid"); - evidence.lock = lock_type; - self.evidence.insert(substate_address, evidence); + if let Some((_, evidence_mut)) = self.evidence.get_index_mut(pos) { + evidence_mut.lock = lock_type; + } }, None => { self.evidence.insert(substate_address, ShardEvidence { - qc_ids: IndexSet::new(), + prepare_justify: None, + accept_justify: None, lock: lock_type, }); }, @@ -166,10 +207,15 @@ impl Evidence { }); match maybe_pos { Some(pos) => { - let (_, mut evidence) = self.evidence.swap_remove_index(pos).expect("position is valid"); - evidence.lock = shard_evidence.lock; - evidence.qc_ids.extend(shard_evidence.qc_ids); - self.evidence.insert(substate_address, evidence); + if let Some((_, evidence_mut)) = self.evidence.get_index_mut(pos) { + evidence_mut.lock = shard_evidence.lock; + if let Some(qc_id) = shard_evidence.prepare_justify { + evidence_mut.prepare_justify = Some(qc_id); + } + if let Some(qc_id) = shard_evidence.accept_justify { + evidence_mut.accept_justify = Some(qc_id); + } + } }, None => { self.evidence.insert(substate_address, shard_evidence); @@ -209,28 +255,37 @@ impl Display for Evidence { ts(export, export_to = "../../bindings/src/types/") )] pub struct ShardEvidence { - #[cfg_attr(feature = "ts", ts(type = "Array"))] - pub qc_ids: IndexSet, + #[cfg_attr(feature = "ts", ts(type = "string | null"))] + pub prepare_justify: Option, + #[cfg_attr(feature = "ts", ts(type = "string | null"))] + pub accept_justify: Option, pub lock: SubstateLockType, } impl ShardEvidence { - pub fn is_empty(&self) -> bool { - self.qc_ids.is_empty() - } - - pub fn contains(&self, qc_id: &QcId) -> bool { - self.qc_ids.contains(qc_id) + pub fn is_prepare_justified(&self) -> bool { + self.prepare_justify.is_some() } - pub fn insert(&mut self, qc_id: QcId) { - self.qc_ids.insert(qc_id); + pub fn is_accept_justified(&self) -> bool { + self.accept_justify.is_some() } } impl Display for ShardEvidence { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { - write!(f, "({}, {} QC(s))", self.lock, self.qc_ids.len()) + write!(f, "({}, ", self.lock)?; + if let Some(qc_id) = self.prepare_justify { + write!(f, "Prepare[{}]", qc_id)?; + } else { + write!(f, "Prepare[NONE]")?; + } + if let Some(qc_id) = self.accept_justify { + write!(f, ", Accept[{}]", qc_id)?; + } else { + write!(f, ", Accept[NONE]")?; + } + write!(f, ")") } } diff --git a/dan_layer/storage/src/consensus_models/foreign_proposal.rs b/dan_layer/storage/src/consensus_models/foreign_proposal.rs index a786d7f4b..2621d4d61 100644 --- a/dan_layer/storage/src/consensus_models/foreign_proposal.rs +++ b/dan_layer/storage/src/consensus_models/foreign_proposal.rs @@ -20,6 +20,7 @@ pub struct ForeignProposal { pub block_pledge: BlockPledge, pub justify_qc: QuorumCertificate, pub proposed_by_block: Option, + pub status: ForeignProposalStatus, } impl ForeignProposal { @@ -29,6 +30,7 @@ impl ForeignProposal { block_pledge, justify_qc, proposed_by_block: None, + status: ForeignProposalStatus::New, } } @@ -55,6 +57,10 @@ impl ForeignProposal { pub fn proposed_by_block(&self) -> Option<&BlockId> { self.proposed_by_block.as_ref() } + + pub fn status(&self) -> ForeignProposalStatus { + self.status + } } impl ForeignProposal { @@ -101,6 +107,13 @@ impl ForeignProposal { ) -> Result<(), StorageError> { tx.foreign_proposals_set_proposed_in(block_id, proposed_in_block) } + + pub fn has_unconfirmed( + tx: &TTx, + max_base_layer_block_height: u64, + ) -> Result { + tx.foreign_proposals_has_unconfirmed(max_base_layer_block_height) + } } #[derive(Debug, Clone, Eq, PartialEq, Hash, Serialize, Deserialize, PartialOrd, Ord)] @@ -123,16 +136,40 @@ impl ForeignProposalAtom { tx.foreign_proposals_exists(&self.block_id) } + pub fn get_proposal( + &self, + tx: &TTx, + ) -> Result { + let mut found = tx.foreign_proposals_get_any(Some(&self.block_id))?; + let found = found.pop().ok_or_else(|| StorageError::NotFound { + item: "ForeignProposal".to_string(), + key: self.block_id.to_string(), + })?; + Ok(found) + } + pub fn delete(&self, tx: &mut TTx) -> Result<(), StorageError> { ForeignProposal::delete(tx, &self.block_id) } + + pub fn set_status( + &self, + tx: &mut TTx, + status: ForeignProposalStatus, + ) -> Result<(), StorageError> { + tx.foreign_proposals_set_status(&self.block_id, status) + } } -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize, PartialOrd, Ord)] +#[derive(Debug, Clone, Copy, Serialize, Deserialize, Default)] pub enum ForeignProposalStatus { + /// New foreign proposal that has not yet been proposed + #[default] New, + /// Foreign proposal has been proposed, but not yet locked. Proposed, - Deleted, + /// Foreign proposal has been confirmed i.e. the block containing it has been locked. + Confirmed, } impl Display for ForeignProposalStatus { @@ -140,20 +177,24 @@ impl Display for ForeignProposalStatus { match self { ForeignProposalStatus::New => write!(f, "New"), ForeignProposalStatus::Proposed => write!(f, "Proposed"), - ForeignProposalStatus::Deleted => write!(f, "Deleted"), + ForeignProposalStatus::Confirmed => write!(f, "Confirmed"), } } } impl FromStr for ForeignProposalStatus { - type Err = anyhow::Error; + type Err = StorageError; fn from_str(s: &str) -> Result { match s { "New" => Ok(ForeignProposalStatus::New), "Proposed" => Ok(ForeignProposalStatus::Proposed), - "Deleted" => Ok(ForeignProposalStatus::Deleted), - _ => Err(anyhow::anyhow!("Invalid foreign proposal state {}", s)), + "Confirmed" => Ok(ForeignProposalStatus::Confirmed), + _ => Err(StorageError::DecodingError { + operation: "ForeignProposalStatus::from_str", + item: "foreign proposal", + details: format!("Invalid foreign proposal state {}", s), + }), } } } diff --git a/dan_layer/storage/src/consensus_models/lock_intent.rs b/dan_layer/storage/src/consensus_models/lock_intent.rs index dcdaa7bed..789b0852b 100644 --- a/dan_layer/storage/src/consensus_models/lock_intent.rs +++ b/dan_layer/storage/src/consensus_models/lock_intent.rs @@ -96,12 +96,7 @@ impl<'a> LockIntent for &'a VersionedSubstateIdLockIntent { } } -#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)] -#[cfg_attr( - feature = "ts", - derive(ts_rs::TS), - ts(export, export_to = "../../bindings/src/types/") -)] +#[derive(Debug, Clone)] pub struct SubstateRequirementLockIntent { substate_requirement: SubstateRequirement, version_to_lock: u32, diff --git a/dan_layer/storage/src/consensus_models/transaction.rs b/dan_layer/storage/src/consensus_models/transaction.rs index 529a36f4e..2a58f4846 100644 --- a/dan_layer/storage/src/consensus_models/transaction.rs +++ b/dan_layer/storage/src/consensus_models/transaction.rs @@ -363,12 +363,12 @@ impl TransactionRecord { let foreign_inputs = self .transaction() .all_inputs_iter() - .filter(|i| !local_committee_info.includes_substate_address(&i.to_substate_address_default_version(0))); + .filter(|i| !local_committee_info.includes_substate_id(i.substate_id())); // TODO(perf): this could be a bespoke DB query #[allow(clippy::mutable_key_type)] let pledges = tx.foreign_substate_pledges_get_all_by_transaction_id(self.id())?; for input in foreign_inputs { - if !pledges.iter().any(|p| *p == input) { + if pledges.iter().all(|p| !p.satisfies_requirement(&input)) { debug!( target: LOG_TARGET, "Transaction {} is missing a pledge for input {}", diff --git a/dan_layer/storage/src/consensus_models/transaction_pool.rs b/dan_layer/storage/src/consensus_models/transaction_pool.rs index c634465a9..c66a68641 100644 --- a/dan_layer/storage/src/consensus_models/transaction_pool.rs +++ b/dan_layer/storage/src/consensus_models/transaction_pool.rs @@ -17,6 +17,7 @@ use tari_dan_common_types::{ ShardGroup, ToSubstateAddress, }; +use tari_engine_types::transaction_receipt::TransactionReceiptAddress; use tari_transaction::TransactionId; use crate::{ @@ -32,7 +33,6 @@ use crate::{ SubstatePledges, TransactionAtom, TransactionExecution, - TransactionPoolStatusUpdate, TransactionRecord, }, StateStore, @@ -56,7 +56,7 @@ impl TransactionPool { pub fn get( &self, tx: &TStateStore::ReadTransaction<'_>, - leaf: LeafBlock, + leaf: &LeafBlock, id: &TransactionId, ) -> Result { // We always want to fetch the state at the current leaf block until the leaf block @@ -158,14 +158,12 @@ impl TransactionPool { Ok(count) } - pub fn confirm_all_transitions<'a, I: IntoIterator>( + pub fn confirm_all_transitions( &self, tx: &mut TStateStore::WriteTransaction<'_>, locked_block: &LockedBlock, - new_locked_block: &LockedBlock, - tx_ids: I, ) -> Result<(), TransactionPoolError> { - tx.transaction_pool_confirm_all_transitions(locked_block, new_locked_block, tx_ids)?; + tx.transaction_pool_confirm_all_transitions(locked_block)?; Ok(()) } @@ -319,7 +317,6 @@ pub struct TransactionPoolRecord { #[cfg_attr(feature = "ts", ts(type = "string"))] transaction_id: TransactionId, evidence: Evidence, - remote_evidence: Option, #[cfg_attr(feature = "ts", ts(type = "number"))] transaction_fee: u64, leader_fee: Option, @@ -335,7 +332,6 @@ impl TransactionPoolRecord { pub fn load( id: TransactionId, evidence: Evidence, - remote_evidence: Option, transaction_fee: Option, leader_fee: Option, stage: TransactionPoolStage, @@ -348,7 +344,6 @@ impl TransactionPoolRecord { Self { transaction_id: id, evidence, - remote_evidence, transaction_fee: transaction_fee.unwrap_or(0), leader_fee, stage, @@ -391,7 +386,7 @@ impl TransactionPoolRecord { &self.evidence } - fn evidence_mut(&mut self) -> &mut Evidence { + pub fn evidence_mut(&mut self) -> &mut Evidence { &mut self.evidence } @@ -422,6 +417,10 @@ impl TransactionPoolRecord { self.is_ready } + pub fn to_receipt_id(&self) -> TransactionReceiptAddress { + (*self.transaction_id()).into() + } + pub fn get_current_transaction_atom(&self) -> TransactionAtom { TransactionAtom { id: self.transaction_id, @@ -523,13 +522,43 @@ impl TransactionPoolRecord { self } + pub fn set_next_stage( + &mut self, + next_stage: TransactionPoolStage, + is_ready: bool, + ) -> Result<(), TransactionPoolError> { + if next_stage == self.stage && is_ready == self.is_ready { + return Ok(()); + } + + self.check_pending_status_update(next_stage, is_ready)?; + info!( + target: LOG_TARGET, + "📝 Setting next update for transaction {} to {}->{},is_ready={}->{},{}", + self.transaction_id(), + self.current_stage(), + next_stage, + self.is_ready, + is_ready, + self.current_decision(), + ); + self.pending_stage = Some(next_stage); + self.is_ready = is_ready; + Ok(()) + } + pub fn set_evidence(&mut self, evidence: Evidence) -> &mut Self { self.evidence = evidence; self } - pub fn add_qc_evidence(&mut self, committee_info: &CommitteeInfo, qc_id: QcId) -> &mut Self { - self.evidence.add_qc_evidence(committee_info, qc_id); + pub fn add_prepare_qc_evidence(&mut self, committee_info: &CommitteeInfo, qc_id: QcId) -> &mut Self { + self.evidence.add_prepare_qc_evidence(committee_info, qc_id); + self + } + + pub fn add_accept_qc_evidence(&mut self, committee_info: &CommitteeInfo, qc_id: QcId) -> &mut Self { + self.evidence.add_accept_qc_evidence(committee_info, qc_id); self } @@ -576,79 +605,6 @@ impl TransactionPoolRecord { } impl TransactionPoolRecord { - pub fn add_pending_status_update( - &mut self, - tx: &mut TTx, - block: LeafBlock, - pending_stage: TransactionPoolStage, - is_ready: bool, - ) -> Result<(), TransactionPoolError> { - self.check_pending_status_update(pending_stage, is_ready)?; - - debug!( - target: LOG_TARGET, - "add_pending_status_update: tx: {}, blk: {}, transition: {}->{}, ready {}->{}", - self.transaction_id, - block.block_id, - self.stage, - pending_stage, - self.is_ready, - is_ready, - ); - - let update = TransactionPoolStatusUpdate { - block_id: block.block_id, - transaction_id: self.transaction_id, - stage: pending_stage, - evidence: self.evidence.clone(), - is_ready, - local_decision: self.current_decision(), - }; - - update.insert(tx)?; - self.is_ready = is_ready; - self.pending_stage = Some(pending_stage); - - Ok(()) - } - - pub fn update_remote_data( - &mut self, - tx: &mut TTx, - decision: Decision, - foreign_qc_id: QcId, - foreign_committee_info: &CommitteeInfo, - remote_evidence: Evidence, - ) -> Result<(), TransactionPoolError> { - match self.remote_evidence.as_mut() { - Some(evidence) => { - evidence.update(remote_evidence.iter().map(|(addr, e)| (*addr, e.lock))); - }, - None => { - self.remote_evidence = Some(remote_evidence); - }, - } - self.remote_evidence - .as_mut() - .expect("set above") - .add_qc_evidence(foreign_committee_info, foreign_qc_id); - - tx.transaction_pool_update( - &self.transaction_id, - None, - None, - None, - Some(decision), - self.remote_evidence.as_ref(), - )?; - // Update the local evidence so that we can check if we have enough evidence to proceed - self.evidence - .merge(self.remote_evidence.as_ref().expect("set above").clone()); - // self.add_qc_evidence(foreign_committee_info, foreign_qc_id); - self.set_remote_decision(decision); - Ok(()) - } - #[allow(clippy::mutable_key_type)] pub fn add_foreign_pledges( &self, @@ -660,29 +616,6 @@ impl TransactionPoolRecord { Ok(()) } - pub fn update_local_data( - &mut self, - tx: &mut TTx, - is_ready: bool, - ) -> Result<(), TransactionPoolError> { - if self - .local_decision - .map(|d| d != self.current_decision()) - .unwrap_or(true) - { - self.set_local_decision(self.current_decision()); - tx.transaction_pool_update( - &self.transaction_id, - Some(is_ready), - Some(self.current_decision()), - Some(&self.evidence), - None, - None, - )?; - } - Ok(()) - } - pub fn remove(&self, tx: &mut TTx) -> Result<(), TransactionPoolError> { tx.transaction_pool_remove(&self.transaction_id)?; Ok(()) @@ -714,6 +647,16 @@ impl TransactionPoolRecord { Ok(recs) } + pub fn get( + tx: &TTx, + from_block_id: &BlockId, + to_block_id: &BlockId, + transaction_id: &TransactionId, + ) -> Result { + let rec = tx.transaction_pool_get_for_blocks(from_block_id, to_block_id, transaction_id)?; + Ok(rec) + } + pub fn get_transaction( &self, tx: &TTx, @@ -730,6 +673,12 @@ impl TransactionPoolRecord { let exec = BlockTransactionExecution::get_pending_for_block(tx, self.transaction_id(), from_block_id)?; Ok(exec) } + + pub fn has_any_local_inputs(&self, local_committee_info: &CommitteeInfo) -> bool { + self.evidence + .iter() + .any(|(addr, ev)| !ev.lock.is_output() && local_committee_info.includes_substate_address(addr)) + } } #[derive(Debug, thiserror::Error)] @@ -742,11 +691,6 @@ pub enum TransactionPoolError { to: TransactionPoolStage, is_ready: bool, }, - #[error("Transaction already updated: {transaction_id} in block {block_id}")] - TransactionAlreadyUpdated { - transaction_id: TransactionId, - block_id: BlockId, - }, #[error("Transaction already executed: {transaction_id} in block {block_id}")] TransactionAlreadyExecuted { transaction_id: TransactionId, @@ -794,7 +738,6 @@ mod tests { transaction_id: TransactionId::new([0; 32]), original_decision: Decision::Commit, evidence: Default::default(), - remote_evidence: None, transaction_fee: fee, leader_fee: None, stage: TransactionPoolStage::New, diff --git a/dan_layer/storage/src/consensus_models/transaction_pool_status_update.rs b/dan_layer/storage/src/consensus_models/transaction_pool_status_update.rs index 3bed503a3..8dcfafbd1 100644 --- a/dan_layer/storage/src/consensus_models/transaction_pool_status_update.rs +++ b/dan_layer/storage/src/consensus_models/transaction_pool_status_update.rs @@ -4,52 +4,55 @@ use tari_transaction::TransactionId; use crate::{ - consensus_models::{BlockId, Decision, Evidence, TransactionPoolStage}, + consensus_models::{BlockId, Decision, Evidence, TransactionPoolRecord, TransactionPoolStage}, StateStoreWriteTransaction, }; #[derive(Debug, Clone)] pub struct TransactionPoolStatusUpdate { - pub block_id: BlockId, - pub transaction_id: TransactionId, - pub stage: TransactionPoolStage, - pub evidence: Evidence, - pub is_ready: bool, - pub local_decision: Decision, + pub transaction: TransactionPoolRecord, } impl TransactionPoolStatusUpdate { - pub fn block_id(&self) -> &BlockId { - &self.block_id - } - pub fn transaction_id(&self) -> &TransactionId { - &self.transaction_id + self.transaction.transaction_id() } pub fn stage(&self) -> TransactionPoolStage { - self.stage + self.transaction.current_stage() } pub fn evidence(&self) -> &Evidence { - &self.evidence + self.transaction.evidence() } pub fn evidence_mut(&mut self) -> &mut Evidence { - &mut self.evidence + self.transaction.evidence_mut() } pub fn is_ready(&self) -> bool { - self.is_ready + self.transaction.is_ready() + } + + pub fn decision(&self) -> Decision { + self.transaction.current_decision() + } + + pub fn remote_decision(&self) -> Option { + self.transaction.remote_decision() } - pub fn local_decision(&self) -> Decision { - self.local_decision + pub fn apply_evidence(&self, tx_rec_mut: &mut TransactionPoolRecord) { + tx_rec_mut.set_evidence(self.evidence().clone()); } } impl TransactionPoolStatusUpdate { - pub fn insert(&self, tx: &mut TTx) -> Result<(), crate::StorageError> { - tx.transaction_pool_add_pending_update(self) + pub fn insert_for_block( + &self, + tx: &mut TTx, + block_id: &BlockId, + ) -> Result<(), crate::StorageError> { + tx.transaction_pool_add_pending_update(block_id, self) } } diff --git a/dan_layer/storage/src/state_store/mod.rs b/dan_layer/storage/src/state_store/mod.rs index 98c0a4a6f..fe1fff8b6 100644 --- a/dan_layer/storage/src/state_store/mod.rs +++ b/dan_layer/storage/src/state_store/mod.rs @@ -19,6 +19,7 @@ use tari_dan_common_types::{ ShardGroup, SubstateAddress, SubstateRequirement, + ToSubstateAddress, VersionedSubstateId, }; use tari_engine_types::substate::SubstateId; @@ -36,10 +37,10 @@ use crate::{ BurntUtxo, Decision, EpochCheckpoint, - Evidence, ForeignParkedProposal, ForeignProposal, ForeignProposalAtom, + ForeignProposalStatus, ForeignReceiveCounters, ForeignSendCounters, HighQc, @@ -121,6 +122,7 @@ pub trait StateStoreReadTransaction: Sized { block_ids: I, ) -> Result, StorageError>; fn foreign_proposals_exists(&self, block_id: &BlockId) -> Result; + fn foreign_proposals_has_unconfirmed(&self, max_base_layer_block_height: u64) -> Result; fn foreign_proposals_get_all_new( &self, max_base_layer_block_height: u64, @@ -317,6 +319,11 @@ pub trait StateStoreReadTransaction: Sized { fn epoch_checkpoint_get(&self, epoch: Epoch) -> Result; // -------------------------------- Foreign Substate Pledges -------------------------------- // + fn foreign_substate_pledges_exists_for_address( + &self, + transaction_id: &TransactionId, + address: T, + ) -> Result; fn foreign_substate_pledges_get_all_by_transaction_id( &self, transaction_id: &TransactionId, @@ -371,6 +378,11 @@ pub trait StateStoreWriteTransaction { proposed_in_block: Option, ) -> Result<(), StorageError>; fn foreign_proposals_delete(&mut self, block_id: &BlockId) -> Result<(), StorageError>; + fn foreign_proposals_set_status( + &mut self, + block_id: &BlockId, + status: ForeignProposalStatus, + ) -> Result<(), StorageError>; fn foreign_proposals_set_proposed_in( &mut self, @@ -415,29 +427,16 @@ pub trait StateStoreWriteTransaction { ) -> Result<(), StorageError>; fn transaction_pool_add_pending_update( &mut self, + block_id: &BlockId, pool_update: &TransactionPoolStatusUpdate, ) -> Result<(), StorageError>; - fn transaction_pool_update( - &mut self, - transaction_id: &TransactionId, - is_ready: Option, - local_decision: Option, - local_evidence: Option<&Evidence>, - remote_decision: Option, - remote_evidence: Option<&Evidence>, - ) -> Result<(), StorageError>; fn transaction_pool_remove(&mut self, transaction_id: &TransactionId) -> Result<(), StorageError>; fn transaction_pool_remove_all<'a, I: IntoIterator>( &mut self, transaction_ids: I, ) -> Result, StorageError>; - fn transaction_pool_confirm_all_transitions<'a, I: IntoIterator>( - &mut self, - locked_block: &LockedBlock, - new_locked_block: &LockedBlock, - tx_ids: I, - ) -> Result<(), StorageError>; + fn transaction_pool_confirm_all_transitions(&mut self, new_locked_block: &LockedBlock) -> Result<(), StorageError>; // -------------------------------- Missing Transactions -------------------------------- // diff --git a/dan_layer/template_lib/src/models/entity_id.rs b/dan_layer/template_lib/src/models/entity_id.rs index 22d5fc731..b9b11b059 100644 --- a/dan_layer/template_lib/src/models/entity_id.rs +++ b/dan_layer/template_lib/src/models/entity_id.rs @@ -135,7 +135,7 @@ impl From<[u8; Self::LENGTH]> for ComponentKey { } } -/// Representation of a 32-byte hash value +/// Representation of a 32-byte object key #[serde_as] #[derive(Debug, Clone, Copy, PartialEq, Eq, Ord, PartialOrd, Hash, Default, serde::Serialize, serde::Deserialize)] #[serde(transparent)] diff --git a/integration_tests/tests/features/claim_burn.feature b/integration_tests/tests/features/claim_burn.feature index 5c3e57713..483810971 100644 --- a/integration_tests/tests/features/claim_burn.feature +++ b/integration_tests/tests/features/claim_burn.feature @@ -36,7 +36,7 @@ Feature: Claim Burn Then VN has scanned to height 30 When I convert commitment COMMITMENT into COMM_ADDRESS address - Then validator node VN has state at COMM_ADDRESS + Then validator node VN has state at COMM_ADDRESS within 20 seconds When I claim burn COMMITMENT with PROOF, RANGEPROOF and CLAIM_PUBKEY and spend it into account ACC via the wallet daemon WALLET_D # Then account ACC has one confidential bucket in it @@ -73,10 +73,8 @@ Feature: Claim Burn When miner MINER mines 13 new blocks Then VN has scanned to height 30 - # TODO: remove sleep - this is needed to allow validators enough time to propose the UTXO - When I wait 10 seconds When I convert commitment COMMITMENT into COMM_ADDRESS address - Then validator node VN has state at COMM_ADDRESS + Then validator node VN has state at COMM_ADDRESS within 20 seconds When I claim burn COMMITMENT with PROOF, RANGEPROOF and CLAIM_PUBKEY and spend it into account ACC via the wallet daemon WALLET_D When I claim burn COMMITMENT with PROOF, RANGEPROOF and CLAIM_PUBKEY and spend it into account ACC via the wallet daemon WALLET_D, it fails diff --git a/integration_tests/tests/features/transfer.feature b/integration_tests/tests/features/transfer.feature index 7e4f02752..9f9934b44 100644 --- a/integration_tests/tests/features/transfer.feature +++ b/integration_tests/tests/features/transfer.feature @@ -48,7 +48,7 @@ Feature: Account transfers Then indexer IDX has scanned to height 45 When I convert commitment COMMITMENT into COMM_ADDRESS address - Then validator node VN has state at COMM_ADDRESS + Then validator node VN has state at COMM_ADDRESS within 20 seconds When I claim burn COMMITMENT with PROOF, RANGEPROOF and CLAIM_PUBKEY and spend it into account ACCOUNT via the wallet daemon WALLET_D # Wait for the wallet daemon account monitor to update the sender account information @@ -129,7 +129,7 @@ Feature: Account transfers Then indexer IDX has scanned to height 45 When I convert commitment COMMITMENT into COMM_ADDRESS address - Then validator node VN has state at COMM_ADDRESS + Then validator node VN has state at COMM_ADDRESS within 20 seconds When I claim burn COMMITMENT with PROOF, RANGEPROOF and CLAIM_PUBKEY and spend it into account ACCOUNT_1 via the wallet daemon WALLET_D # Wait for the wallet daemon account monitor to update the sender account information diff --git a/integration_tests/tests/features/wallet_daemon.feature b/integration_tests/tests/features/wallet_daemon.feature index f6bb4919b..8a0eedd80 100644 --- a/integration_tests/tests/features/wallet_daemon.feature +++ b/integration_tests/tests/features/wallet_daemon.feature @@ -120,7 +120,7 @@ Feature: Wallet Daemon Then VN has scanned to height 30 When I convert commitment COMMITMENT into COMM_ADDRESS address - Then validator node VN has state at COMM_ADDRESS + Then validator node VN has state at COMM_ADDRESS within 20 seconds When I claim burn COMMITMENT with PROOF, RANGEPROOF and CLAIM_PUBKEY and spend it into account ACCOUNT_1 via the wallet daemon WALLET_D When I print the cucumber world diff --git a/integration_tests/tests/steps/validator_node.rs b/integration_tests/tests/steps/validator_node.rs index 331527467..1ab7370dd 100644 --- a/integration_tests/tests/steps/validator_node.rs +++ b/integration_tests/tests/steps/validator_node.rs @@ -320,8 +320,13 @@ async fn assert_template_is_registered_by_all(world: &mut TariWorld, template_na } } -#[then(expr = "validator node {word} has state at {word}")] -async fn then_validator_node_has_state_at(world: &mut TariWorld, vn_name: String, state_address_name: String) { +#[then(expr = "validator node {word} has state at {word} within {int} seconds")] +async fn then_validator_node_has_state_at( + world: &mut TariWorld, + vn_name: String, + state_address_name: String, + timeout_secs: u64, +) { let state_address = world .addresses .get(&state_address_name) @@ -330,14 +335,25 @@ async fn then_validator_node_has_state_at(world: &mut TariWorld, vn_name: String let mut client = vn.create_client(); let substate_address = SubstateAddress::from_substate_id(&SubstateId::from_str(state_address).expect("Invalid state address"), 0); - if let Err(e) = client - .get_state(GetStateRequest { - address: substate_address, - }) - .await - { - println!("Failed to get state: {}", e); - panic!("Failed to get state: {}", e); + let mut attempts = 0; + loop { + match client + .get_state(GetStateRequest { + address: substate_address, + }) + .await + { + Ok(_) => return, + Err(e) => { + attempts += 1; + if attempts == timeout_secs { + println!("Failed to get state: {}", e); + panic!("Failed to get state: {}", e); + } + }, + } + + tokio::time::sleep(Duration::from_secs(1)).await; } }