diff --git a/Cargo.lock b/Cargo.lock index 4c85d46a2..d66bc7a96 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -9469,7 +9469,6 @@ dependencies = [ "indexmap 2.6.0", "log", "serde", - "serde_json", "tari_common", "tari_common_types", "tari_crypto", diff --git a/applications/tari_swarm_daemon/src/webserver/rpc/validator_nodes.rs b/applications/tari_swarm_daemon/src/webserver/rpc/validator_nodes.rs index e20904a70..616277ae6 100644 --- a/applications/tari_swarm_daemon/src/webserver/rpc/validator_nodes.rs +++ b/applications/tari_swarm_daemon/src/webserver/rpc/validator_nodes.rs @@ -8,15 +8,15 @@ use serde::{Deserialize, Serialize}; use crate::{config::InstanceType, process_manager::InstanceId, webserver::context::HandlerContext}; -#[derive(Debug, Clone, Serialize, Deserialize)] +#[derive(Debug, Clone, Deserialize)] pub struct ListValidatorNodesRequest {} -#[derive(Debug, Clone, Serialize, Deserialize)] +#[derive(Debug, Clone, Serialize)] pub struct ListValidatorNodesResponse { pub nodes: Vec, } -#[derive(Debug, Clone, Serialize, Deserialize)] +#[derive(Debug, Clone, Serialize)] pub struct ValidatorNodeInfo { pub instance_id: InstanceId, pub name: String, @@ -55,13 +55,14 @@ pub async fn list( Ok(ListValidatorNodesResponse { nodes }) } -#[derive(Debug, Clone, Serialize, Deserialize)] +#[derive(Debug, Clone, Deserialize)] pub struct ValidatorNodeCreateRequest { - pub name: String, - pub register: bool, + name: Option, + register: bool, + mine: bool, } -#[derive(Debug, Clone, Serialize, Deserialize)] +#[derive(Debug, Clone, Serialize)] pub struct ValidatorNodeCreateResponse { pub instance_id: InstanceId, } @@ -70,14 +71,24 @@ pub async fn create( context: &HandlerContext, req: ValidatorNodeCreateRequest, ) -> Result { - let instance_id = context - .process_manager() - .create_instance(req.name, InstanceType::TariValidatorNode, HashMap::new()) + let process_manager = context.process_manager(); + + let name = match req.name { + Some(name) => name, + None => { + let all_instances = process_manager.list_instances(None).await?; + format!("New VN-#{}", all_instances.len()) + }, + }; + let instance_id = process_manager + .create_instance(name, InstanceType::TariValidatorNode, HashMap::new()) .await?; if req.register { - context.process_manager().register_validator_node(instance_id).await?; - context.process_manager().mine_blocks(10).await?; + process_manager.register_validator_node(instance_id).await?; + if req.mine { + process_manager.mine_blocks(10).await?; + } } Ok(ValidatorNodeCreateResponse { instance_id }) diff --git a/applications/tari_swarm_daemon/webui/src/routes/Main.tsx b/applications/tari_swarm_daemon/webui/src/routes/Main.tsx index 77881dc11..339d584f4 100644 --- a/applications/tari_swarm_daemon/webui/src/routes/Main.tsx +++ b/applications/tari_swarm_daemon/webui/src/routes/Main.tsx @@ -524,6 +524,10 @@ export default function Main() { jsonRpc("start_all", { instance_type: "TariValidatorNode" }).then(getInfo); }; + const addValidatorNode = () => { + jsonRpc("add_validator_node", { name: null, register: true, mine: false }).then(getInfo); + }; + return (
@@ -532,6 +536,7 @@ export default function Main() { +
Base layer
diff --git a/applications/tari_validator_node/src/json_rpc/handlers.rs b/applications/tari_validator_node/src/json_rpc/handlers.rs index 0e34bdc09..4be691868 100644 --- a/applications/tari_validator_node/src/json_rpc/handlers.rs +++ b/applications/tari_validator_node/src/json_rpc/handlers.rs @@ -342,8 +342,9 @@ impl JsonRpcHandlers { let transaction = self .state_store - .with_read_tx(|tx| ExecutedTransaction::get(tx, &data.transaction_id)) - .map_err(internal_error(answer_id))?; + .with_read_tx(|tx| ExecutedTransaction::get(tx, &data.transaction_id).optional()) + .map_err(internal_error(answer_id))? + .ok_or_else(|| not_found(answer_id, format!("Transaction {} not found", data.transaction_id)))?; Ok(JsonRpcResponse::success(answer_id, GetTransactionResponse { transaction, @@ -410,40 +411,25 @@ impl JsonRpcHandlers { pub async fn get_block(&self, value: JsonRpcExtractor) -> JrpcResult { let answer_id = value.get_answer_id(); let data: GetBlockRequest = value.parse_params()?; - let tx = self.state_store.create_read_tx().map_err(internal_error(answer_id))?; - match Block::get(&tx, &data.block_id) { - Ok(block) => { - let res = GetBlockResponse { block }; - Ok(JsonRpcResponse::success(answer_id, res)) - }, - Err(e) => Err(JsonRpcResponse::error( - answer_id, - JsonRpcError::new( - JsonRpcErrorReason::InvalidParams, - format!("Something went wrong: {}", e), - json::Value::Null, - ), - )), - } + let block = self + .state_store + .with_read_tx(|tx| Block::get(tx, &data.block_id).optional()) + .map_err(internal_error(answer_id))? + .ok_or_else(|| not_found(answer_id, format!("Block {} not found", data.block_id)))?; + + let res = GetBlockResponse { block }; + Ok(JsonRpcResponse::success(answer_id, res)) } pub async fn get_blocks_count(&self, value: JsonRpcExtractor) -> JrpcResult { let answer_id = value.get_answer_id(); - let tx = self.state_store.create_read_tx().map_err(internal_error(answer_id))?; - match Block::get_count(&tx) { - Ok(count) => { - let res = GetBlocksCountResponse { count }; - Ok(JsonRpcResponse::success(answer_id, res)) - }, - Err(e) => Err(JsonRpcResponse::error( - answer_id, - JsonRpcError::new( - JsonRpcErrorReason::InternalError, - format!("Something went wrong: {}", e), - json::Value::Null, - ), - )), - } + let count = self + .state_store + .with_read_tx(|tx| Block::get_count(tx)) + .map_err(internal_error(answer_id))?; + + let res = GetBlocksCountResponse { count }; + Ok(JsonRpcResponse::success(answer_id, res)) } pub async fn get_filtered_blocks_count(&self, value: JsonRpcExtractor) -> JrpcResult { diff --git a/applications/tari_validator_node/src/json_rpc/server.rs b/applications/tari_validator_node/src/json_rpc/server.rs index e392b92f5..836e2bb20 100644 --- a/applications/tari_validator_node/src/json_rpc/server.rs +++ b/applications/tari_validator_node/src/json_rpc/server.rs @@ -23,7 +23,7 @@ use std::{net::SocketAddr, sync::Arc}; use axum::{extract::Extension, routing::post, Router}; -use axum_jrpc::{JrpcResult, JsonRpcAnswer, JsonRpcExtractor}; +use axum_jrpc::{error::JsonRpcErrorReason, JrpcResult, JsonRpcAnswer, JsonRpcExtractor}; use log::*; use tower_http::cors::CorsLayer; @@ -111,8 +111,12 @@ async fn handler(Extension(handlers): Extension>, value: Js serde_json::to_string_pretty(val).unwrap_or_else(|e| e.to_string()) ); }, + // Log application errors as debug as these are typically intentional + JsonRpcAnswer::Error(err) if matches!(err.error_reason(), JsonRpcErrorReason::ApplicationError(_)) => { + debug!(target: LOG_TARGET, "JSON-RPC: {}", err); + }, JsonRpcAnswer::Error(err) => { - error!(target: LOG_TARGET, "🚨 JSON-RPC request failed: {}", err); + error!(target: LOG_TARGET, "JSON-RPC request failed: {}", err); }, } } diff --git a/applications/tari_validator_node/src/p2p/services/messaging/outbound.rs b/applications/tari_validator_node/src/p2p/services/messaging/outbound.rs index b029e6687..a57869114 100644 --- a/applications/tari_validator_node/src/p2p/services/messaging/outbound.rs +++ b/applications/tari_validator_node/src/p2p/services/messaging/outbound.rs @@ -102,7 +102,29 @@ impl tari_consensus::traits::OutboundMessaging Ok(()) } - async fn multicast(&mut self, shard_group: ShardGroup, message: T) -> Result<(), OutboundMessagingError> + async fn multicast(&mut self, addresses: I, message: T) -> Result<(), OutboundMessagingError> + where + I: IntoIterator + Send, + T: Into + Send, + { + let message = message.into(); + + self.networking + .send_multicast( + addresses + .into_iter() + .filter(|addr| *addr != self.our_node_addr) + .map(|addr| addr.as_peer_id()) + .collect::>(), + proto::consensus::HotStuffMessage::from(&message), + ) + .await + .map_err(OutboundMessagingError::from_error)?; + + Ok(()) + } + + async fn broadcast(&mut self, shard_group: ShardGroup, message: T) -> Result<(), OutboundMessagingError> where T: Into + Send { let message = message.into(); diff --git a/bindings/dist/index.d.ts b/bindings/dist/index.d.ts index 2de55da51..4ca5f8260 100644 --- a/bindings/dist/index.d.ts +++ b/bindings/dist/index.d.ts @@ -2,25 +2,25 @@ export * from "./types/AbortReason"; export * from "./types/AccessRule"; export * from "./types/Account"; export * from "./types/Amount"; -export * from "./types/Arg"; export * from "./types/ArgDef"; +export * from "./types/Arg"; export * from "./types/AuthHook"; -export * from "./types/Block"; export * from "./types/BlockHeader"; +export * from "./types/Block"; export * from "./types/BucketId"; export * from "./types/Claims"; export * from "./types/Command"; -export * from "./types/Committee"; 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/ConfidentialOutput"; export * from "./types/ConfidentialOutputStatement"; +export * from "./types/ConfidentialOutput"; export * from "./types/ConfidentialStatement"; export * from "./types/ConfidentialTransferInputSelection"; export * from "./types/ConfidentialWithdrawProof"; @@ -32,12 +32,12 @@ export * from "./types/Era"; export * from "./types/Event"; export * from "./types/EvictNodeAtom"; export * from "./types/Evidence"; -export * from "./types/ExecuteResult"; export * from "./types/ExecutedTransaction"; +export * from "./types/ExecuteResult"; export * from "./types/ExtraData"; export * from "./types/FeeBreakdown"; -export * from "./types/FeeClaim"; export * from "./types/FeeClaimAddress"; +export * from "./types/FeeClaim"; export * from "./types/FeeCostBreakdown"; export * from "./types/FeeReceipt"; export * from "./types/FeeSource"; @@ -46,10 +46,10 @@ export * from "./types/ForeignProposalAtom"; export * from "./types/FunctionDef"; export * from "./types/IndexedValue"; export * from "./types/IndexedWellKnownTypes"; -export * from "./types/Instruction"; export * from "./types/InstructionResult"; -export * from "./types/JrpcPermission"; +export * from "./types/Instruction"; export * from "./types/JrpcPermissions"; +export * from "./types/JrpcPermission"; export * from "./types/LeaderFee"; export * from "./types/LockFlag"; export * from "./types/LogEntry"; @@ -58,14 +58,14 @@ export * from "./types/Metadata"; export * from "./types/MintConfidentialOutputAtom"; export * from "./types/NetworkCommitteeInfo"; export * from "./types/NodeHeight"; -export * from "./types/NonFungible"; -export * from "./types/NonFungibleAddress"; export * from "./types/NonFungibleAddressContents"; +export * from "./types/NonFungibleAddress"; export * from "./types/NonFungibleContainer"; export * from "./types/NonFungibleId"; -export * from "./types/NonFungibleIndex"; 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"; @@ -75,50 +75,50 @@ export * from "./types/QuorumCertificate"; export * from "./types/QuorumDecision"; export * from "./types/RejectReason"; export * from "./types/RequireRule"; -export * from "./types/Resource"; 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/ResumeNodeAtom"; export * from "./types/RuleRequirement"; -export * from "./types/Shard"; export * from "./types/ShardEvidence"; -export * from "./types/ShardGroup"; export * from "./types/ShardGroupEvidence"; -export * from "./types/Substate"; +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/SubstateLockType"; export * from "./types/SubstateRecord"; -export * from "./types/SubstateRequirement"; export * from "./types/SubstateRequirementLockIntent"; +export * from "./types/SubstateRequirement"; +export * from "./types/Substate"; export * from "./types/SubstateType"; export * from "./types/SubstateValue"; export * from "./types/SuspendNodeAtom"; export * from "./types/TemplateDef"; export * from "./types/TemplateDefV1"; -export * from "./types/Transaction"; export * from "./types/TransactionAtom"; export * from "./types/TransactionPoolRecord"; export * from "./types/TransactionPoolStage"; -export * from "./types/TransactionReceipt"; 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/UnclaimedConfidentialOutputAddress"; +export * from "./types/UnclaimedConfidentialOutput"; export * from "./types/UnsignedTransaction"; export * from "./types/ValidatorSignature"; -export * from "./types/Vault"; export * from "./types/VaultId"; -export * from "./types/VersionedSubstateId"; +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"; diff --git a/bindings/dist/index.js b/bindings/dist/index.js index 373efe48a..4dfb6fe4b 100644 --- a/bindings/dist/index.js +++ b/bindings/dist/index.js @@ -4,25 +4,25 @@ export * from "./types/AbortReason"; export * from "./types/AccessRule"; export * from "./types/Account"; export * from "./types/Amount"; -export * from "./types/Arg"; export * from "./types/ArgDef"; +export * from "./types/Arg"; export * from "./types/AuthHook"; -export * from "./types/Block"; export * from "./types/BlockHeader"; +export * from "./types/Block"; export * from "./types/BucketId"; export * from "./types/Claims"; export * from "./types/Command"; -export * from "./types/Committee"; 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/ConfidentialOutput"; export * from "./types/ConfidentialOutputStatement"; +export * from "./types/ConfidentialOutput"; export * from "./types/ConfidentialStatement"; export * from "./types/ConfidentialTransferInputSelection"; export * from "./types/ConfidentialWithdrawProof"; @@ -34,12 +34,12 @@ export * from "./types/Era"; export * from "./types/Event"; export * from "./types/EvictNodeAtom"; export * from "./types/Evidence"; -export * from "./types/ExecuteResult"; export * from "./types/ExecutedTransaction"; +export * from "./types/ExecuteResult"; export * from "./types/ExtraData"; export * from "./types/FeeBreakdown"; -export * from "./types/FeeClaim"; export * from "./types/FeeClaimAddress"; +export * from "./types/FeeClaim"; export * from "./types/FeeCostBreakdown"; export * from "./types/FeeReceipt"; export * from "./types/FeeSource"; @@ -48,10 +48,10 @@ export * from "./types/ForeignProposalAtom"; export * from "./types/FunctionDef"; export * from "./types/IndexedValue"; export * from "./types/IndexedWellKnownTypes"; -export * from "./types/Instruction"; export * from "./types/InstructionResult"; -export * from "./types/JrpcPermission"; +export * from "./types/Instruction"; export * from "./types/JrpcPermissions"; +export * from "./types/JrpcPermission"; export * from "./types/LeaderFee"; export * from "./types/LockFlag"; export * from "./types/LogEntry"; @@ -60,14 +60,14 @@ export * from "./types/Metadata"; export * from "./types/MintConfidentialOutputAtom"; export * from "./types/NetworkCommitteeInfo"; export * from "./types/NodeHeight"; -export * from "./types/NonFungible"; -export * from "./types/NonFungibleAddress"; export * from "./types/NonFungibleAddressContents"; +export * from "./types/NonFungibleAddress"; export * from "./types/NonFungibleContainer"; export * from "./types/NonFungibleId"; -export * from "./types/NonFungibleIndex"; 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"; @@ -77,50 +77,50 @@ export * from "./types/QuorumCertificate"; export * from "./types/QuorumDecision"; export * from "./types/RejectReason"; export * from "./types/RequireRule"; -export * from "./types/Resource"; 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/ResumeNodeAtom"; export * from "./types/RuleRequirement"; -export * from "./types/Shard"; export * from "./types/ShardEvidence"; -export * from "./types/ShardGroup"; export * from "./types/ShardGroupEvidence"; -export * from "./types/Substate"; +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/SubstateLockType"; export * from "./types/SubstateRecord"; -export * from "./types/SubstateRequirement"; export * from "./types/SubstateRequirementLockIntent"; +export * from "./types/SubstateRequirement"; +export * from "./types/Substate"; export * from "./types/SubstateType"; export * from "./types/SubstateValue"; export * from "./types/SuspendNodeAtom"; export * from "./types/TemplateDef"; export * from "./types/TemplateDefV1"; -export * from "./types/Transaction"; export * from "./types/TransactionAtom"; export * from "./types/TransactionPoolRecord"; export * from "./types/TransactionPoolStage"; -export * from "./types/TransactionReceipt"; 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/UnclaimedConfidentialOutputAddress"; +export * from "./types/UnclaimedConfidentialOutput"; export * from "./types/UnsignedTransaction"; export * from "./types/ValidatorSignature"; -export * from "./types/Vault"; export * from "./types/VaultId"; -export * from "./types/VersionedSubstateId"; +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"; diff --git a/bindings/dist/tari-indexer-client.d.ts b/bindings/dist/tari-indexer-client.d.ts index 03fbfd537..2bc290afb 100644 --- a/bindings/dist/tari-indexer-client.d.ts +++ b/bindings/dist/tari-indexer-client.d.ts @@ -1,34 +1,34 @@ -export * from "./types/tari-indexer-client/IndexerGetEpochManagerStatsResponse"; -export * from "./types/tari-indexer-client/IndexerAddPeerRequest"; -export * from "./types/tari-indexer-client/NonFungibleSubstate"; -export * from "./types/tari-indexer-client/GetNonFungibleCountResponse"; -export * from "./types/tari-indexer-client/ListSubstatesRequest"; -export * from "./types/tari-indexer-client/IndexerGetIdentityResponse"; +export * from "./types/tari-indexer-client/IndexerSubmitTransactionResponse"; export * from "./types/tari-indexer-client/GetTemplateDefinitionRequest"; -export * from "./types/tari-indexer-client/IndexerGetSubstateRequest"; -export * from "./types/tari-indexer-client/GetTemplateDefinitionResponse"; -export * from "./types/tari-indexer-client/ListTemplatesRequest"; +export * from "./types/tari-indexer-client/ListSubstatesResponse"; +export * from "./types/tari-indexer-client/IndexerAddPeerResponse"; +export * from "./types/tari-indexer-client/InspectSubstateRequest"; +export * from "./types/tari-indexer-client/ListSubstateItem"; export * from "./types/tari-indexer-client/IndexerGetAllVnsResponse"; -export * from "./types/tari-indexer-client/GetNonFungiblesRequest"; +export * from "./types/tari-indexer-client/ListSubstatesRequest"; +export * from "./types/tari-indexer-client/GetRelatedTransactionsResponse"; +export * from "./types/tari-indexer-client/IndexerTransactionFinalizedResult"; export * from "./types/tari-indexer-client/IndexerGetSubstateResponse"; -export * from "./types/tari-indexer-client/IndexerSubmitTransactionRequest"; -export * from "./types/tari-indexer-client/IndexerConnection"; -export * from "./types/tari-indexer-client/InspectSubstateResponse"; export * from "./types/tari-indexer-client/IndexerGetAllVnsRequest"; -export * from "./types/tari-indexer-client/InspectSubstateRequest"; export * from "./types/tari-indexer-client/IndexerGetCommsStatsResponse"; -export * from "./types/tari-indexer-client/GetNonFungibleCountRequest"; -export * from "./types/tari-indexer-client/GetRelatedTransactionsResponse"; -export * from "./types/tari-indexer-client/IndexerAddPeerResponse"; -export * from "./types/tari-indexer-client/IndexerGetConnectionsResponse"; -export * from "./types/tari-indexer-client/GetNonFungiblesResponse"; +export * from "./types/tari-indexer-client/IndexerConnection"; +export * from "./types/tari-indexer-client/GetNonFungiblesRequest"; +export * from "./types/tari-indexer-client/IndexerAddPeerRequest"; export * from "./types/tari-indexer-client/GetRelatedTransactionsRequest"; -export * from "./types/tari-indexer-client/IndexerGetTransactionResultResponse"; +export * from "./types/tari-indexer-client/GetNonFungiblesResponse"; +export * from "./types/tari-indexer-client/GetTemplateDefinitionResponse"; +export * from "./types/tari-indexer-client/IndexerGetConnectionsResponse"; +export * from "./types/tari-indexer-client/IndexerSubmitTransactionRequest"; export * from "./types/tari-indexer-client/ListTemplatesResponse"; -export * from "./types/tari-indexer-client/IndexerGetTransactionResultRequest"; -export * from "./types/tari-indexer-client/ListSubstatesResponse"; -export * from "./types/tari-indexer-client/IndexerTransactionFinalizedResult"; +export * from "./types/tari-indexer-client/InspectSubstateResponse"; export * from "./types/tari-indexer-client/GetNonFungibleCollectionsResponse"; -export * from "./types/tari-indexer-client/IndexerSubmitTransactionResponse"; +export * from "./types/tari-indexer-client/IndexerGetSubstateRequest"; +export * from "./types/tari-indexer-client/IndexerGetEpochManagerStatsResponse"; +export * from "./types/tari-indexer-client/NonFungibleSubstate"; +export * from "./types/tari-indexer-client/GetNonFungibleCountResponse"; +export * from "./types/tari-indexer-client/ListTemplatesRequest"; +export * from "./types/tari-indexer-client/IndexerGetTransactionResultResponse"; export * from "./types/tari-indexer-client/IndexerConnectionDirection"; -export * from "./types/tari-indexer-client/ListSubstateItem"; +export * from "./types/tari-indexer-client/IndexerGetIdentityResponse"; +export * from "./types/tari-indexer-client/IndexerGetTransactionResultRequest"; +export * from "./types/tari-indexer-client/GetNonFungibleCountRequest"; diff --git a/bindings/dist/tari-indexer-client.js b/bindings/dist/tari-indexer-client.js index 633c07b9e..d6c53a6f9 100644 --- a/bindings/dist/tari-indexer-client.js +++ b/bindings/dist/tari-indexer-client.js @@ -1,36 +1,36 @@ // Copyright 2023 The Tari Project // SPDX-License-Identifier: BSD-3-Clause -export * from "./types/tari-indexer-client/IndexerGetEpochManagerStatsResponse"; -export * from "./types/tari-indexer-client/IndexerAddPeerRequest"; -export * from "./types/tari-indexer-client/NonFungibleSubstate"; -export * from "./types/tari-indexer-client/GetNonFungibleCountResponse"; -export * from "./types/tari-indexer-client/ListSubstatesRequest"; -export * from "./types/tari-indexer-client/IndexerGetIdentityResponse"; +export * from "./types/tari-indexer-client/IndexerSubmitTransactionResponse"; export * from "./types/tari-indexer-client/GetTemplateDefinitionRequest"; -export * from "./types/tari-indexer-client/IndexerGetSubstateRequest"; -export * from "./types/tari-indexer-client/GetTemplateDefinitionResponse"; -export * from "./types/tari-indexer-client/ListTemplatesRequest"; +export * from "./types/tari-indexer-client/ListSubstatesResponse"; +export * from "./types/tari-indexer-client/IndexerAddPeerResponse"; +export * from "./types/tari-indexer-client/InspectSubstateRequest"; +export * from "./types/tari-indexer-client/ListSubstateItem"; export * from "./types/tari-indexer-client/IndexerGetAllVnsResponse"; -export * from "./types/tari-indexer-client/GetNonFungiblesRequest"; +export * from "./types/tari-indexer-client/ListSubstatesRequest"; +export * from "./types/tari-indexer-client/GetRelatedTransactionsResponse"; +export * from "./types/tari-indexer-client/IndexerTransactionFinalizedResult"; export * from "./types/tari-indexer-client/IndexerGetSubstateResponse"; -export * from "./types/tari-indexer-client/IndexerSubmitTransactionRequest"; -export * from "./types/tari-indexer-client/IndexerConnection"; -export * from "./types/tari-indexer-client/InspectSubstateResponse"; export * from "./types/tari-indexer-client/IndexerGetAllVnsRequest"; -export * from "./types/tari-indexer-client/InspectSubstateRequest"; export * from "./types/tari-indexer-client/IndexerGetCommsStatsResponse"; -export * from "./types/tari-indexer-client/GetNonFungibleCountRequest"; -export * from "./types/tari-indexer-client/GetRelatedTransactionsResponse"; -export * from "./types/tari-indexer-client/IndexerAddPeerResponse"; -export * from "./types/tari-indexer-client/IndexerGetConnectionsResponse"; -export * from "./types/tari-indexer-client/GetNonFungiblesResponse"; +export * from "./types/tari-indexer-client/IndexerConnection"; +export * from "./types/tari-indexer-client/GetNonFungiblesRequest"; +export * from "./types/tari-indexer-client/IndexerAddPeerRequest"; export * from "./types/tari-indexer-client/GetRelatedTransactionsRequest"; -export * from "./types/tari-indexer-client/IndexerGetTransactionResultResponse"; +export * from "./types/tari-indexer-client/GetNonFungiblesResponse"; +export * from "./types/tari-indexer-client/GetTemplateDefinitionResponse"; +export * from "./types/tari-indexer-client/IndexerGetConnectionsResponse"; +export * from "./types/tari-indexer-client/IndexerSubmitTransactionRequest"; export * from "./types/tari-indexer-client/ListTemplatesResponse"; -export * from "./types/tari-indexer-client/IndexerGetTransactionResultRequest"; -export * from "./types/tari-indexer-client/ListSubstatesResponse"; -export * from "./types/tari-indexer-client/IndexerTransactionFinalizedResult"; +export * from "./types/tari-indexer-client/InspectSubstateResponse"; export * from "./types/tari-indexer-client/GetNonFungibleCollectionsResponse"; -export * from "./types/tari-indexer-client/IndexerSubmitTransactionResponse"; +export * from "./types/tari-indexer-client/IndexerGetSubstateRequest"; +export * from "./types/tari-indexer-client/IndexerGetEpochManagerStatsResponse"; +export * from "./types/tari-indexer-client/NonFungibleSubstate"; +export * from "./types/tari-indexer-client/GetNonFungibleCountResponse"; +export * from "./types/tari-indexer-client/ListTemplatesRequest"; +export * from "./types/tari-indexer-client/IndexerGetTransactionResultResponse"; export * from "./types/tari-indexer-client/IndexerConnectionDirection"; -export * from "./types/tari-indexer-client/ListSubstateItem"; +export * from "./types/tari-indexer-client/IndexerGetIdentityResponse"; +export * from "./types/tari-indexer-client/IndexerGetTransactionResultRequest"; +export * from "./types/tari-indexer-client/GetNonFungibleCountRequest"; diff --git a/bindings/dist/types/Command.d.ts b/bindings/dist/types/Command.d.ts index 1374b8885..358ce0e05 100644 --- a/bindings/dist/types/Command.d.ts +++ b/bindings/dist/types/Command.d.ts @@ -1,8 +1,6 @@ import type { EvictNodeAtom } from "./EvictNodeAtom"; import type { ForeignProposalAtom } from "./ForeignProposalAtom"; import type { MintConfidentialOutputAtom } from "./MintConfidentialOutputAtom"; -import type { ResumeNodeAtom } from "./ResumeNodeAtom"; -import type { SuspendNodeAtom } from "./SuspendNodeAtom"; import type { TransactionAtom } from "./TransactionAtom"; export type Command = { LocalOnly: TransactionAtom; @@ -24,10 +22,6 @@ export type Command = { ForeignProposal: ForeignProposalAtom; } | { MintConfidentialOutput: MintConfidentialOutputAtom; -} | { - SuspendNode: SuspendNodeAtom; -} | { - ResumeNode: ResumeNodeAtom; } | { EvictNode: EvictNodeAtom; } | "EndEpoch"; diff --git a/bindings/dist/types/validator-node-client/GetBaseLayerEpochChangesRequest.d.ts b/bindings/dist/types/validator-node-client/GetBaseLayerEpochChangesRequest.d.ts new file mode 100644 index 000000000..1f7d16e41 --- /dev/null +++ b/bindings/dist/types/validator-node-client/GetBaseLayerEpochChangesRequest.d.ts @@ -0,0 +1,5 @@ +import type { Epoch } from "../Epoch"; +export interface GetBaseLayerEpochChangesRequest { + start_epoch: Epoch; + end_epoch: Epoch; +} diff --git a/bindings/dist/types/validator-node-client/GetBaseLayerEpochChangesRequest.js b/bindings/dist/types/validator-node-client/GetBaseLayerEpochChangesRequest.js new file mode 100644 index 000000000..cb0ff5c3b --- /dev/null +++ b/bindings/dist/types/validator-node-client/GetBaseLayerEpochChangesRequest.js @@ -0,0 +1 @@ +export {}; diff --git a/bindings/dist/types/validator-node-client/GetBaseLayerEpochChangesResponse.d.ts b/bindings/dist/types/validator-node-client/GetBaseLayerEpochChangesResponse.d.ts new file mode 100644 index 000000000..e3817ecab --- /dev/null +++ b/bindings/dist/types/validator-node-client/GetBaseLayerEpochChangesResponse.d.ts @@ -0,0 +1,5 @@ +import type { Epoch } from "../Epoch"; +import type { ValidatorNodeChange } from "./ValidatorNodeChange"; +export interface GetBaseLayerEpochChangesResponse { + changes: Array<[Epoch, Array]>; +} diff --git a/bindings/dist/types/validator-node-client/GetBaseLayerEpochChangesResponse.js b/bindings/dist/types/validator-node-client/GetBaseLayerEpochChangesResponse.js new file mode 100644 index 000000000..cb0ff5c3b --- /dev/null +++ b/bindings/dist/types/validator-node-client/GetBaseLayerEpochChangesResponse.js @@ -0,0 +1 @@ +export {}; diff --git a/bindings/dist/types/validator-node-client/GetConsensusStatusResponse.d.ts b/bindings/dist/types/validator-node-client/GetConsensusStatusResponse.d.ts new file mode 100644 index 000000000..e3efd7468 --- /dev/null +++ b/bindings/dist/types/validator-node-client/GetConsensusStatusResponse.d.ts @@ -0,0 +1,7 @@ +import type { Epoch } from "../Epoch"; +import type { NodeHeight } from "../NodeHeight"; +export interface GetConsensusStatusResponse { + epoch: Epoch; + height: NodeHeight; + state: string; +} diff --git a/bindings/dist/types/validator-node-client/GetConsensusStatusResponse.js b/bindings/dist/types/validator-node-client/GetConsensusStatusResponse.js new file mode 100644 index 000000000..cb0ff5c3b --- /dev/null +++ b/bindings/dist/types/validator-node-client/GetConsensusStatusResponse.js @@ -0,0 +1 @@ +export {}; diff --git a/bindings/dist/types/validator-node-client/ValidatorNodeChange.d.ts b/bindings/dist/types/validator-node-client/ValidatorNodeChange.d.ts new file mode 100644 index 000000000..e2b24ea99 --- /dev/null +++ b/bindings/dist/types/validator-node-client/ValidatorNodeChange.d.ts @@ -0,0 +1,12 @@ +import type { Epoch } from "../Epoch"; +export type ValidatorNodeChange = { + Add: { + public_key: string; + activation_epoch: Epoch; + minimum_value_promise: bigint; + }; +} | { + Remove: { + public_key: string; + }; +}; diff --git a/bindings/dist/types/validator-node-client/ValidatorNodeChange.js b/bindings/dist/types/validator-node-client/ValidatorNodeChange.js new file mode 100644 index 000000000..cb0ff5c3b --- /dev/null +++ b/bindings/dist/types/validator-node-client/ValidatorNodeChange.js @@ -0,0 +1 @@ +export {}; diff --git a/bindings/dist/validator-node-client.d.ts b/bindings/dist/validator-node-client.d.ts index cfd875605..e6ca04d52 100644 --- a/bindings/dist/validator-node-client.d.ts +++ b/bindings/dist/validator-node-client.d.ts @@ -1,56 +1,60 @@ -export * from "./types/validator-node-client/GetCommitteeRequest"; -export * from "./types/validator-node-client/GetRecentTransactionsResponse"; -export * from "./types/validator-node-client/GetRecentTransactionsRequest"; -export * from "./types/validator-node-client/GetTemplatesRequest"; -export * from "./types/validator-node-client/GetBlocksCountResponse"; -export * from "./types/validator-node-client/VNAddPeerRequest"; -export * from "./types/validator-node-client/GetCommitteeResponse"; +export * from "./types/validator-node-client/ValidatorNodeChange"; export * from "./types/validator-node-client/VNSubmitTransactionRequest"; -export * from "./types/validator-node-client/VNConnectionDirection"; -export * from "./types/validator-node-client/VNAddPeerResponse"; -export * from "./types/validator-node-client/GetSubstatesByTransactionResponse"; -export * from "./types/validator-node-client/VNCommitteeShardInfo"; -export * from "./types/validator-node-client/VNFunctionDef"; -export * from "./types/validator-node-client/VNGetValidatorFeesResponse"; -export * from "./types/validator-node-client/VNGetAllVnsResponse"; -export * from "./types/validator-node-client/TemplateAbi"; -export * from "./types/validator-node-client/GetMempoolStatsResponse"; export * from "./types/validator-node-client/TemplateMetadata"; -export * from "./types/validator-node-client/GetBlockResponse"; -export * from "./types/validator-node-client/VNLogLevel"; -export * from "./types/validator-node-client/VNGetAllVnsRequest"; +export * from "./types/validator-node-client/GetFilteredBlocksCountRequest"; export * from "./types/validator-node-client/VNLogEntry"; export * from "./types/validator-node-client/GetShardKeyRequest"; -export * from "./types/validator-node-client/GetBlockRequest"; +export * from "./types/validator-node-client/VNGetTransactionResultResponse"; export * from "./types/validator-node-client/VNSubmitTransactionResponse"; -export * from "./types/validator-node-client/DryRunTransactionFinalizeResult"; -export * from "./types/validator-node-client/GetTransactionResponse"; -export * from "./types/validator-node-client/GetStateResponse"; -export * from "./types/validator-node-client/VNGetSubstateRequest"; -export * from "./types/validator-node-client/VNGetSubstateResponse"; -export * from "./types/validator-node-client/ListBlocksResponse"; -export * from "./types/validator-node-client/SubstateStatus"; -export * from "./types/validator-node-client/ValidatorNode"; -export * from "./types/validator-node-client/GetFilteredBlocksCountRequest"; -export * from "./types/validator-node-client/ListBlocksRequest"; -export * from "./types/validator-node-client/GetEpochManagerStatsResponse"; export * from "./types/validator-node-client/GetTxPoolResponse"; -export * from "./types/validator-node-client/VNConnection"; export * from "./types/validator-node-client/GetTemplateResponse"; -export * from "./types/validator-node-client/ValidatorFee"; -export * from "./types/validator-node-client/VNGetConnectionsResponse"; -export * from "./types/validator-node-client/VNGetCommsStatsResponse"; -export * from "./types/validator-node-client/GetTemplateRequest"; +export * from "./types/validator-node-client/GetBlocksCountResponse"; +export * from "./types/validator-node-client/VNGetValidatorFeesRequest"; +export * from "./types/validator-node-client/GetSubstatesByTransactionResponse"; +export * from "./types/validator-node-client/VNConnectionDirection"; +export * from "./types/validator-node-client/VNAddPeerRequest"; +export * from "./types/validator-node-client/GetTemplatesResponse"; +export * from "./types/validator-node-client/GetTransactionRequest"; export * from "./types/validator-node-client/GetStateRequest"; +export * from "./types/validator-node-client/VNGetIdentityResponse"; +export * from "./types/validator-node-client/VNFunctionDef"; export * from "./types/validator-node-client/GetBlocksRequest"; -export * from "./types/validator-node-client/VNGetTransactionResultRequest"; -export * from "./types/validator-node-client/GetTransactionRequest"; -export * from "./types/validator-node-client/GetTemplatesResponse"; -export * from "./types/validator-node-client/VNGetTransactionResultResponse"; -export * from "./types/validator-node-client/VNArgDef"; +export * from "./types/validator-node-client/GetTemplateRequest"; export * from "./types/validator-node-client/GetShardKeyResponse"; -export * from "./types/validator-node-client/GetBlocksResponse"; -export * from "./types/validator-node-client/VNGetIdentityResponse"; +export * from "./types/validator-node-client/GetBaseLayerEpochChangesResponse"; export * from "./types/validator-node-client/GetSubstatesByTransactionRequest"; +export * from "./types/validator-node-client/VNGetCommsStatsResponse"; +export * from "./types/validator-node-client/GetTransactionResponse"; +export * from "./types/validator-node-client/GetCommitteeResponse"; +export * from "./types/validator-node-client/VNGetAllVnsRequest"; +export * from "./types/validator-node-client/GetCommitteeRequest"; +export * from "./types/validator-node-client/DryRunTransactionFinalizeResult"; +export * from "./types/validator-node-client/VNGetValidatorFeesResponse"; +export * from "./types/validator-node-client/GetStateResponse"; +export * from "./types/validator-node-client/GetBaseLayerEpochChangesRequest"; +export * from "./types/validator-node-client/SubstateStatus"; +export * from "./types/validator-node-client/GetConsensusStatusResponse"; +export * from "./types/validator-node-client/GetBlocksResponse"; +export * from "./types/validator-node-client/ListBlocksResponse"; +export * from "./types/validator-node-client/GetBlockRequest"; +export * from "./types/validator-node-client/VNGetTransactionResultRequest"; +export * from "./types/validator-node-client/GetRecentTransactionsRequest"; +export * from "./types/validator-node-client/ValidatorFee"; +export * from "./types/validator-node-client/VNLogLevel"; +export * from "./types/validator-node-client/GetRecentTransactionsResponse"; +export * from "./types/validator-node-client/VNAddPeerResponse"; +export * from "./types/validator-node-client/VNConnection"; +export * from "./types/validator-node-client/ValidatorNode"; +export * from "./types/validator-node-client/VNGetConnectionsResponse"; +export * from "./types/validator-node-client/ListBlocksRequest"; export * from "./types/validator-node-client/GetNetworkCommitteeResponse"; -export * from "./types/validator-node-client/VNGetValidatorFeesRequest"; +export * from "./types/validator-node-client/VNGetSubstateRequest"; +export * from "./types/validator-node-client/GetMempoolStatsResponse"; +export * from "./types/validator-node-client/TemplateAbi"; +export * from "./types/validator-node-client/GetTemplatesRequest"; +export * from "./types/validator-node-client/VNGetSubstateResponse"; +export * from "./types/validator-node-client/VNGetAllVnsResponse"; +export * from "./types/validator-node-client/VNArgDef"; +export * from "./types/validator-node-client/GetEpochManagerStatsResponse"; +export * from "./types/validator-node-client/GetBlockResponse"; +export * from "./types/validator-node-client/VNCommitteeShardInfo"; diff --git a/bindings/dist/validator-node-client.js b/bindings/dist/validator-node-client.js index 477e5dd45..5ea2ff7f9 100644 --- a/bindings/dist/validator-node-client.js +++ b/bindings/dist/validator-node-client.js @@ -1,58 +1,62 @@ // Copyright 2023 The Tari Project // SPDX-License-Identifier: BSD-3-Clause -export * from "./types/validator-node-client/GetCommitteeRequest"; -export * from "./types/validator-node-client/GetRecentTransactionsResponse"; -export * from "./types/validator-node-client/GetRecentTransactionsRequest"; -export * from "./types/validator-node-client/GetTemplatesRequest"; -export * from "./types/validator-node-client/GetBlocksCountResponse"; -export * from "./types/validator-node-client/VNAddPeerRequest"; -export * from "./types/validator-node-client/GetCommitteeResponse"; +export * from "./types/validator-node-client/ValidatorNodeChange"; export * from "./types/validator-node-client/VNSubmitTransactionRequest"; -export * from "./types/validator-node-client/VNConnectionDirection"; -export * from "./types/validator-node-client/VNAddPeerResponse"; -export * from "./types/validator-node-client/GetSubstatesByTransactionResponse"; -export * from "./types/validator-node-client/VNCommitteeShardInfo"; -export * from "./types/validator-node-client/VNFunctionDef"; -export * from "./types/validator-node-client/VNGetValidatorFeesResponse"; -export * from "./types/validator-node-client/VNGetAllVnsResponse"; -export * from "./types/validator-node-client/TemplateAbi"; -export * from "./types/validator-node-client/GetMempoolStatsResponse"; export * from "./types/validator-node-client/TemplateMetadata"; -export * from "./types/validator-node-client/GetBlockResponse"; -export * from "./types/validator-node-client/VNLogLevel"; -export * from "./types/validator-node-client/VNGetAllVnsRequest"; +export * from "./types/validator-node-client/GetFilteredBlocksCountRequest"; export * from "./types/validator-node-client/VNLogEntry"; export * from "./types/validator-node-client/GetShardKeyRequest"; -export * from "./types/validator-node-client/GetBlockRequest"; +export * from "./types/validator-node-client/VNGetTransactionResultResponse"; export * from "./types/validator-node-client/VNSubmitTransactionResponse"; -export * from "./types/validator-node-client/DryRunTransactionFinalizeResult"; -export * from "./types/validator-node-client/GetTransactionResponse"; -export * from "./types/validator-node-client/GetStateResponse"; -export * from "./types/validator-node-client/VNGetSubstateRequest"; -export * from "./types/validator-node-client/VNGetSubstateResponse"; -export * from "./types/validator-node-client/ListBlocksResponse"; -export * from "./types/validator-node-client/SubstateStatus"; -export * from "./types/validator-node-client/ValidatorNode"; -export * from "./types/validator-node-client/GetFilteredBlocksCountRequest"; -export * from "./types/validator-node-client/ListBlocksRequest"; -export * from "./types/validator-node-client/GetEpochManagerStatsResponse"; export * from "./types/validator-node-client/GetTxPoolResponse"; -export * from "./types/validator-node-client/VNConnection"; export * from "./types/validator-node-client/GetTemplateResponse"; -export * from "./types/validator-node-client/ValidatorFee"; -export * from "./types/validator-node-client/VNGetConnectionsResponse"; -export * from "./types/validator-node-client/VNGetCommsStatsResponse"; -export * from "./types/validator-node-client/GetTemplateRequest"; +export * from "./types/validator-node-client/GetBlocksCountResponse"; +export * from "./types/validator-node-client/VNGetValidatorFeesRequest"; +export * from "./types/validator-node-client/GetSubstatesByTransactionResponse"; +export * from "./types/validator-node-client/VNConnectionDirection"; +export * from "./types/validator-node-client/VNAddPeerRequest"; +export * from "./types/validator-node-client/GetTemplatesResponse"; +export * from "./types/validator-node-client/GetTransactionRequest"; export * from "./types/validator-node-client/GetStateRequest"; +export * from "./types/validator-node-client/VNGetIdentityResponse"; +export * from "./types/validator-node-client/VNFunctionDef"; export * from "./types/validator-node-client/GetBlocksRequest"; -export * from "./types/validator-node-client/VNGetTransactionResultRequest"; -export * from "./types/validator-node-client/GetTransactionRequest"; -export * from "./types/validator-node-client/GetTemplatesResponse"; -export * from "./types/validator-node-client/VNGetTransactionResultResponse"; -export * from "./types/validator-node-client/VNArgDef"; +export * from "./types/validator-node-client/GetTemplateRequest"; export * from "./types/validator-node-client/GetShardKeyResponse"; -export * from "./types/validator-node-client/GetBlocksResponse"; -export * from "./types/validator-node-client/VNGetIdentityResponse"; +export * from "./types/validator-node-client/GetBaseLayerEpochChangesResponse"; export * from "./types/validator-node-client/GetSubstatesByTransactionRequest"; +export * from "./types/validator-node-client/VNGetCommsStatsResponse"; +export * from "./types/validator-node-client/GetTransactionResponse"; +export * from "./types/validator-node-client/GetCommitteeResponse"; +export * from "./types/validator-node-client/VNGetAllVnsRequest"; +export * from "./types/validator-node-client/GetCommitteeRequest"; +export * from "./types/validator-node-client/DryRunTransactionFinalizeResult"; +export * from "./types/validator-node-client/VNGetValidatorFeesResponse"; +export * from "./types/validator-node-client/GetStateResponse"; +export * from "./types/validator-node-client/GetBaseLayerEpochChangesRequest"; +export * from "./types/validator-node-client/SubstateStatus"; +export * from "./types/validator-node-client/GetConsensusStatusResponse"; +export * from "./types/validator-node-client/GetBlocksResponse"; +export * from "./types/validator-node-client/ListBlocksResponse"; +export * from "./types/validator-node-client/GetBlockRequest"; +export * from "./types/validator-node-client/VNGetTransactionResultRequest"; +export * from "./types/validator-node-client/GetRecentTransactionsRequest"; +export * from "./types/validator-node-client/ValidatorFee"; +export * from "./types/validator-node-client/VNLogLevel"; +export * from "./types/validator-node-client/GetRecentTransactionsResponse"; +export * from "./types/validator-node-client/VNAddPeerResponse"; +export * from "./types/validator-node-client/VNConnection"; +export * from "./types/validator-node-client/ValidatorNode"; +export * from "./types/validator-node-client/VNGetConnectionsResponse"; +export * from "./types/validator-node-client/ListBlocksRequest"; export * from "./types/validator-node-client/GetNetworkCommitteeResponse"; -export * from "./types/validator-node-client/VNGetValidatorFeesRequest"; +export * from "./types/validator-node-client/VNGetSubstateRequest"; +export * from "./types/validator-node-client/GetMempoolStatsResponse"; +export * from "./types/validator-node-client/TemplateAbi"; +export * from "./types/validator-node-client/GetTemplatesRequest"; +export * from "./types/validator-node-client/VNGetSubstateResponse"; +export * from "./types/validator-node-client/VNGetAllVnsResponse"; +export * from "./types/validator-node-client/VNArgDef"; +export * from "./types/validator-node-client/GetEpochManagerStatsResponse"; +export * from "./types/validator-node-client/GetBlockResponse"; +export * from "./types/validator-node-client/VNCommitteeShardInfo"; diff --git a/bindings/dist/wallet-daemon-client.d.ts b/bindings/dist/wallet-daemon-client.d.ts index 800a672e4..72464d0b9 100644 --- a/bindings/dist/wallet-daemon-client.d.ts +++ b/bindings/dist/wallet-daemon-client.d.ts @@ -1,89 +1,89 @@ -export * from "./types/wallet-daemon-client/AccountsListResponse"; -export * from "./types/wallet-daemon-client/RevealFundsRequest"; -export * from "./types/wallet-daemon-client/ClaimBurnResponse"; -export * from "./types/wallet-daemon-client/KeysSetActiveRequest"; export * from "./types/wallet-daemon-client/WalletSubstateRecord"; -export * from "./types/wallet-daemon-client/AccountsGetBalancesResponse"; -export * from "./types/wallet-daemon-client/SubstatesGetResponse"; -export * from "./types/wallet-daemon-client/ListAccountNftRequest"; -export * from "./types/wallet-daemon-client/RevealFundsResponse"; -export * from "./types/wallet-daemon-client/AccountSetDefaultRequest"; -export * from "./types/wallet-daemon-client/GetAccountNftRequest"; -export * from "./types/wallet-daemon-client/TransactionGetAllResponse"; -export * from "./types/wallet-daemon-client/TransactionGetRequest"; -export * from "./types/wallet-daemon-client/KeyBranch"; -export * from "./types/wallet-daemon-client/AuthLoginAcceptRequest"; -export * from "./types/wallet-daemon-client/AccountSetDefaultResponse"; -export * from "./types/wallet-daemon-client/SubstatesListResponse"; +export * from "./types/wallet-daemon-client/ProofsFinalizeResponse"; +export * from "./types/wallet-daemon-client/CallInstructionRequest"; +export * from "./types/wallet-daemon-client/AuthLoginAcceptResponse"; +export * from "./types/wallet-daemon-client/AccountsListRequest"; +export * from "./types/wallet-daemon-client/AuthGetAllJwtResponse"; +export * from "./types/wallet-daemon-client/AuthLoginResponse"; +export * from "./types/wallet-daemon-client/GetValidatorFeesRequest"; export * from "./types/wallet-daemon-client/AccountGetDefaultRequest"; -export * from "./types/wallet-daemon-client/KeysListResponse"; -export * from "./types/wallet-daemon-client/ProofsGenerateResponse"; +export * from "./types/wallet-daemon-client/AuthGetAllJwtRequest"; +export * from "./types/wallet-daemon-client/KeyBranch"; +export * from "./types/wallet-daemon-client/AccountGetResponse"; +export * from "./types/wallet-daemon-client/SettingsSetRequest"; +export * from "./types/wallet-daemon-client/GetValidatorFeesResponse"; export * from "./types/wallet-daemon-client/TransactionGetAllRequest"; +export * from "./types/wallet-daemon-client/RevealFundsRequest"; +export * from "./types/wallet-daemon-client/AuthLoginDenyResponse"; +export * from "./types/wallet-daemon-client/AuthLoginDenyRequest"; +export * from "./types/wallet-daemon-client/TransactionSubmitResponse"; +export * from "./types/wallet-daemon-client/ProofsGenerateResponse"; +export * from "./types/wallet-daemon-client/ClaimValidatorFeesRequest"; +export * from "./types/wallet-daemon-client/AuthLoginRequest"; +export * from "./types/wallet-daemon-client/ListAccountNftRequest"; +export * from "./types/wallet-daemon-client/TransactionGetRequest"; +export * from "./types/wallet-daemon-client/AuthRevokeTokenResponse"; +export * from "./types/wallet-daemon-client/ProofsFinalizeRequest"; +export * from "./types/wallet-daemon-client/AccountsTransferRequest"; +export * from "./types/wallet-daemon-client/SettingsSetResponse"; +export * from "./types/wallet-daemon-client/KeysListRequest"; export * from "./types/wallet-daemon-client/AccountsTransferResponse"; -export * from "./types/wallet-daemon-client/AuthLoginResponse"; +export * from "./types/wallet-daemon-client/TransactionGetResultResponse"; export * from "./types/wallet-daemon-client/ClaimBurnRequest"; -export * from "./types/wallet-daemon-client/BalanceEntry"; -export * from "./types/wallet-daemon-client/KeysListRequest"; +export * from "./types/wallet-daemon-client/KeysListResponse"; export * from "./types/wallet-daemon-client/SubstatesGetRequest"; -export * from "./types/wallet-daemon-client/ProofsFinalizeResponse"; +export * from "./types/wallet-daemon-client/TransactionSubmitRequest"; +export * from "./types/wallet-daemon-client/AccountsGetBalancesResponse"; +export * from "./types/wallet-daemon-client/TransactionGetAllResponse"; +export * from "./types/wallet-daemon-client/AccountsCreateFreeTestCoinsResponse"; +export * from "./types/wallet-daemon-client/ConfidentialTransferResponse"; +export * from "./types/wallet-daemon-client/TransactionGetResponse"; +export * from "./types/wallet-daemon-client/SubstatesGetResponse"; +export * from "./types/wallet-daemon-client/GetAccountNftRequest"; export * from "./types/wallet-daemon-client/AuthRevokeTokenRequest"; -export * from "./types/wallet-daemon-client/TransactionWaitResultRequest"; -export * from "./types/wallet-daemon-client/TransactionSubmitResponse"; -export * from "./types/wallet-daemon-client/AccountsCreateRequest"; -export * from "./types/wallet-daemon-client/CallInstructionRequest"; -export * from "./types/wallet-daemon-client/WebRtcStartRequest"; +export * from "./types/wallet-daemon-client/ProofsGenerateRequest"; +export * from "./types/wallet-daemon-client/RevealFundsResponse"; +export * from "./types/wallet-daemon-client/AccountsInvokeResponse"; +export * from "./types/wallet-daemon-client/AccountsListResponse"; export * from "./types/wallet-daemon-client/WebRtcStartResponse"; -export * from "./types/wallet-daemon-client/TransactionSubmitDryRunRequest"; -export * from "./types/wallet-daemon-client/MintAccountNftResponse"; +export * from "./types/wallet-daemon-client/TransactionGetResultRequest"; export * from "./types/wallet-daemon-client/ProofsCancelResponse"; -export * from "./types/wallet-daemon-client/AccountGetResponse"; -export * from "./types/wallet-daemon-client/ClaimValidatorFeesRequest"; -export * from "./types/wallet-daemon-client/AuthRevokeTokenResponse"; -export * from "./types/wallet-daemon-client/AccountsInvokeRequest"; -export * from "./types/wallet-daemon-client/WebRtcStart"; -export * from "./types/wallet-daemon-client/TransactionWaitResultResponse"; -export * from "./types/wallet-daemon-client/GetValidatorFeesRequest"; +export * from "./types/wallet-daemon-client/AccountsCreateRequest"; +export * from "./types/wallet-daemon-client/MintAccountNftRequest"; +export * from "./types/wallet-daemon-client/TransactionClaimBurnResponse"; +export * from "./types/wallet-daemon-client/TransactionWaitResultRequest"; +export * from "./types/wallet-daemon-client/ClaimValidatorFeesResponse"; export * from "./types/wallet-daemon-client/ConfidentialCreateOutputProofRequest"; -export * from "./types/wallet-daemon-client/KeysCreateResponse"; -export * from "./types/wallet-daemon-client/AuthLoginDenyRequest"; -export * from "./types/wallet-daemon-client/ProofsFinalizeRequest"; -export * from "./types/wallet-daemon-client/ProofsCancelRequest"; +export * from "./types/wallet-daemon-client/KeysCreateRequest"; export * from "./types/wallet-daemon-client/SettingsGetResponse"; -export * from "./types/wallet-daemon-client/ConfidentialViewVaultBalanceRequest"; -export * from "./types/wallet-daemon-client/GetValidatorFeesResponse"; -export * from "./types/wallet-daemon-client/TransactionGetResponse"; -export * from "./types/wallet-daemon-client/TransactionSubmitRequest"; -export * from "./types/wallet-daemon-client/ListAccountNftResponse"; -export * from "./types/wallet-daemon-client/AccountsInvokeResponse"; -export * from "./types/wallet-daemon-client/AccountsListRequest"; -export * from "./types/wallet-daemon-client/AuthLoginAcceptResponse"; export * from "./types/wallet-daemon-client/TransactionSubmitDryRunResponse"; -export * from "./types/wallet-daemon-client/ConfidentialCreateOutputProofResponse"; -export * from "./types/wallet-daemon-client/TemplatesGetRequest"; +export * from "./types/wallet-daemon-client/ClaimBurnResponse"; +export * from "./types/wallet-daemon-client/WebRtcStartRequest"; export * from "./types/wallet-daemon-client/ConfidentialViewVaultBalanceResponse"; -export * from "./types/wallet-daemon-client/SettingsSetRequest"; -export * from "./types/wallet-daemon-client/MintAccountNftRequest"; -export * from "./types/wallet-daemon-client/TransactionClaimBurnResponse"; -export * from "./types/wallet-daemon-client/AuthGetAllJwtRequest"; -export * from "./types/wallet-daemon-client/ClaimValidatorFeesResponse"; -export * from "./types/wallet-daemon-client/ConfidentialTransferResponse"; +export * from "./types/wallet-daemon-client/WebRtcStart"; +export * from "./types/wallet-daemon-client/AccountSetDefaultRequest"; +export * from "./types/wallet-daemon-client/ConfidentialCreateOutputProofResponse"; export * from "./types/wallet-daemon-client/TemplatesGetResponse"; -export * from "./types/wallet-daemon-client/AccountsTransferRequest"; -export * from "./types/wallet-daemon-client/AuthLoginRequest"; -export * from "./types/wallet-daemon-client/AuthGetAllJwtResponse"; -export * from "./types/wallet-daemon-client/AccountsCreateFreeTestCoinsRequest"; -export * from "./types/wallet-daemon-client/ConfidentialTransferRequest"; -export * from "./types/wallet-daemon-client/SettingsSetResponse"; -export * from "./types/wallet-daemon-client/AccountsCreateFreeTestCoinsResponse"; -export * from "./types/wallet-daemon-client/AccountGetRequest"; -export * from "./types/wallet-daemon-client/KeysCreateRequest"; -export * from "./types/wallet-daemon-client/ProofsGenerateRequest"; -export * from "./types/wallet-daemon-client/TransactionGetResultResponse"; -export * from "./types/wallet-daemon-client/KeysSetActiveResponse"; -export * from "./types/wallet-daemon-client/AuthLoginDenyResponse"; -export * from "./types/wallet-daemon-client/TransactionGetResultRequest"; -export * from "./types/wallet-daemon-client/AccountsCreateResponse"; +export * from "./types/wallet-daemon-client/ListAccountNftResponse"; export * from "./types/wallet-daemon-client/AccountsGetBalancesRequest"; +export * from "./types/wallet-daemon-client/MintAccountNftResponse"; +export * from "./types/wallet-daemon-client/AccountsCreateFreeTestCoinsRequest"; +export * from "./types/wallet-daemon-client/KeysCreateResponse"; export * from "./types/wallet-daemon-client/AccountInfo"; export * from "./types/wallet-daemon-client/SubstatesListRequest"; +export * from "./types/wallet-daemon-client/BalanceEntry"; +export * from "./types/wallet-daemon-client/TemplatesGetRequest"; +export * from "./types/wallet-daemon-client/AccountsInvokeRequest"; +export * from "./types/wallet-daemon-client/ProofsCancelRequest"; +export * from "./types/wallet-daemon-client/AccountSetDefaultResponse"; +export * from "./types/wallet-daemon-client/SubstatesListResponse"; +export * from "./types/wallet-daemon-client/KeysSetActiveResponse"; export * from "./types/wallet-daemon-client/ComponentAddressOrName"; +export * from "./types/wallet-daemon-client/AuthLoginAcceptRequest"; +export * from "./types/wallet-daemon-client/TransactionSubmitDryRunRequest"; +export * from "./types/wallet-daemon-client/KeysSetActiveRequest"; +export * from "./types/wallet-daemon-client/ConfidentialViewVaultBalanceRequest"; +export * from "./types/wallet-daemon-client/ConfidentialTransferRequest"; +export * from "./types/wallet-daemon-client/AccountsCreateResponse"; +export * from "./types/wallet-daemon-client/TransactionWaitResultResponse"; +export * from "./types/wallet-daemon-client/AccountGetRequest"; diff --git a/bindings/dist/wallet-daemon-client.js b/bindings/dist/wallet-daemon-client.js index e579fd71b..389f4730a 100644 --- a/bindings/dist/wallet-daemon-client.js +++ b/bindings/dist/wallet-daemon-client.js @@ -1,91 +1,91 @@ // Copyright 2023 The Tari Project // SPDX-License-Identifier: BSD-3-Clause -export * from "./types/wallet-daemon-client/AccountsListResponse"; -export * from "./types/wallet-daemon-client/RevealFundsRequest"; -export * from "./types/wallet-daemon-client/ClaimBurnResponse"; -export * from "./types/wallet-daemon-client/KeysSetActiveRequest"; export * from "./types/wallet-daemon-client/WalletSubstateRecord"; -export * from "./types/wallet-daemon-client/AccountsGetBalancesResponse"; -export * from "./types/wallet-daemon-client/SubstatesGetResponse"; -export * from "./types/wallet-daemon-client/ListAccountNftRequest"; -export * from "./types/wallet-daemon-client/RevealFundsResponse"; -export * from "./types/wallet-daemon-client/AccountSetDefaultRequest"; -export * from "./types/wallet-daemon-client/GetAccountNftRequest"; -export * from "./types/wallet-daemon-client/TransactionGetAllResponse"; -export * from "./types/wallet-daemon-client/TransactionGetRequest"; -export * from "./types/wallet-daemon-client/KeyBranch"; -export * from "./types/wallet-daemon-client/AuthLoginAcceptRequest"; -export * from "./types/wallet-daemon-client/AccountSetDefaultResponse"; -export * from "./types/wallet-daemon-client/SubstatesListResponse"; +export * from "./types/wallet-daemon-client/ProofsFinalizeResponse"; +export * from "./types/wallet-daemon-client/CallInstructionRequest"; +export * from "./types/wallet-daemon-client/AuthLoginAcceptResponse"; +export * from "./types/wallet-daemon-client/AccountsListRequest"; +export * from "./types/wallet-daemon-client/AuthGetAllJwtResponse"; +export * from "./types/wallet-daemon-client/AuthLoginResponse"; +export * from "./types/wallet-daemon-client/GetValidatorFeesRequest"; export * from "./types/wallet-daemon-client/AccountGetDefaultRequest"; -export * from "./types/wallet-daemon-client/KeysListResponse"; -export * from "./types/wallet-daemon-client/ProofsGenerateResponse"; +export * from "./types/wallet-daemon-client/AuthGetAllJwtRequest"; +export * from "./types/wallet-daemon-client/KeyBranch"; +export * from "./types/wallet-daemon-client/AccountGetResponse"; +export * from "./types/wallet-daemon-client/SettingsSetRequest"; +export * from "./types/wallet-daemon-client/GetValidatorFeesResponse"; export * from "./types/wallet-daemon-client/TransactionGetAllRequest"; +export * from "./types/wallet-daemon-client/RevealFundsRequest"; +export * from "./types/wallet-daemon-client/AuthLoginDenyResponse"; +export * from "./types/wallet-daemon-client/AuthLoginDenyRequest"; +export * from "./types/wallet-daemon-client/TransactionSubmitResponse"; +export * from "./types/wallet-daemon-client/ProofsGenerateResponse"; +export * from "./types/wallet-daemon-client/ClaimValidatorFeesRequest"; +export * from "./types/wallet-daemon-client/AuthLoginRequest"; +export * from "./types/wallet-daemon-client/ListAccountNftRequest"; +export * from "./types/wallet-daemon-client/TransactionGetRequest"; +export * from "./types/wallet-daemon-client/AuthRevokeTokenResponse"; +export * from "./types/wallet-daemon-client/ProofsFinalizeRequest"; +export * from "./types/wallet-daemon-client/AccountsTransferRequest"; +export * from "./types/wallet-daemon-client/SettingsSetResponse"; +export * from "./types/wallet-daemon-client/KeysListRequest"; export * from "./types/wallet-daemon-client/AccountsTransferResponse"; -export * from "./types/wallet-daemon-client/AuthLoginResponse"; +export * from "./types/wallet-daemon-client/TransactionGetResultResponse"; export * from "./types/wallet-daemon-client/ClaimBurnRequest"; -export * from "./types/wallet-daemon-client/BalanceEntry"; -export * from "./types/wallet-daemon-client/KeysListRequest"; +export * from "./types/wallet-daemon-client/KeysListResponse"; export * from "./types/wallet-daemon-client/SubstatesGetRequest"; -export * from "./types/wallet-daemon-client/ProofsFinalizeResponse"; +export * from "./types/wallet-daemon-client/TransactionSubmitRequest"; +export * from "./types/wallet-daemon-client/AccountsGetBalancesResponse"; +export * from "./types/wallet-daemon-client/TransactionGetAllResponse"; +export * from "./types/wallet-daemon-client/AccountsCreateFreeTestCoinsResponse"; +export * from "./types/wallet-daemon-client/ConfidentialTransferResponse"; +export * from "./types/wallet-daemon-client/TransactionGetResponse"; +export * from "./types/wallet-daemon-client/SubstatesGetResponse"; +export * from "./types/wallet-daemon-client/GetAccountNftRequest"; export * from "./types/wallet-daemon-client/AuthRevokeTokenRequest"; -export * from "./types/wallet-daemon-client/TransactionWaitResultRequest"; -export * from "./types/wallet-daemon-client/TransactionSubmitResponse"; -export * from "./types/wallet-daemon-client/AccountsCreateRequest"; -export * from "./types/wallet-daemon-client/CallInstructionRequest"; -export * from "./types/wallet-daemon-client/WebRtcStartRequest"; +export * from "./types/wallet-daemon-client/ProofsGenerateRequest"; +export * from "./types/wallet-daemon-client/RevealFundsResponse"; +export * from "./types/wallet-daemon-client/AccountsInvokeResponse"; +export * from "./types/wallet-daemon-client/AccountsListResponse"; export * from "./types/wallet-daemon-client/WebRtcStartResponse"; -export * from "./types/wallet-daemon-client/TransactionSubmitDryRunRequest"; -export * from "./types/wallet-daemon-client/MintAccountNftResponse"; +export * from "./types/wallet-daemon-client/TransactionGetResultRequest"; export * from "./types/wallet-daemon-client/ProofsCancelResponse"; -export * from "./types/wallet-daemon-client/AccountGetResponse"; -export * from "./types/wallet-daemon-client/ClaimValidatorFeesRequest"; -export * from "./types/wallet-daemon-client/AuthRevokeTokenResponse"; -export * from "./types/wallet-daemon-client/AccountsInvokeRequest"; -export * from "./types/wallet-daemon-client/WebRtcStart"; -export * from "./types/wallet-daemon-client/TransactionWaitResultResponse"; -export * from "./types/wallet-daemon-client/GetValidatorFeesRequest"; +export * from "./types/wallet-daemon-client/AccountsCreateRequest"; +export * from "./types/wallet-daemon-client/MintAccountNftRequest"; +export * from "./types/wallet-daemon-client/TransactionClaimBurnResponse"; +export * from "./types/wallet-daemon-client/TransactionWaitResultRequest"; +export * from "./types/wallet-daemon-client/ClaimValidatorFeesResponse"; export * from "./types/wallet-daemon-client/ConfidentialCreateOutputProofRequest"; -export * from "./types/wallet-daemon-client/KeysCreateResponse"; -export * from "./types/wallet-daemon-client/AuthLoginDenyRequest"; -export * from "./types/wallet-daemon-client/ProofsFinalizeRequest"; -export * from "./types/wallet-daemon-client/ProofsCancelRequest"; +export * from "./types/wallet-daemon-client/KeysCreateRequest"; export * from "./types/wallet-daemon-client/SettingsGetResponse"; -export * from "./types/wallet-daemon-client/ConfidentialViewVaultBalanceRequest"; -export * from "./types/wallet-daemon-client/GetValidatorFeesResponse"; -export * from "./types/wallet-daemon-client/TransactionGetResponse"; -export * from "./types/wallet-daemon-client/TransactionSubmitRequest"; -export * from "./types/wallet-daemon-client/ListAccountNftResponse"; -export * from "./types/wallet-daemon-client/AccountsInvokeResponse"; -export * from "./types/wallet-daemon-client/AccountsListRequest"; -export * from "./types/wallet-daemon-client/AuthLoginAcceptResponse"; export * from "./types/wallet-daemon-client/TransactionSubmitDryRunResponse"; -export * from "./types/wallet-daemon-client/ConfidentialCreateOutputProofResponse"; -export * from "./types/wallet-daemon-client/TemplatesGetRequest"; +export * from "./types/wallet-daemon-client/ClaimBurnResponse"; +export * from "./types/wallet-daemon-client/WebRtcStartRequest"; export * from "./types/wallet-daemon-client/ConfidentialViewVaultBalanceResponse"; -export * from "./types/wallet-daemon-client/SettingsSetRequest"; -export * from "./types/wallet-daemon-client/MintAccountNftRequest"; -export * from "./types/wallet-daemon-client/TransactionClaimBurnResponse"; -export * from "./types/wallet-daemon-client/AuthGetAllJwtRequest"; -export * from "./types/wallet-daemon-client/ClaimValidatorFeesResponse"; -export * from "./types/wallet-daemon-client/ConfidentialTransferResponse"; +export * from "./types/wallet-daemon-client/WebRtcStart"; +export * from "./types/wallet-daemon-client/AccountSetDefaultRequest"; +export * from "./types/wallet-daemon-client/ConfidentialCreateOutputProofResponse"; export * from "./types/wallet-daemon-client/TemplatesGetResponse"; -export * from "./types/wallet-daemon-client/AccountsTransferRequest"; -export * from "./types/wallet-daemon-client/AuthLoginRequest"; -export * from "./types/wallet-daemon-client/AuthGetAllJwtResponse"; -export * from "./types/wallet-daemon-client/AccountsCreateFreeTestCoinsRequest"; -export * from "./types/wallet-daemon-client/ConfidentialTransferRequest"; -export * from "./types/wallet-daemon-client/SettingsSetResponse"; -export * from "./types/wallet-daemon-client/AccountsCreateFreeTestCoinsResponse"; -export * from "./types/wallet-daemon-client/AccountGetRequest"; -export * from "./types/wallet-daemon-client/KeysCreateRequest"; -export * from "./types/wallet-daemon-client/ProofsGenerateRequest"; -export * from "./types/wallet-daemon-client/TransactionGetResultResponse"; -export * from "./types/wallet-daemon-client/KeysSetActiveResponse"; -export * from "./types/wallet-daemon-client/AuthLoginDenyResponse"; -export * from "./types/wallet-daemon-client/TransactionGetResultRequest"; -export * from "./types/wallet-daemon-client/AccountsCreateResponse"; +export * from "./types/wallet-daemon-client/ListAccountNftResponse"; export * from "./types/wallet-daemon-client/AccountsGetBalancesRequest"; +export * from "./types/wallet-daemon-client/MintAccountNftResponse"; +export * from "./types/wallet-daemon-client/AccountsCreateFreeTestCoinsRequest"; +export * from "./types/wallet-daemon-client/KeysCreateResponse"; export * from "./types/wallet-daemon-client/AccountInfo"; export * from "./types/wallet-daemon-client/SubstatesListRequest"; +export * from "./types/wallet-daemon-client/BalanceEntry"; +export * from "./types/wallet-daemon-client/TemplatesGetRequest"; +export * from "./types/wallet-daemon-client/AccountsInvokeRequest"; +export * from "./types/wallet-daemon-client/ProofsCancelRequest"; +export * from "./types/wallet-daemon-client/AccountSetDefaultResponse"; +export * from "./types/wallet-daemon-client/SubstatesListResponse"; +export * from "./types/wallet-daemon-client/KeysSetActiveResponse"; export * from "./types/wallet-daemon-client/ComponentAddressOrName"; +export * from "./types/wallet-daemon-client/AuthLoginAcceptRequest"; +export * from "./types/wallet-daemon-client/TransactionSubmitDryRunRequest"; +export * from "./types/wallet-daemon-client/KeysSetActiveRequest"; +export * from "./types/wallet-daemon-client/ConfidentialViewVaultBalanceRequest"; +export * from "./types/wallet-daemon-client/ConfidentialTransferRequest"; +export * from "./types/wallet-daemon-client/AccountsCreateResponse"; +export * from "./types/wallet-daemon-client/TransactionWaitResultResponse"; +export * from "./types/wallet-daemon-client/AccountGetRequest"; diff --git a/bindings/src/index.ts b/bindings/src/index.ts index ffca6215d..d3345a466 100644 --- a/bindings/src/index.ts +++ b/bindings/src/index.ts @@ -5,25 +5,25 @@ export * from "./types/AbortReason"; export * from "./types/AccessRule"; export * from "./types/Account"; export * from "./types/Amount"; -export * from "./types/Arg"; export * from "./types/ArgDef"; +export * from "./types/Arg"; export * from "./types/AuthHook"; -export * from "./types/Block"; export * from "./types/BlockHeader"; +export * from "./types/Block"; export * from "./types/BucketId"; export * from "./types/Claims"; export * from "./types/Command"; -export * from "./types/Committee"; 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/ConfidentialOutput"; export * from "./types/ConfidentialOutputStatement"; +export * from "./types/ConfidentialOutput"; export * from "./types/ConfidentialStatement"; export * from "./types/ConfidentialTransferInputSelection"; export * from "./types/ConfidentialWithdrawProof"; @@ -35,12 +35,12 @@ export * from "./types/Era"; export * from "./types/Event"; export * from "./types/EvictNodeAtom"; export * from "./types/Evidence"; -export * from "./types/ExecuteResult"; export * from "./types/ExecutedTransaction"; +export * from "./types/ExecuteResult"; export * from "./types/ExtraData"; export * from "./types/FeeBreakdown"; -export * from "./types/FeeClaim"; export * from "./types/FeeClaimAddress"; +export * from "./types/FeeClaim"; export * from "./types/FeeCostBreakdown"; export * from "./types/FeeReceipt"; export * from "./types/FeeSource"; @@ -49,10 +49,10 @@ export * from "./types/ForeignProposalAtom"; export * from "./types/FunctionDef"; export * from "./types/IndexedValue"; export * from "./types/IndexedWellKnownTypes"; -export * from "./types/Instruction"; export * from "./types/InstructionResult"; -export * from "./types/JrpcPermission"; +export * from "./types/Instruction"; export * from "./types/JrpcPermissions"; +export * from "./types/JrpcPermission"; export * from "./types/LeaderFee"; export * from "./types/LockFlag"; export * from "./types/LogEntry"; @@ -61,14 +61,14 @@ export * from "./types/Metadata"; export * from "./types/MintConfidentialOutputAtom"; export * from "./types/NetworkCommitteeInfo"; export * from "./types/NodeHeight"; -export * from "./types/NonFungible"; -export * from "./types/NonFungibleAddress"; export * from "./types/NonFungibleAddressContents"; +export * from "./types/NonFungibleAddress"; export * from "./types/NonFungibleContainer"; export * from "./types/NonFungibleId"; -export * from "./types/NonFungibleIndex"; 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"; @@ -78,50 +78,50 @@ export * from "./types/QuorumCertificate"; export * from "./types/QuorumDecision"; export * from "./types/RejectReason"; export * from "./types/RequireRule"; -export * from "./types/Resource"; 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/ResumeNodeAtom"; export * from "./types/RuleRequirement"; -export * from "./types/Shard"; export * from "./types/ShardEvidence"; -export * from "./types/ShardGroup"; export * from "./types/ShardGroupEvidence"; -export * from "./types/Substate"; +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/SubstateLockType"; export * from "./types/SubstateRecord"; -export * from "./types/SubstateRequirement"; export * from "./types/SubstateRequirementLockIntent"; +export * from "./types/SubstateRequirement"; +export * from "./types/Substate"; export * from "./types/SubstateType"; export * from "./types/SubstateValue"; export * from "./types/SuspendNodeAtom"; export * from "./types/TemplateDef"; export * from "./types/TemplateDefV1"; -export * from "./types/Transaction"; export * from "./types/TransactionAtom"; export * from "./types/TransactionPoolRecord"; export * from "./types/TransactionPoolStage"; -export * from "./types/TransactionReceipt"; 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/UnclaimedConfidentialOutputAddress"; +export * from "./types/UnclaimedConfidentialOutput"; export * from "./types/UnsignedTransaction"; export * from "./types/ValidatorSignature"; -export * from "./types/Vault"; export * from "./types/VaultId"; -export * from "./types/VersionedSubstateId"; +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"; diff --git a/bindings/src/tari-indexer-client.ts b/bindings/src/tari-indexer-client.ts index e9782093f..9d60c9416 100644 --- a/bindings/src/tari-indexer-client.ts +++ b/bindings/src/tari-indexer-client.ts @@ -1,37 +1,37 @@ // Copyright 2023 The Tari Project // SPDX-License-Identifier: BSD-3-Clause -export * from "./types/tari-indexer-client/IndexerGetEpochManagerStatsResponse"; -export * from "./types/tari-indexer-client/IndexerAddPeerRequest"; -export * from "./types/tari-indexer-client/NonFungibleSubstate"; -export * from "./types/tari-indexer-client/GetNonFungibleCountResponse"; -export * from "./types/tari-indexer-client/ListSubstatesRequest"; -export * from "./types/tari-indexer-client/IndexerGetIdentityResponse"; +export * from "./types/tari-indexer-client/IndexerSubmitTransactionResponse"; export * from "./types/tari-indexer-client/GetTemplateDefinitionRequest"; -export * from "./types/tari-indexer-client/IndexerGetSubstateRequest"; -export * from "./types/tari-indexer-client/GetTemplateDefinitionResponse"; -export * from "./types/tari-indexer-client/ListTemplatesRequest"; +export * from "./types/tari-indexer-client/ListSubstatesResponse"; +export * from "./types/tari-indexer-client/IndexerAddPeerResponse"; +export * from "./types/tari-indexer-client/InspectSubstateRequest"; +export * from "./types/tari-indexer-client/ListSubstateItem"; export * from "./types/tari-indexer-client/IndexerGetAllVnsResponse"; -export * from "./types/tari-indexer-client/GetNonFungiblesRequest"; +export * from "./types/tari-indexer-client/ListSubstatesRequest"; +export * from "./types/tari-indexer-client/GetRelatedTransactionsResponse"; +export * from "./types/tari-indexer-client/IndexerTransactionFinalizedResult"; export * from "./types/tari-indexer-client/IndexerGetSubstateResponse"; -export * from "./types/tari-indexer-client/IndexerSubmitTransactionRequest"; -export * from "./types/tari-indexer-client/IndexerConnection"; -export * from "./types/tari-indexer-client/InspectSubstateResponse"; export * from "./types/tari-indexer-client/IndexerGetAllVnsRequest"; -export * from "./types/tari-indexer-client/InspectSubstateRequest"; export * from "./types/tari-indexer-client/IndexerGetCommsStatsResponse"; -export * from "./types/tari-indexer-client/GetNonFungibleCountRequest"; -export * from "./types/tari-indexer-client/GetRelatedTransactionsResponse"; -export * from "./types/tari-indexer-client/IndexerAddPeerResponse"; -export * from "./types/tari-indexer-client/IndexerGetConnectionsResponse"; -export * from "./types/tari-indexer-client/GetNonFungiblesResponse"; +export * from "./types/tari-indexer-client/IndexerConnection"; +export * from "./types/tari-indexer-client/GetNonFungiblesRequest"; +export * from "./types/tari-indexer-client/IndexerAddPeerRequest"; export * from "./types/tari-indexer-client/GetRelatedTransactionsRequest"; -export * from "./types/tari-indexer-client/IndexerGetTransactionResultResponse"; +export * from "./types/tari-indexer-client/GetNonFungiblesResponse"; +export * from "./types/tari-indexer-client/GetTemplateDefinitionResponse"; +export * from "./types/tari-indexer-client/IndexerGetConnectionsResponse"; +export * from "./types/tari-indexer-client/IndexerSubmitTransactionRequest"; export * from "./types/tari-indexer-client/ListTemplatesResponse"; -export * from "./types/tari-indexer-client/IndexerGetTransactionResultRequest"; -export * from "./types/tari-indexer-client/ListSubstatesResponse"; -export * from "./types/tari-indexer-client/IndexerTransactionFinalizedResult"; +export * from "./types/tari-indexer-client/InspectSubstateResponse"; export * from "./types/tari-indexer-client/GetNonFungibleCollectionsResponse"; -export * from "./types/tari-indexer-client/IndexerSubmitTransactionResponse"; +export * from "./types/tari-indexer-client/IndexerGetSubstateRequest"; +export * from "./types/tari-indexer-client/IndexerGetEpochManagerStatsResponse"; +export * from "./types/tari-indexer-client/NonFungibleSubstate"; +export * from "./types/tari-indexer-client/GetNonFungibleCountResponse"; +export * from "./types/tari-indexer-client/ListTemplatesRequest"; +export * from "./types/tari-indexer-client/IndexerGetTransactionResultResponse"; export * from "./types/tari-indexer-client/IndexerConnectionDirection"; -export * from "./types/tari-indexer-client/ListSubstateItem"; +export * from "./types/tari-indexer-client/IndexerGetIdentityResponse"; +export * from "./types/tari-indexer-client/IndexerGetTransactionResultRequest"; +export * from "./types/tari-indexer-client/GetNonFungibleCountRequest"; diff --git a/bindings/src/types/Command.ts b/bindings/src/types/Command.ts index 9436e5fee..d49fa4b03 100644 --- a/bindings/src/types/Command.ts +++ b/bindings/src/types/Command.ts @@ -2,8 +2,6 @@ import type { EvictNodeAtom } from "./EvictNodeAtom"; import type { ForeignProposalAtom } from "./ForeignProposalAtom"; import type { MintConfidentialOutputAtom } from "./MintConfidentialOutputAtom"; -import type { ResumeNodeAtom } from "./ResumeNodeAtom"; -import type { SuspendNodeAtom } from "./SuspendNodeAtom"; import type { TransactionAtom } from "./TransactionAtom"; export type Command = @@ -17,7 +15,5 @@ export type Command = | { SomeAccept: TransactionAtom } | { ForeignProposal: ForeignProposalAtom } | { MintConfidentialOutput: MintConfidentialOutputAtom } - | { SuspendNode: SuspendNodeAtom } - | { ResumeNode: ResumeNodeAtom } | { EvictNode: EvictNodeAtom } | "EndEpoch"; diff --git a/bindings/src/types/validator-node-client/GetBaseLayerEpochChangesRequest.ts b/bindings/src/types/validator-node-client/GetBaseLayerEpochChangesRequest.ts new file mode 100644 index 000000000..b2d122ea6 --- /dev/null +++ b/bindings/src/types/validator-node-client/GetBaseLayerEpochChangesRequest.ts @@ -0,0 +1,7 @@ +// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually. +import type { Epoch } from "../Epoch"; + +export interface GetBaseLayerEpochChangesRequest { + start_epoch: Epoch; + end_epoch: Epoch; +} diff --git a/bindings/src/types/validator-node-client/GetBaseLayerEpochChangesResponse.ts b/bindings/src/types/validator-node-client/GetBaseLayerEpochChangesResponse.ts new file mode 100644 index 000000000..ffa7a1898 --- /dev/null +++ b/bindings/src/types/validator-node-client/GetBaseLayerEpochChangesResponse.ts @@ -0,0 +1,7 @@ +// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually. +import type { Epoch } from "../Epoch"; +import type { ValidatorNodeChange } from "./ValidatorNodeChange"; + +export interface GetBaseLayerEpochChangesResponse { + changes: Array<[Epoch, Array]>; +} diff --git a/bindings/src/types/validator-node-client/GetConsensusStatusResponse.ts b/bindings/src/types/validator-node-client/GetConsensusStatusResponse.ts new file mode 100644 index 000000000..34c972e71 --- /dev/null +++ b/bindings/src/types/validator-node-client/GetConsensusStatusResponse.ts @@ -0,0 +1,9 @@ +// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually. +import type { Epoch } from "../Epoch"; +import type { NodeHeight } from "../NodeHeight"; + +export interface GetConsensusStatusResponse { + epoch: Epoch; + height: NodeHeight; + state: string; +} diff --git a/bindings/src/types/validator-node-client/ValidatorNodeChange.ts b/bindings/src/types/validator-node-client/ValidatorNodeChange.ts new file mode 100644 index 000000000..40ab2a3e4 --- /dev/null +++ b/bindings/src/types/validator-node-client/ValidatorNodeChange.ts @@ -0,0 +1,6 @@ +// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually. +import type { Epoch } from "../Epoch"; + +export type ValidatorNodeChange = + | { Add: { public_key: string; activation_epoch: Epoch; minimum_value_promise: bigint } } + | { Remove: { public_key: string } }; diff --git a/bindings/src/validator-node-client.ts b/bindings/src/validator-node-client.ts index 989140390..d8d5ae0d8 100644 --- a/bindings/src/validator-node-client.ts +++ b/bindings/src/validator-node-client.ts @@ -1,59 +1,63 @@ // Copyright 2023 The Tari Project // SPDX-License-Identifier: BSD-3-Clause -export * from "./types/validator-node-client/GetCommitteeRequest"; -export * from "./types/validator-node-client/GetRecentTransactionsResponse"; -export * from "./types/validator-node-client/GetRecentTransactionsRequest"; -export * from "./types/validator-node-client/GetTemplatesRequest"; -export * from "./types/validator-node-client/GetBlocksCountResponse"; -export * from "./types/validator-node-client/VNAddPeerRequest"; -export * from "./types/validator-node-client/GetCommitteeResponse"; +export * from "./types/validator-node-client/ValidatorNodeChange"; export * from "./types/validator-node-client/VNSubmitTransactionRequest"; -export * from "./types/validator-node-client/VNConnectionDirection"; -export * from "./types/validator-node-client/VNAddPeerResponse"; -export * from "./types/validator-node-client/GetSubstatesByTransactionResponse"; -export * from "./types/validator-node-client/VNCommitteeShardInfo"; -export * from "./types/validator-node-client/VNFunctionDef"; -export * from "./types/validator-node-client/VNGetValidatorFeesResponse"; -export * from "./types/validator-node-client/VNGetAllVnsResponse"; -export * from "./types/validator-node-client/TemplateAbi"; -export * from "./types/validator-node-client/GetMempoolStatsResponse"; export * from "./types/validator-node-client/TemplateMetadata"; -export * from "./types/validator-node-client/GetBlockResponse"; -export * from "./types/validator-node-client/VNLogLevel"; -export * from "./types/validator-node-client/VNGetAllVnsRequest"; +export * from "./types/validator-node-client/GetFilteredBlocksCountRequest"; export * from "./types/validator-node-client/VNLogEntry"; export * from "./types/validator-node-client/GetShardKeyRequest"; -export * from "./types/validator-node-client/GetBlockRequest"; +export * from "./types/validator-node-client/VNGetTransactionResultResponse"; export * from "./types/validator-node-client/VNSubmitTransactionResponse"; -export * from "./types/validator-node-client/DryRunTransactionFinalizeResult"; -export * from "./types/validator-node-client/GetTransactionResponse"; -export * from "./types/validator-node-client/GetStateResponse"; -export * from "./types/validator-node-client/VNGetSubstateRequest"; -export * from "./types/validator-node-client/VNGetSubstateResponse"; -export * from "./types/validator-node-client/ListBlocksResponse"; -export * from "./types/validator-node-client/SubstateStatus"; -export * from "./types/validator-node-client/ValidatorNode"; -export * from "./types/validator-node-client/GetFilteredBlocksCountRequest"; -export * from "./types/validator-node-client/ListBlocksRequest"; -export * from "./types/validator-node-client/GetEpochManagerStatsResponse"; export * from "./types/validator-node-client/GetTxPoolResponse"; -export * from "./types/validator-node-client/VNConnection"; export * from "./types/validator-node-client/GetTemplateResponse"; -export * from "./types/validator-node-client/ValidatorFee"; -export * from "./types/validator-node-client/VNGetConnectionsResponse"; -export * from "./types/validator-node-client/VNGetCommsStatsResponse"; -export * from "./types/validator-node-client/GetTemplateRequest"; +export * from "./types/validator-node-client/GetBlocksCountResponse"; +export * from "./types/validator-node-client/VNGetValidatorFeesRequest"; +export * from "./types/validator-node-client/GetSubstatesByTransactionResponse"; +export * from "./types/validator-node-client/VNConnectionDirection"; +export * from "./types/validator-node-client/VNAddPeerRequest"; +export * from "./types/validator-node-client/GetTemplatesResponse"; +export * from "./types/validator-node-client/GetTransactionRequest"; export * from "./types/validator-node-client/GetStateRequest"; +export * from "./types/validator-node-client/VNGetIdentityResponse"; +export * from "./types/validator-node-client/VNFunctionDef"; export * from "./types/validator-node-client/GetBlocksRequest"; -export * from "./types/validator-node-client/VNGetTransactionResultRequest"; -export * from "./types/validator-node-client/GetTransactionRequest"; -export * from "./types/validator-node-client/GetTemplatesResponse"; -export * from "./types/validator-node-client/VNGetTransactionResultResponse"; -export * from "./types/validator-node-client/VNArgDef"; +export * from "./types/validator-node-client/GetTemplateRequest"; export * from "./types/validator-node-client/GetShardKeyResponse"; -export * from "./types/validator-node-client/GetBlocksResponse"; -export * from "./types/validator-node-client/VNGetIdentityResponse"; +export * from "./types/validator-node-client/GetBaseLayerEpochChangesResponse"; export * from "./types/validator-node-client/GetSubstatesByTransactionRequest"; +export * from "./types/validator-node-client/VNGetCommsStatsResponse"; +export * from "./types/validator-node-client/GetTransactionResponse"; +export * from "./types/validator-node-client/GetCommitteeResponse"; +export * from "./types/validator-node-client/VNGetAllVnsRequest"; +export * from "./types/validator-node-client/GetCommitteeRequest"; +export * from "./types/validator-node-client/DryRunTransactionFinalizeResult"; +export * from "./types/validator-node-client/VNGetValidatorFeesResponse"; +export * from "./types/validator-node-client/GetStateResponse"; +export * from "./types/validator-node-client/GetBaseLayerEpochChangesRequest"; +export * from "./types/validator-node-client/SubstateStatus"; +export * from "./types/validator-node-client/GetConsensusStatusResponse"; +export * from "./types/validator-node-client/GetBlocksResponse"; +export * from "./types/validator-node-client/ListBlocksResponse"; +export * from "./types/validator-node-client/GetBlockRequest"; +export * from "./types/validator-node-client/VNGetTransactionResultRequest"; +export * from "./types/validator-node-client/GetRecentTransactionsRequest"; +export * from "./types/validator-node-client/ValidatorFee"; +export * from "./types/validator-node-client/VNLogLevel"; +export * from "./types/validator-node-client/GetRecentTransactionsResponse"; +export * from "./types/validator-node-client/VNAddPeerResponse"; +export * from "./types/validator-node-client/VNConnection"; +export * from "./types/validator-node-client/ValidatorNode"; +export * from "./types/validator-node-client/VNGetConnectionsResponse"; +export * from "./types/validator-node-client/ListBlocksRequest"; export * from "./types/validator-node-client/GetNetworkCommitteeResponse"; -export * from "./types/validator-node-client/VNGetValidatorFeesRequest"; +export * from "./types/validator-node-client/VNGetSubstateRequest"; +export * from "./types/validator-node-client/GetMempoolStatsResponse"; +export * from "./types/validator-node-client/TemplateAbi"; +export * from "./types/validator-node-client/GetTemplatesRequest"; +export * from "./types/validator-node-client/VNGetSubstateResponse"; +export * from "./types/validator-node-client/VNGetAllVnsResponse"; +export * from "./types/validator-node-client/VNArgDef"; +export * from "./types/validator-node-client/GetEpochManagerStatsResponse"; +export * from "./types/validator-node-client/GetBlockResponse"; +export * from "./types/validator-node-client/VNCommitteeShardInfo"; diff --git a/bindings/src/wallet-daemon-client.ts b/bindings/src/wallet-daemon-client.ts index 9fe3e1c56..7c10e0ad2 100644 --- a/bindings/src/wallet-daemon-client.ts +++ b/bindings/src/wallet-daemon-client.ts @@ -1,92 +1,92 @@ // Copyright 2023 The Tari Project // SPDX-License-Identifier: BSD-3-Clause -export * from "./types/wallet-daemon-client/AccountsListResponse"; -export * from "./types/wallet-daemon-client/RevealFundsRequest"; -export * from "./types/wallet-daemon-client/ClaimBurnResponse"; -export * from "./types/wallet-daemon-client/KeysSetActiveRequest"; export * from "./types/wallet-daemon-client/WalletSubstateRecord"; -export * from "./types/wallet-daemon-client/AccountsGetBalancesResponse"; -export * from "./types/wallet-daemon-client/SubstatesGetResponse"; -export * from "./types/wallet-daemon-client/ListAccountNftRequest"; -export * from "./types/wallet-daemon-client/RevealFundsResponse"; -export * from "./types/wallet-daemon-client/AccountSetDefaultRequest"; -export * from "./types/wallet-daemon-client/GetAccountNftRequest"; -export * from "./types/wallet-daemon-client/TransactionGetAllResponse"; -export * from "./types/wallet-daemon-client/TransactionGetRequest"; -export * from "./types/wallet-daemon-client/KeyBranch"; -export * from "./types/wallet-daemon-client/AuthLoginAcceptRequest"; -export * from "./types/wallet-daemon-client/AccountSetDefaultResponse"; -export * from "./types/wallet-daemon-client/SubstatesListResponse"; +export * from "./types/wallet-daemon-client/ProofsFinalizeResponse"; +export * from "./types/wallet-daemon-client/CallInstructionRequest"; +export * from "./types/wallet-daemon-client/AuthLoginAcceptResponse"; +export * from "./types/wallet-daemon-client/AccountsListRequest"; +export * from "./types/wallet-daemon-client/AuthGetAllJwtResponse"; +export * from "./types/wallet-daemon-client/AuthLoginResponse"; +export * from "./types/wallet-daemon-client/GetValidatorFeesRequest"; export * from "./types/wallet-daemon-client/AccountGetDefaultRequest"; -export * from "./types/wallet-daemon-client/KeysListResponse"; -export * from "./types/wallet-daemon-client/ProofsGenerateResponse"; +export * from "./types/wallet-daemon-client/AuthGetAllJwtRequest"; +export * from "./types/wallet-daemon-client/KeyBranch"; +export * from "./types/wallet-daemon-client/AccountGetResponse"; +export * from "./types/wallet-daemon-client/SettingsSetRequest"; +export * from "./types/wallet-daemon-client/GetValidatorFeesResponse"; export * from "./types/wallet-daemon-client/TransactionGetAllRequest"; +export * from "./types/wallet-daemon-client/RevealFundsRequest"; +export * from "./types/wallet-daemon-client/AuthLoginDenyResponse"; +export * from "./types/wallet-daemon-client/AuthLoginDenyRequest"; +export * from "./types/wallet-daemon-client/TransactionSubmitResponse"; +export * from "./types/wallet-daemon-client/ProofsGenerateResponse"; +export * from "./types/wallet-daemon-client/ClaimValidatorFeesRequest"; +export * from "./types/wallet-daemon-client/AuthLoginRequest"; +export * from "./types/wallet-daemon-client/ListAccountNftRequest"; +export * from "./types/wallet-daemon-client/TransactionGetRequest"; +export * from "./types/wallet-daemon-client/AuthRevokeTokenResponse"; +export * from "./types/wallet-daemon-client/ProofsFinalizeRequest"; +export * from "./types/wallet-daemon-client/AccountsTransferRequest"; +export * from "./types/wallet-daemon-client/SettingsSetResponse"; +export * from "./types/wallet-daemon-client/KeysListRequest"; export * from "./types/wallet-daemon-client/AccountsTransferResponse"; -export * from "./types/wallet-daemon-client/AuthLoginResponse"; +export * from "./types/wallet-daemon-client/TransactionGetResultResponse"; export * from "./types/wallet-daemon-client/ClaimBurnRequest"; -export * from "./types/wallet-daemon-client/BalanceEntry"; -export * from "./types/wallet-daemon-client/KeysListRequest"; +export * from "./types/wallet-daemon-client/KeysListResponse"; export * from "./types/wallet-daemon-client/SubstatesGetRequest"; -export * from "./types/wallet-daemon-client/ProofsFinalizeResponse"; +export * from "./types/wallet-daemon-client/TransactionSubmitRequest"; +export * from "./types/wallet-daemon-client/AccountsGetBalancesResponse"; +export * from "./types/wallet-daemon-client/TransactionGetAllResponse"; +export * from "./types/wallet-daemon-client/AccountsCreateFreeTestCoinsResponse"; +export * from "./types/wallet-daemon-client/ConfidentialTransferResponse"; +export * from "./types/wallet-daemon-client/TransactionGetResponse"; +export * from "./types/wallet-daemon-client/SubstatesGetResponse"; +export * from "./types/wallet-daemon-client/GetAccountNftRequest"; export * from "./types/wallet-daemon-client/AuthRevokeTokenRequest"; -export * from "./types/wallet-daemon-client/TransactionWaitResultRequest"; -export * from "./types/wallet-daemon-client/TransactionSubmitResponse"; -export * from "./types/wallet-daemon-client/AccountsCreateRequest"; -export * from "./types/wallet-daemon-client/CallInstructionRequest"; -export * from "./types/wallet-daemon-client/WebRtcStartRequest"; +export * from "./types/wallet-daemon-client/ProofsGenerateRequest"; +export * from "./types/wallet-daemon-client/RevealFundsResponse"; +export * from "./types/wallet-daemon-client/AccountsInvokeResponse"; +export * from "./types/wallet-daemon-client/AccountsListResponse"; export * from "./types/wallet-daemon-client/WebRtcStartResponse"; -export * from "./types/wallet-daemon-client/TransactionSubmitDryRunRequest"; -export * from "./types/wallet-daemon-client/MintAccountNftResponse"; +export * from "./types/wallet-daemon-client/TransactionGetResultRequest"; export * from "./types/wallet-daemon-client/ProofsCancelResponse"; -export * from "./types/wallet-daemon-client/AccountGetResponse"; -export * from "./types/wallet-daemon-client/ClaimValidatorFeesRequest"; -export * from "./types/wallet-daemon-client/AuthRevokeTokenResponse"; -export * from "./types/wallet-daemon-client/AccountsInvokeRequest"; -export * from "./types/wallet-daemon-client/WebRtcStart"; -export * from "./types/wallet-daemon-client/TransactionWaitResultResponse"; -export * from "./types/wallet-daemon-client/GetValidatorFeesRequest"; +export * from "./types/wallet-daemon-client/AccountsCreateRequest"; +export * from "./types/wallet-daemon-client/MintAccountNftRequest"; +export * from "./types/wallet-daemon-client/TransactionClaimBurnResponse"; +export * from "./types/wallet-daemon-client/TransactionWaitResultRequest"; +export * from "./types/wallet-daemon-client/ClaimValidatorFeesResponse"; export * from "./types/wallet-daemon-client/ConfidentialCreateOutputProofRequest"; -export * from "./types/wallet-daemon-client/KeysCreateResponse"; -export * from "./types/wallet-daemon-client/AuthLoginDenyRequest"; -export * from "./types/wallet-daemon-client/ProofsFinalizeRequest"; -export * from "./types/wallet-daemon-client/ProofsCancelRequest"; +export * from "./types/wallet-daemon-client/KeysCreateRequest"; export * from "./types/wallet-daemon-client/SettingsGetResponse"; -export * from "./types/wallet-daemon-client/ConfidentialViewVaultBalanceRequest"; -export * from "./types/wallet-daemon-client/GetValidatorFeesResponse"; -export * from "./types/wallet-daemon-client/TransactionGetResponse"; -export * from "./types/wallet-daemon-client/TransactionSubmitRequest"; -export * from "./types/wallet-daemon-client/ListAccountNftResponse"; -export * from "./types/wallet-daemon-client/AccountsInvokeResponse"; -export * from "./types/wallet-daemon-client/AccountsListRequest"; -export * from "./types/wallet-daemon-client/AuthLoginAcceptResponse"; export * from "./types/wallet-daemon-client/TransactionSubmitDryRunResponse"; -export * from "./types/wallet-daemon-client/ConfidentialCreateOutputProofResponse"; -export * from "./types/wallet-daemon-client/TemplatesGetRequest"; +export * from "./types/wallet-daemon-client/ClaimBurnResponse"; +export * from "./types/wallet-daemon-client/WebRtcStartRequest"; export * from "./types/wallet-daemon-client/ConfidentialViewVaultBalanceResponse"; -export * from "./types/wallet-daemon-client/SettingsSetRequest"; -export * from "./types/wallet-daemon-client/MintAccountNftRequest"; -export * from "./types/wallet-daemon-client/TransactionClaimBurnResponse"; -export * from "./types/wallet-daemon-client/AuthGetAllJwtRequest"; -export * from "./types/wallet-daemon-client/ClaimValidatorFeesResponse"; -export * from "./types/wallet-daemon-client/ConfidentialTransferResponse"; +export * from "./types/wallet-daemon-client/WebRtcStart"; +export * from "./types/wallet-daemon-client/AccountSetDefaultRequest"; +export * from "./types/wallet-daemon-client/ConfidentialCreateOutputProofResponse"; export * from "./types/wallet-daemon-client/TemplatesGetResponse"; -export * from "./types/wallet-daemon-client/AccountsTransferRequest"; -export * from "./types/wallet-daemon-client/AuthLoginRequest"; -export * from "./types/wallet-daemon-client/AuthGetAllJwtResponse"; -export * from "./types/wallet-daemon-client/AccountsCreateFreeTestCoinsRequest"; -export * from "./types/wallet-daemon-client/ConfidentialTransferRequest"; -export * from "./types/wallet-daemon-client/SettingsSetResponse"; -export * from "./types/wallet-daemon-client/AccountsCreateFreeTestCoinsResponse"; -export * from "./types/wallet-daemon-client/AccountGetRequest"; -export * from "./types/wallet-daemon-client/KeysCreateRequest"; -export * from "./types/wallet-daemon-client/ProofsGenerateRequest"; -export * from "./types/wallet-daemon-client/TransactionGetResultResponse"; -export * from "./types/wallet-daemon-client/KeysSetActiveResponse"; -export * from "./types/wallet-daemon-client/AuthLoginDenyResponse"; -export * from "./types/wallet-daemon-client/TransactionGetResultRequest"; -export * from "./types/wallet-daemon-client/AccountsCreateResponse"; +export * from "./types/wallet-daemon-client/ListAccountNftResponse"; export * from "./types/wallet-daemon-client/AccountsGetBalancesRequest"; +export * from "./types/wallet-daemon-client/MintAccountNftResponse"; +export * from "./types/wallet-daemon-client/AccountsCreateFreeTestCoinsRequest"; +export * from "./types/wallet-daemon-client/KeysCreateResponse"; export * from "./types/wallet-daemon-client/AccountInfo"; export * from "./types/wallet-daemon-client/SubstatesListRequest"; +export * from "./types/wallet-daemon-client/BalanceEntry"; +export * from "./types/wallet-daemon-client/TemplatesGetRequest"; +export * from "./types/wallet-daemon-client/AccountsInvokeRequest"; +export * from "./types/wallet-daemon-client/ProofsCancelRequest"; +export * from "./types/wallet-daemon-client/AccountSetDefaultResponse"; +export * from "./types/wallet-daemon-client/SubstatesListResponse"; +export * from "./types/wallet-daemon-client/KeysSetActiveResponse"; export * from "./types/wallet-daemon-client/ComponentAddressOrName"; +export * from "./types/wallet-daemon-client/AuthLoginAcceptRequest"; +export * from "./types/wallet-daemon-client/TransactionSubmitDryRunRequest"; +export * from "./types/wallet-daemon-client/KeysSetActiveRequest"; +export * from "./types/wallet-daemon-client/ConfidentialViewVaultBalanceRequest"; +export * from "./types/wallet-daemon-client/ConfidentialTransferRequest"; +export * from "./types/wallet-daemon-client/AccountsCreateResponse"; +export * from "./types/wallet-daemon-client/TransactionWaitResultResponse"; +export * from "./types/wallet-daemon-client/AccountGetRequest"; diff --git a/dan_layer/common_types/src/committee.rs b/dan_layer/common_types/src/committee.rs index 1e2d4952b..7455a56d2 100644 --- a/dan_layer/common_types/src/committee.rs +++ b/dan_layer/common_types/src/committee.rs @@ -63,10 +63,8 @@ impl Committee { self.members.shuffle(&mut OsRng); } - pub fn shuffled(&self) -> impl Iterator + '_ { - self.members - .choose_multiple(&mut OsRng, self.len()) - .map(|(addr, _)| addr) + pub fn shuffled(&self) -> impl Iterator + '_ { + self.members.choose_multiple(&mut OsRng, self.len()) } pub fn select_n_random(&self, n: usize) -> impl Iterator + '_ { diff --git a/dan_layer/consensus/Cargo.toml b/dan_layer/consensus/Cargo.toml index fe18f8a55..39bb407c0 100644 --- a/dan_layer/consensus/Cargo.toml +++ b/dan_layer/consensus/Cargo.toml @@ -29,6 +29,3 @@ log = { workspace = true } serde = { workspace = true, default-features = true } thiserror = { workspace = true } tokio = { workspace = true, default-features = false, features = ["sync", "time", "macros", "rt"] } - -# REMOvE -serde_json = { workspace = true } diff --git a/dan_layer/consensus/src/block_validations.rs b/dan_layer/consensus/src/block_validations.rs index 51403db1e..32b129ff2 100644 --- a/dan_layer/consensus/src/block_validations.rs +++ b/dan_layer/consensus/src/block_validations.rs @@ -10,7 +10,7 @@ use tari_dan_common_types::{ Epoch, ExtraFieldKey, }; -use tari_dan_storage::consensus_models::Block; +use tari_dan_storage::consensus_models::{Block, QuorumCertificate}; use tari_epoch_manager::EpochManagerReader; use crate::{ @@ -68,7 +68,13 @@ pub fn check_proposal( } check_proposed_by_leader(leader_strategy, committee_for_block, block)?; check_signature(block)?; - check_quorum_certificate::(block, committee_for_block, committee_info, vote_signing_service)?; + check_block(block)?; + check_quorum_certificate::( + block.justify(), + committee_for_block, + committee_info, + vote_signing_service, + )?; Ok(()) } @@ -205,26 +211,30 @@ pub fn check_signature(candidate_block: &Block) -> Result<(), ProposalValidation Ok(()) } +pub fn check_block(candidate_block: &Block) -> Result<(), ProposalValidationError> { + let qc = candidate_block.justify(); + if candidate_block.height() <= qc.block_height() { + return Err(ProposalValidationError::CandidateBlockNotHigherThanJustify { + justify_block_height: qc.block_height(), + candidate_block_height: candidate_block.height(), + }); + } + + Ok(()) +} + pub fn check_quorum_certificate( - candidate_block: &Block, + qc: &QuorumCertificate, committee: &Committee, committee_info: &CommitteeInfo, vote_signing_service: &TConsensusSpec::SignatureService, ) -> Result<(), HotStuffError> { - let qc = candidate_block.justify(); - if qc.is_zero() { + if qc.justifies_zero_block() { // TODO: This is potentially dangerous. There should be a check // to make sure this is the start of the chain. return Ok(()); } - if candidate_block.height() <= qc.block_height() { - return Err(ProposalValidationError::CandidateBlockNotHigherThanJustify { - justify_block_height: qc.block_height(), - candidate_block_height: candidate_block.height(), - } - .into()); - } if qc.signatures().is_empty() { return Err(ProposalValidationError::QuorumWasNotReached { qc: *qc.id() }.into()); diff --git a/dan_layer/consensus/src/hotstuff/common.rs b/dan_layer/consensus/src/hotstuff/common.rs index a51108d1e..cc9053c44 100644 --- a/dan_layer/consensus/src/hotstuff/common.rs +++ b/dan_layer/consensus/src/hotstuff/common.rs @@ -89,7 +89,7 @@ pub fn calculate_last_dummy_block>( +pub fn calculate_dummy_blocks>( from_height: NodeHeight, new_height: NodeHeight, network: Network, @@ -105,7 +105,7 @@ fn calculate_dummy_blocks Vec { - let mut dummies = Vec::new(); + let mut dummies = Vec::with_capacity(new_height.saturating_sub(from_height).as_u64() as usize); with_dummy_blocks( from_height, new_height, @@ -147,7 +147,7 @@ pub fn calculate_dummy_blocks_from_justify CommitProofElement { }, }) } - -#[cfg(test)] -mod tests { - - use super::*; - use crate::test_helpers::load_fixture; - - #[test] - fn it_produces_a_summarized_header_that_hashes_to_the_original() { - let block = load_fixture::("block.json"); - let sidechain_block = convert_block_to_sidechain_block_header(block.header()); - assert_eq!(sidechain_block.extra_data_hash, block.header().create_extra_data_hash()); - assert_eq!( - sidechain_block.base_layer_block_hash, - *block.header().base_layer_block_hash() - ); - assert_eq!( - sidechain_block.base_layer_block_height, - block.header().base_layer_block_height() - ); - assert_eq!(sidechain_block.timestamp, block.header().timestamp()); - assert_eq!( - sidechain_block.signature, - block.header().signature().expect("checked by caller").clone() - ); - assert_eq!( - sidechain_block.foreign_indexes_hash, - block.header().create_foreign_indexes_hash() - ); - assert_eq!(sidechain_block.is_dummy, block.header().is_dummy()); - assert_eq!( - sidechain_block.command_merkle_root, - *block.header().command_merkle_root() - ); - assert_eq!(sidechain_block.state_merkle_root, *block.header().state_merkle_root()); - assert_eq!(sidechain_block.total_leader_fee, block.header().total_leader_fee()); - assert_eq!(sidechain_block.proposed_by, block.header().proposed_by().clone()); - assert_eq!( - sidechain_block.shard_group.start, - block.header().shard_group().start().as_u32() - ); - assert_eq!( - sidechain_block.shard_group.end_inclusive, - block.header().shard_group().end().as_u32() - ); - assert_eq!(sidechain_block.epoch, block.header().epoch().as_u64()); - assert_eq!(sidechain_block.height, block.header().height().as_u64()); - assert_eq!(sidechain_block.justify_id, *block.header().justify_id().hash()); - assert_eq!(sidechain_block.parent_id, *block.header().parent().hash()); - assert_eq!(sidechain_block.network, block.header().network().as_byte()); - - // Finally check the hash matches - assert_eq!(sidechain_block.calculate_hash(), block.header().calculate_hash()); - assert_eq!( - sidechain_block.calculate_block_id(), - *block.header().calculate_id().hash() - ); - } -} diff --git a/dan_layer/consensus/src/hotstuff/foreign_proposal_processor.rs b/dan_layer/consensus/src/hotstuff/foreign_proposal_processor.rs index 737bc10a1..dc21104d2 100644 --- a/dan_layer/consensus/src/hotstuff/foreign_proposal_processor.rs +++ b/dan_layer/consensus/src/hotstuff/foreign_proposal_processor.rs @@ -96,8 +96,7 @@ pub fn process_foreign_block( command_count += 1; if tx_rec.current_stage() > TransactionPoolStage::LocalPrepared { - // CASE: This will happen if output-only nodes send a prepare to input-involved nodes. TODO: - // output-only nodes can skip sending prepare + // CASE: This will happen if output-only nodes send a prepare to input-involved nodes. warn!( target: LOG_TARGET, "⚠️ Foreign LocalPrepare proposal ({}) received LOCAL_PREPARE for transaction {} but current transaction stage is {}. Ignoring.", diff --git a/dan_layer/consensus/src/hotstuff/on_catch_up_sync_request.rs b/dan_layer/consensus/src/hotstuff/on_catch_up_sync_request.rs index be30e05e0..bf488e482 100644 --- a/dan_layer/consensus/src/hotstuff/on_catch_up_sync_request.rs +++ b/dan_layer/consensus/src/hotstuff/on_catch_up_sync_request.rs @@ -63,7 +63,7 @@ impl OnSyncRequest { } if leaf_block.height.is_zero() { - info!(target: LOG_TARGET, "This node is at height 0 so cannot return any syn blocks. Ignoring request"); + info!(target: LOG_TARGET, "This node is at height 0 so cannot return any sync blocks. Ignoring request"); return Ok(vec![]); } diff --git a/dan_layer/consensus/src/hotstuff/on_inbound_message.rs b/dan_layer/consensus/src/hotstuff/on_inbound_message.rs index 0a1955627..bf16bbcaf 100644 --- a/dan_layer/consensus/src/hotstuff/on_inbound_message.rs +++ b/dan_layer/consensus/src/hotstuff/on_inbound_message.rs @@ -112,9 +112,9 @@ impl MessageBuffer { // Buffer message for future epoch/height Some((epoch, height)) if epoch == current_epoch && height > next_height => { if msg.proposal().is_some() { - info!(target: LOG_TARGET, "🦴Proposal {msg} is for future view (Current view: {current_epoch}, {next_height})"); + info!(target: LOG_TARGET, "🦴Proposal {msg} is for future view (Current view: {current_epoch}, {current_height})"); } else { - info!(target: LOG_TARGET, "🦴Message {msg} is for future view (Current view: {current_epoch}, {next_height})"); + info!(target: LOG_TARGET, "🦴Message {msg} is for future view (Current view: {current_epoch}, {current_height})"); } self.push_to_buffer(epoch, height, from, msg); continue; @@ -174,7 +174,7 @@ fn msg_epoch_and_height(msg: &HotstuffMessage) -> Option { HotstuffMessage::Vote(msg) => Some((msg.epoch, msg.unverified_block_height.saturating_add(NodeHeight(1)))), // We will buffer NEWVIEW messages until the appropriate height is set. This essentially prevents us from being // forced to the next height without locally deciding to do so. - HotstuffMessage::NewView(msg) => Some((msg.high_qc.epoch(), msg.new_height.saturating_add(NodeHeight(1)))), + // HotstuffMessage::NewView(msg) => Some((msg.high_qc.epoch(), msg.new_height.saturating_add(NodeHeight(1)))), _ => None, } } diff --git a/dan_layer/consensus/src/hotstuff/on_next_sync_view.rs b/dan_layer/consensus/src/hotstuff/on_next_sync_view.rs index 8848be42f..d2ccc9000 100644 --- a/dan_layer/consensus/src/hotstuff/on_next_sync_view.rs +++ b/dan_layer/consensus/src/hotstuff/on_next_sync_view.rs @@ -44,9 +44,6 @@ impl OnNextSyncViewHandler { current_height: NodeHeight, local_committee: &Committee, ) -> Result<(), HotStuffError> { - // info!(target: LOG_TARGET, "⚠️ Leader failure: NEXTSYNCVIEW for epoch {} and current height {}", epoch, - // current_height); - let (new_height, next_leader, leaf_block, high_qc, last_sent_vote) = self.store.with_read_tx(|tx| { let leaf_block = LeafBlock::get(tx, epoch)?; let (next_height, next_leader, _) = get_next_block_height_and_leader( @@ -60,7 +57,7 @@ impl OnNextSyncViewHandler { let high_qc = HighQc::get(tx, epoch)?.get_quorum_certificate(tx)?; let last_sent_vote = LastSentVote::get(tx) .optional()? - .filter(|vote| high_qc.epoch() < vote.epoch) + .filter(|vote| high_qc.epoch() == vote.epoch) .filter(|vote| high_qc.block_height() < vote.block_height); Ok::<_, HotStuffError>((next_height, next_leader, leaf_block, high_qc, last_sent_vote)) })?; diff --git a/dan_layer/consensus/src/hotstuff/on_propose.rs b/dan_layer/consensus/src/hotstuff/on_propose.rs index 7abaeea39..d3548547b 100644 --- a/dan_layer/consensus/src/hotstuff/on_propose.rs +++ b/dan_layer/consensus/src/hotstuff/on_propose.rs @@ -233,24 +233,35 @@ where TConsensusSpec: ConsensusSpec foreign_proposals: Vec, local_committee_info: &CommitteeInfo, ) -> Result<(), HotStuffError> { - info!( - target: LOG_TARGET, - "🌿 Broadcasting local proposal {} to local committee", - next_block, - ); + let epoch = next_block.epoch(); + let leaf_block = next_block.as_leaf_block(); let msg = HotstuffMessage::Proposal(ProposalMessage { block: next_block, foreign_proposals, }); + // Broadcast to local and foreign committees self.outbound_messaging.send_self(msg.clone()).await?; + // If we are the only VN in this committee, no need to multicast - if local_committee_info.num_shard_group_members() > 1 { - if let Err(err) = self - .outbound_messaging - .multicast(local_committee_info.shard_group(), msg) - .await - { + if local_committee_info.num_shard_group_members() <= 1 { + info!( + target: LOG_TARGET, + "🌿 Only member of local committee. No need to multicast proposal {leaf_block}", + ); + } else { + let committee = self + .epoch_manager + .get_committee_by_shard_group(epoch, local_committee_info.shard_group(), None) + .await?; + + info!( + target: LOG_TARGET, + "🌿 Broadcasting local proposal to {}/{} local committee members {}", + committee.len(), local_committee_info.num_shard_group_members(), leaf_block, + ); + + if let Err(err) = self.outbound_messaging.multicast(committee.into_addresses(), msg).await { warn!( target: LOG_TARGET, "Failed to multicast proposal to local committee: {}", 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 c9038eb27..8153b7180 100644 --- a/dan_layer/consensus/src/hotstuff/on_receive_foreign_proposal.rs +++ b/dan_layer/consensus/src/hotstuff/on_receive_foreign_proposal.rs @@ -2,18 +2,23 @@ // SPDX-License-Identifier: BSD-3-Clause use log::*; -use tari_dan_common_types::{committee::CommitteeInfo, ShardGroup}; +use tari_dan_common_types::{committee::CommitteeInfo, Epoch, ShardGroup}; use tari_dan_storage::{ - consensus_models::{Block, ForeignProposal, ForeignReceiveCounters}, + consensus_models::{Block, ForeignProposal, ForeignReceiveCounters, QuorumCertificate}, StateStore, }; use tari_epoch_manager::EpochManagerReader; use crate::{ hotstuff::{error::HotStuffError, pacemaker_handle::PaceMakerHandle, ProposalValidationError}, - messages::ForeignProposalMessage, + messages::{ + ForeignProposalMessage, + ForeignProposalNotificationMessage, + ForeignProposalRequestMessage, + HotstuffMessage, + }, tracing::TraceTimer, - traits::ConsensusSpec, + traits::{ConsensusSpec, OutboundMessaging}, }; const LOG_TARGET: &str = "tari::dan::consensus::hotstuff::on_receive_foreign_proposal"; @@ -23,6 +28,7 @@ pub struct OnReceiveForeignProposalHandler { store: TConsensusSpec::StateStore, epoch_manager: TConsensusSpec::EpochManager, pacemaker: PaceMakerHandle, + outbound_messaging: TConsensusSpec::OutboundMessaging, } impl OnReceiveForeignProposalHandler @@ -32,15 +38,17 @@ where TConsensusSpec: ConsensusSpec store: TConsensusSpec::StateStore, epoch_manager: TConsensusSpec::EpochManager, pacemaker: PaceMakerHandle, + outbound_messaging: TConsensusSpec::OutboundMessaging, ) -> Self { Self { store, epoch_manager, pacemaker, + outbound_messaging, } } - pub async fn handle( + pub async fn handle_received( &mut self, message: ForeignProposalMessage, local_committee_info: &CommitteeInfo, @@ -70,6 +78,152 @@ where TConsensusSpec: ConsensusSpec Ok(()) } + pub async fn handle_notification_received( + &mut self, + from: TConsensusSpec::Addr, + current_epoch: Epoch, + message: ForeignProposalNotificationMessage, + local_committee_info: &CommitteeInfo, + ) -> Result<(), HotStuffError> { + debug!( + target: LOG_TARGET, + "🌐 Receive FOREIGN PROPOSAL NOTIFICATION from {} for block {}", + from, + message.block_id, + ); + if self + .store + .with_read_tx(|tx| ForeignProposal::record_exists(tx, &message.block_id))? + { + // This is expected behaviour, we may receive the same foreign proposal notification multiple times + debug!( + target: LOG_TARGET, + "FOREIGN PROPOSAL: Already received proposal for block {}", + message.block_id, + ); + return Ok(()); + } + + // Check if the source is in a foreign committee + let foreign_committee_info = self + .epoch_manager + .get_committee_info_by_validator_address(message.epoch, &from) + .await?; + + if local_committee_info.shard_group() == foreign_committee_info.shard_group() { + warn!( + target: LOG_TARGET, + "❓️ FOREIGN PROPOSAL: Received foreign proposal notification from a validator in the same shard group. Ignoring." + ); + return Ok(()); + } + + let f = local_committee_info.max_failures() as usize; + let committee = self + .epoch_manager + .get_committee_by_shard_group(current_epoch, foreign_committee_info.shard_group(), Some(f + 1)) + .await?; + + let Some((selected, _)) = committee.shuffled().next() else { + warn!( + target: LOG_TARGET, + "FOREIGN PROPOSAL: No validator selected for the shard group {}", + foreign_committee_info.shard_group(), + ); + return Ok(()); + }; + + info!( + target: LOG_TARGET, + "🌐 REQUEST foreign proposal for block {} from {}", + message.block_id, + selected, + ); + self.outbound_messaging + .send( + selected.clone(), + HotstuffMessage::ForeignProposalRequest(ForeignProposalRequestMessage::ByBlockId { + block_id: message.block_id, + for_shard_group: local_committee_info.shard_group(), + epoch: message.epoch, + }), + ) + .await?; + + Ok(()) + } + + pub async fn handle_requested( + &mut self, + from: TConsensusSpec::Addr, + message: ForeignProposalRequestMessage, + local_committee_info: &CommitteeInfo, + ) -> Result<(), HotStuffError> { + match message { + ForeignProposalRequestMessage::ByBlockId { + block_id, + for_shard_group, + .. + } => { + let (block, justify_qc, mut block_pledge) = self.store.with_read_tx(|tx| { + let block = Block::get(tx, &block_id)?; + let justify_qc = QuorumCertificate::get_by_block_id(tx, &block_id)?; + let block_pledge = block.get_block_pledge(tx)?; + Ok::<_, HotStuffError>((block, justify_qc, block_pledge)) + })?; + + info!( + target: LOG_TARGET, + "🌐 REPLY foreign proposal {} to {}. justify: {} ({}), parent: {}", + block, + for_shard_group, + justify_qc.block_id(), + justify_qc.block_height(), + block.parent() + ); + + let applicable_transactions = block + .commands() + .iter() + .filter_map(|c| { + c.local_prepare() + // No need to broadcast LocalPrepare if the committee is output only + .filter(|atom| !atom.evidence.is_committee_output_only(local_committee_info)) + .or_else(|| c.local_accept()) + }) + .filter(|atom| { + atom.evidence + .shard_groups_iter() + .any(|shard_group| *shard_group == for_shard_group) + }) + .map(|atom| atom.id) + .collect(); + + // Only send the pledges for the involved shard group that requested them + block_pledge.retain_transactions(&applicable_transactions); + + self.outbound_messaging + .send( + from, + HotstuffMessage::ForeignProposal(ForeignProposalMessage { + block, + justify_qc, + block_pledge, + }), + ) + .await?; + }, + ForeignProposalRequestMessage::ByTransactionId { .. } => { + error!( + target: LOG_TARGET, + "TODO FOREIGN PROPOSAL: Request by transaction id is not supported. Ignoring." + ); + }, + } + + Ok(()) + } + pub fn validate_and_save( &self, tx: &mut ::WriteTransaction<'_>, 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 baf435000..5ce3eeae3 100644 --- a/dan_layer/consensus/src/hotstuff/on_receive_local_proposal.rs +++ b/dan_layer/consensus/src/hotstuff/on_receive_local_proposal.rs @@ -48,12 +48,11 @@ use crate::{ HotstuffEvent, ProposalValidationError, }, - messages::{ForeignProposalMessage, HotstuffMessage, NewViewMessage, ProposalMessage, VoteMessage}, + messages::{ForeignProposalNotificationMessage, HotstuffMessage, NewViewMessage, ProposalMessage, VoteMessage}, tracing::TraceTimer, traits::{ hooks::ConsensusHooks, ConsensusSpec, - LeaderStrategy, OutboundMessaging, ValidatorSignatureService, VoteSignatureService, @@ -103,10 +102,15 @@ impl OnReceiveLocalProposalHandler OnReceiveLocalProposalHandler, msg: ProposalMessage, - ) -> Result<(), HotStuffError> { + ) -> Result { let _timer = TraceTimer::debug(LOG_TARGET, "OnReceiveLocalProposalHandler"); // Do not trigger leader failures while processing a proposal. @@ -149,12 +153,12 @@ impl OnReceiveLocalProposalHandler OnReceiveLocalProposalHandler OnReceiveLocalProposalHandler OnReceiveLocalProposalHandler Ok(()), + Ok(is_accept) => Ok(is_accept), Err(err) => { if let Err(err) = self.pacemaker.resume_leader_failure().await { error!(target: LOG_TARGET, "Error resuming leader failure: {:?}", err); @@ -250,7 +254,7 @@ impl OnReceiveLocalProposalHandler, valid_block: ValidBlock, foreign_committees: HashMap, - ) -> Result<(), HotStuffError> { + ) -> Result { let em_epoch = self.epoch_manager.current_epoch().await?; let can_propose_epoch_end = em_epoch > current_epoch; let is_epoch_end = valid_block.block().is_epoch_end(); @@ -412,7 +416,7 @@ impl OnReceiveLocalProposalHandler OnReceiveLocalProposalHandler( self.epoch_manager.clone(), - self.leader_strategy.clone(), self.outbound_messaging.clone(), - self.store.clone(), self.config.consensus_constants.num_preshards, local_committee_info, blocks, @@ -765,15 +767,21 @@ impl OnReceiveLocalProposalHandler OnReceiveLocalProposalHandler OnReceiveLocalProposalHandler( epoch_manager: TConsensusSpec::EpochManager, - leader_strategy: TConsensusSpec::LeaderStrategy, outbound_messaging: TConsensusSpec::OutboundMessaging, - store: TConsensusSpec::StateStore, num_preshards: NumPreshards, local_committee_info: CommitteeInfo, blocks: Vec<(Block, QuorumCertificate)>, ) { - let _timer = TraceTimer::debug(LOG_TARGET, "ProposeNewlyLockedBlocks").with_iterations(blocks.len()); + let _timer = TraceTimer::debug(LOG_TARGET, "propose_newly_locked_blocks_task").with_iterations(blocks.len()); if let Err(err) = propose_newly_locked_blocks_task_inner::( epoch_manager, - leader_strategy, outbound_messaging, - store, num_preshards, &local_committee_info, blocks, @@ -895,54 +899,21 @@ async fn propose_newly_locked_blocks_task( async fn propose_newly_locked_blocks_task_inner( epoch_manager: TConsensusSpec::EpochManager, - leader_strategy: TConsensusSpec::LeaderStrategy, mut outbound_messaging: TConsensusSpec::OutboundMessaging, - store: TConsensusSpec::StateStore, num_preshards: NumPreshards, local_committee_info: &CommitteeInfo, blocks: Vec<(Block, QuorumCertificate)>, ) -> Result<(), HotStuffError> { for (block, justify_qc) in blocks.into_iter().rev() { - debug!(target:LOG_TARGET,"Checking if we need to broadcast the new locked block: {block}"); - let Some(our_vn) = epoch_manager.get_our_validator_node(block.epoch()).await.optional()? else { - info!( - target: LOG_TARGET, - "❌ Our validator node is not registered for epoch {}. Not proposing {block} to foreign committee", block.epoch(), - ); - continue; - }; - - let local_committee = epoch_manager - .get_committee_by_validator_public_key(block.epoch(), block.proposed_by().clone()) - .await?; - let leader_index = leader_strategy.calculate_leader(&local_committee, block.height()) as usize; - let my_index = local_committee - .addresses() - .position(|addr| *addr == our_vn.address) - .ok_or_else(|| HotStuffError::InvariantError("Our address not found in local committee".to_string()))?; - // There are other ways to approach this. But for simplicity, it is better just to make sure at least one - // honest node will send it to the whole foreign committee. So we select the leader and f other - // nodes. It has to be deterministic so we select by index (leader, leader+1, ..., leader+f). - // f+1 nodes (including the leader) send the proposal to the foreign committee - - let should_broadcast = if my_index >= leader_index { - my_index - leader_index <= local_committee.len() / 3 - } else { - my_index + local_committee.len() - leader_index <= local_committee.len() / 3 - }; - - if should_broadcast { - broadcast_foreign_proposal_if_required::( - &mut outbound_messaging, - &epoch_manager, - &store, - num_preshards, - local_committee_info, - block, - justify_qc, - ) - .await?; - } + broadcast_foreign_proposal_if_required::( + &mut outbound_messaging, + &epoch_manager, + num_preshards, + local_committee_info, + block, + justify_qc, + ) + .await?; } Ok(()) } @@ -950,7 +921,6 @@ async fn propose_newly_locked_blocks_task_inner( async fn broadcast_foreign_proposal_if_required( outbound_messaging: &mut TConsensusSpec::OutboundMessaging, epoch_manager: &TConsensusSpec::EpochManager, - store: &TConsensusSpec::StateStore, num_preshards: NumPreshards, local_committee_info: &CommitteeInfo, block: Block, @@ -973,6 +943,11 @@ async fn broadcast_foreign_proposal_if_required( .filter(|shard_group| local_shard_group != *shard_group) .collect::>(); if non_local_shard_groups.is_empty() { + debug!( + target: LOG_TARGET, + "🌐 No foreign shards involved for new locked block {}", + block, + ); return Ok(()); } info!( @@ -985,40 +960,30 @@ async fn broadcast_foreign_proposal_if_required( block.parent() ); - let block_pledge = store - .with_read_tx(|tx| block.get_block_pledge(tx)) - .optional()? - .ok_or_else(|| HotStuffError::InvariantError(format!("Pledges not found for block {}", block)))?; - - // TODO(perf/message-size): the pledges for a given foreign proposal are not necessarily the same for each shard - // group involved in the block. Currently we send all pledges to all shard groups but we could limit the - // substates we send to validators to only those that are applicable to the transactions that involve - // them. - - // TODO(perf): fetch only applicable committee addresses - for shard_group in non_local_shard_groups { info!( target: LOG_TARGET, - "🌐 FOREIGN PROPOSE: Broadcasting locked block {} with {} pledge(s) to shard group {}.", + "🌐 FOREIGN PROPOSE: Broadcasting locked block foreign {} notification to shard group {}.", &block, - &block_pledge.num_substates_pledged(), shard_group, ); - - // TODO: This message can be much larger than the default maximum for gossipsub (16KiB) For now, the limit is - // increased. We also need to allow committees that are stuck on LocalAccept/LocalPrepare to request the - // foreign proposal through messaging. - outbound_messaging - .multicast( + if let Err(err) = outbound_messaging + .broadcast( shard_group, - HotstuffMessage::ForeignProposal(ForeignProposalMessage { - block: block.clone(), - block_pledge: block_pledge.clone(), - justify_qc: justify_qc.clone(), + HotstuffMessage::ForeignProposalNotification(ForeignProposalNotificationMessage { + block_id: *block.id(), + epoch: block.epoch(), }), ) - .await?; + .await + { + error!( + target: LOG_TARGET, + "❌ Error broadcasting foreign proposal notification to shard group {}: {}", + shard_group, + err + ); + } } Ok(()) diff --git a/dan_layer/consensus/src/hotstuff/on_receive_new_transaction.rs b/dan_layer/consensus/src/hotstuff/on_receive_new_transaction.rs index f084c4ff9..fb907147f 100644 --- a/dan_layer/consensus/src/hotstuff/on_receive_new_transaction.rs +++ b/dan_layer/consensus/src/hotstuff/on_receive_new_transaction.rs @@ -18,7 +18,7 @@ use crate::{ traits::{BlockTransactionExecutor, ConsensusSpec}, }; -const LOG_TARGET: &str = "tari::dan::consensus::hotstuff::on_receive_requested_transactions"; +const LOG_TARGET: &str = "tari::dan::consensus::hotstuff::on_receive_new_transaction"; pub struct OnReceiveNewTransaction { store: TConsensusSpec::StateStore, @@ -126,7 +126,6 @@ where TConsensusSpec: ConsensusSpec ); rec.set_abort_reason(RejectReason::InvalidTransaction(err.to_string())) .save(tx)?; - // self.add_to_pool(tx, &rec, true)?; return Ok(Some((rec, true))); } @@ -137,6 +136,14 @@ where TConsensusSpec: ConsensusSpec let has_some_local_inputs_or_all_foreign_inputs = rec.has_any_local_inputs(local_committee_info) || rec.has_all_foreign_input_pledges(&**tx, local_committee_info)?; + if !has_some_local_inputs_or_all_foreign_inputs { + debug!( + target: LOG_TARGET, + "Transaction {} has no local inputs or all foreign inputs. Will sequence once we have received the LocalAccept foreign proposal.", + rec.id() + ); + } + Ok(Some((rec, has_some_local_inputs_or_all_foreign_inputs))) } diff --git a/dan_layer/consensus/src/hotstuff/on_receive_new_view.rs b/dan_layer/consensus/src/hotstuff/on_receive_new_view.rs index 019b83e5e..c2c63f0d0 100644 --- a/dan_layer/consensus/src/hotstuff/on_receive_new_view.rs +++ b/dan_layer/consensus/src/hotstuff/on_receive_new_view.rs @@ -17,6 +17,7 @@ use tari_dan_storage::{ use super::vote_collector::VoteCollector; use crate::{ + block_validations::check_quorum_certificate, hotstuff::{error::HotStuffError, pacemaker_handle::PaceMakerHandle}, messages::NewViewMessage, tracing::TraceTimer, @@ -103,9 +104,17 @@ where TConsensusSpec: ConsensusSpec return Ok(()); } - self.store.with_read_tx(|tx| { - self.validate_qc(&high_qc)?; + if let Err(err) = self.validate_qc( + &high_qc, + local_committee, + local_committee_info, + self.vote_collector.signing_service(), + ) { + warn!(target: LOG_TARGET, "❌ NEWVIEW: Invalid QC: {}", err); + return Ok(()); + } + self.store.with_read_tx(|tx| { if !Block::record_exists(tx, high_qc.block_id())? { // Sync if we do not have the block for this valid QC let local_height = LeafBlock::get(tx, current_epoch) @@ -144,6 +153,7 @@ where TConsensusSpec: ConsensusSpec return Ok(()); } + let has_vote = last_vote.is_some(); if let Some(vote) = last_vote { debug!( target: LOG_TARGET, @@ -171,7 +181,8 @@ where TConsensusSpec: ConsensusSpec info!( target: LOG_TARGET, - "🌟 Received NEWVIEW (QUORUM: {}/{}) {} with high {}", + "🌟 Received NEWVIEW (has_vote={}) (QUORUM: {}/{}) {} with high {}", + has_vote, newview_count, threshold, new_height, @@ -192,8 +203,14 @@ where TConsensusSpec: ConsensusSpec Ok(()) } - fn validate_qc(&self, _qc: &QuorumCertificate) -> Result<(), HotStuffError> { - // TODO + fn validate_qc( + &self, + qc: &QuorumCertificate, + committee: &Committee, + committee_info: &CommitteeInfo, + vote_signing_service: &TConsensusSpec::SignatureService, + ) -> Result<(), HotStuffError> { + check_quorum_certificate::(qc, committee, committee_info, vote_signing_service)?; Ok(()) } } diff --git a/dan_layer/consensus/src/hotstuff/state_machine/idle.rs b/dan_layer/consensus/src/hotstuff/state_machine/idle.rs index c5577aab3..339e0e30a 100644 --- a/dan_layer/consensus/src/hotstuff/state_machine/idle.rs +++ b/dan_layer/consensus/src/hotstuff/state_machine/idle.rs @@ -1,12 +1,12 @@ // Copyright 2023 The Tari Project // SPDX-License-Identifier: BSD-3-Clause -use std::marker::PhantomData; +use std::{marker::PhantomData, time::Duration}; use log::*; use tari_dan_common_types::Epoch; use tari_epoch_manager::{EpochManagerEvent, EpochManagerReader}; -use tokio::sync::broadcast; +use tokio::{sync::broadcast, time}; use crate::{ hotstuff::{ @@ -19,19 +19,35 @@ use crate::{ const LOG_TARGET: &str = "tari::dan::consensus::sm::idle"; #[derive(Debug, Clone)] -pub struct Idle(PhantomData); +pub struct Idle { + _spec: PhantomData, + delay: bool, +} impl Idle where TSpec: ConsensusSpec { pub fn new() -> Self { - Self(PhantomData) + Self { + _spec: PhantomData, + delay: false, + } + } + + pub fn with_delay() -> Self { + Self { + _spec: PhantomData, + delay: true, + } } pub(super) async fn on_enter( &self, context: &mut ConsensusWorkerContext, ) -> Result { + if self.delay { + time::sleep(Duration::from_secs(5)).await; + } // Subscribe before checking if we're registered to eliminate the chance that we miss the epoch event let mut epoch_events = context.epoch_manager.subscribe(); context.epoch_manager.wait_for_initial_scanning_to_complete().await?; diff --git a/dan_layer/consensus/src/hotstuff/state_machine/worker.rs b/dan_layer/consensus/src/hotstuff/state_machine/worker.rs index 4c9bfaa7b..65b1126f8 100644 --- a/dan_layer/consensus/src/hotstuff/state_machine/worker.rs +++ b/dan_layer/consensus/src/hotstuff/state_machine/worker.rs @@ -25,6 +25,7 @@ const LOG_TARGET: &str = "tari::dan::consensus::sm::worker"; #[derive(Debug)] pub struct ConsensusWorker { pub(super) shutdown_signal: ShutdownSignal, + initial_delay: bool, _spec: PhantomData, } @@ -44,10 +45,16 @@ where pub fn new(shutdown_signal: ShutdownSignal) -> Self { Self { shutdown_signal, + initial_delay: true, _spec: PhantomData, } } + pub fn no_initial_delay(mut self) -> Self { + self.initial_delay = false; + self + } + async fn next_event( &self, context: &mut ConsensusWorkerContext, @@ -114,8 +121,14 @@ where pub async fn run(&mut self, mut context: ConsensusWorkerContext) { // When starting up we will wait a bit. - // Context: in swarm, we start on epoch 2, then quickly go to epoch 3. - let mut state = ConsensusState::Idle(Idle::new()); + // Context: in swarm, we start on epoch 2, then quickly go to epoch 3. This causes some nodes to start consensus + // on epoch 2 and some on epoch 3. + let idle = if self.initial_delay { + Idle::with_delay() + } else { + Idle::new() + }; + let mut state = ConsensusState::Idle(idle); loop { let next_event = self.next_event(&mut context, &state).await; state = self.transition(state, next_event); diff --git a/dan_layer/consensus/src/hotstuff/substate_store/pending_store.rs b/dan_layer/consensus/src/hotstuff/substate_store/pending_store.rs index 633c5a28b..d1fdc9040 100644 --- a/dan_layer/consensus/src/hotstuff/substate_store/pending_store.rs +++ b/dan_layer/consensus/src/hotstuff/substate_store/pending_store.rs @@ -339,6 +339,7 @@ impl<'a, 'tx, TStore: StateStore + 'a + 'tx> PendingSubstateStore<'a, 'tx, TStor existing_lock: existing.substate_lock(), requested_lock: requested_lock_type, transaction_id: *existing.transaction_id(), + is_local_only: has_local_only_rules, }, } .into()); @@ -372,6 +373,7 @@ impl<'a, 'tx, TStore: StateStore + 'a + 'tx> PendingSubstateStore<'a, 'tx, TStor existing_lock: existing.substate_lock(), requested_lock: requested_lock_type, transaction_id: *existing.transaction_id(), + is_local_only: false, }, } .into()); @@ -392,6 +394,7 @@ impl<'a, 'tx, TStore: StateStore + 'a + 'tx> PendingSubstateStore<'a, 'tx, TStor existing_lock: existing.substate_lock(), requested_lock: requested_lock_type, transaction_id: *existing.transaction_id(), + is_local_only: has_local_only_rules, }, } .into()); @@ -425,6 +428,7 @@ impl<'a, 'tx, TStore: StateStore + 'a + 'tx> PendingSubstateStore<'a, 'tx, TStor existing_lock: existing.substate_lock(), requested_lock: requested_lock_type, transaction_id: *existing.transaction_id(), + is_local_only: has_local_only_rules, }, } .into()); @@ -445,6 +449,7 @@ impl<'a, 'tx, TStore: StateStore + 'a + 'tx> PendingSubstateStore<'a, 'tx, TStor existing_lock: existing.substate_lock(), requested_lock: requested_lock_type, transaction_id: *existing.transaction_id(), + is_local_only: has_local_only_rules, }, } .into()); diff --git a/dan_layer/consensus/src/hotstuff/vote_collector.rs b/dan_layer/consensus/src/hotstuff/vote_collector.rs index 0d7aa6673..d96ae403f 100644 --- a/dan_layer/consensus/src/hotstuff/vote_collector.rs +++ b/dan_layer/consensus/src/hotstuff/vote_collector.rs @@ -46,6 +46,10 @@ where TConsensusSpec: ConsensusSpec } } + pub fn signing_service(&self) -> &TConsensusSpec::SignatureService { + &self.vote_signature_service + } + /// Returns Some if quorum is reached pub async fn check_and_collect_vote( &self, diff --git a/dan_layer/consensus/src/hotstuff/worker.rs b/dan_layer/consensus/src/hotstuff/worker.rs index 21f3e8d09..9614223f5 100644 --- a/dan_layer/consensus/src/hotstuff/worker.rs +++ b/dan_layer/consensus/src/hotstuff/worker.rs @@ -169,6 +169,7 @@ impl HotstuffWorker { state_store.clone(), epoch_manager.clone(), pacemaker.clone_handle(), + outbound_messaging.clone(), ), on_receive_vote: OnReceiveVoteHandler::new(pacemaker.clone_handle(), vote_receiver.clone()), on_receive_new_view: OnReceiveNewViewHandler::new( @@ -530,7 +531,11 @@ impl HotstuffWorker { let is_any_block_unparked = !local_proposals.is_empty() || !foreign_proposals.is_empty(); for msg in foreign_proposals { - if let Err(e) = self.on_receive_foreign_proposal.handle(msg, local_committee_info).await { + if let Err(e) = self + .on_receive_foreign_proposal + .handle_received(msg, local_committee_info) + .await + { self.on_failure("check_if_block_can_be_unparked -> on_receive_foreign_proposal", &e) .await; return Err(e); @@ -539,7 +544,13 @@ impl HotstuffWorker { for msg in local_proposals { if let Err(e) = self - .on_proposal_message(current_epoch, *local_committee_info, local_committee, msg) + .on_proposal_message( + current_epoch, + current_height, + local_committee_info, + local_committee, + msg, + ) .await { self.on_failure("check_if_block_can_be_unparked -> on_proposal_message", &e) @@ -827,12 +838,32 @@ impl HotstuffWorker { ), HotstuffMessage::Proposal(msg) => log_err( "on_receive_local_proposal", - self.on_proposal_message(current_epoch, *local_committee_info, local_committee, msg) - .await, + self.on_proposal_message( + current_epoch, + current_height, + local_committee_info, + local_committee, + msg, + ) + .await, ), HotstuffMessage::ForeignProposal(msg) => log_err( - "on_receive_foreign_proposal", - self.on_receive_foreign_proposal.handle(msg, local_committee_info).await, + "on_receive_foreign_proposal (received)", + self.on_receive_foreign_proposal + .handle_received(msg, local_committee_info) + .await, + ), + HotstuffMessage::ForeignProposalNotification(msg) => log_err( + "on_receive_foreign_proposal (notification)", + self.on_receive_foreign_proposal + .handle_notification_received(from, current_epoch, msg, local_committee_info) + .await, + ), + HotstuffMessage::ForeignProposalRequest(msg) => log_err( + "on_receive_foreign_proposal (request)", + self.on_receive_foreign_proposal + .handle_requested(from, msg, local_committee_info) + .await, ), HotstuffMessage::Vote(msg) => log_err( "on_receive_vote", @@ -868,7 +899,8 @@ impl HotstuffWorker { async fn on_proposal_message( &mut self, current_epoch: Epoch, - local_committee_info: CommitteeInfo, + current_height: NodeHeight, + local_committee_info: &CommitteeInfo, local_committee: &Committee, msg: ProposalMessage, ) -> Result<(), HotStuffError> { @@ -879,7 +911,12 @@ impl HotstuffWorker { .handle(current_epoch, local_committee_info, local_committee, msg) .await, ) { - Ok(_) => Ok(()), + Ok(true) => Ok(()), + Ok(false) => { + // We decided NOVOTE, so we immediately send a NEWVIEW + self.on_leader_timeout(current_epoch, current_height, local_committee) + .await + }, Err(err @ HotStuffError::ProposalValidationError(ProposalValidationError::JustifyBlockNotFound { .. })) => { let vn = self .epoch_manager diff --git a/dan_layer/consensus/src/lib.rs b/dan_layer/consensus/src/lib.rs index 9373f84f0..125ef4825 100644 --- a/dan_layer/consensus/src/lib.rs +++ b/dan_layer/consensus/src/lib.rs @@ -7,6 +7,3 @@ pub mod hotstuff; pub mod messages; mod tracing; pub mod traits; - -#[cfg(test)] -mod test_helpers; diff --git a/dan_layer/consensus/src/messages/foreign_proposal.rs b/dan_layer/consensus/src/messages/foreign_proposal.rs new file mode 100644 index 000000000..6decfdc9e --- /dev/null +++ b/dan_layer/consensus/src/messages/foreign_proposal.rs @@ -0,0 +1,141 @@ +// Copyright 2023 The Tari Project +// SPDX-License-Identifier: BSD-3-Clause + +use std::fmt::{Display, Formatter}; + +use serde::Serialize; +use tari_dan_common_types::{Epoch, ShardGroup}; +use tari_dan_storage::consensus_models::{ + Block, + BlockId, + BlockPledge, + ForeignParkedProposal, + ForeignProposal, + QuorumCertificate, +}; +use tari_transaction::TransactionId; + +#[derive(Debug, Clone, Serialize)] +pub struct ForeignProposalMessage { + pub block: Block, + pub justify_qc: QuorumCertificate, + pub block_pledge: BlockPledge, +} + +impl From for ForeignParkedProposal { + fn from(msg: ForeignProposalMessage) -> Self { + ForeignParkedProposal::new(msg.into()) + } +} + +impl From for ForeignProposal { + fn from(msg: ForeignProposalMessage) -> Self { + ForeignProposal::new(msg.block, msg.block_pledge, msg.justify_qc) + } +} + +impl From for ForeignProposalMessage { + fn from(proposal: ForeignProposal) -> Self { + ForeignProposalMessage { + block: proposal.block, + justify_qc: proposal.justify_qc, + block_pledge: proposal.block_pledge, + } + } +} + +impl From for ForeignProposalMessage { + fn from(proposal: ForeignParkedProposal) -> Self { + let proposal = proposal.into_proposal(); + ForeignProposalMessage { + block: proposal.block, + justify_qc: proposal.justify_qc, + block_pledge: proposal.block_pledge, + } + } +} + +impl Display for ForeignProposalMessage { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + write!( + f, + "ForeignProposalMessage({}, {}, {} pledged substate(s))", + self.block, + self.justify_qc, + self.block_pledge.num_substates_pledged() + ) + } +} + +#[derive(Debug, Clone, Serialize)] +pub struct ForeignProposalNotificationMessage { + pub block_id: BlockId, + pub epoch: Epoch, +} + +impl Display for ForeignProposalNotificationMessage { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + write!( + f, + "ForeignProposalNotificationMessage({}, {})", + self.epoch, self.block_id + ) + } +} + +#[derive(Debug, Clone, Serialize)] +pub enum ForeignProposalRequestMessage { + /// Request a foreign proposal for a specific block ID in response to a ForeignProposalNotificationMessage that has + /// not already been received. + ByBlockId { + block_id: BlockId, + /// The shard group to return pledges for + for_shard_group: ShardGroup, + epoch: Epoch, + }, + /// Request a foreign proposal for a specific transaction ID. This is used as a "bump" when a transaction is + /// reached LocalPrepared but the foreign proposal has not yet been received after some time. + ByTransactionId { + transaction_id: TransactionId, + for_shard_group: ShardGroup, + epoch: Epoch, + }, +} + +impl ForeignProposalRequestMessage { + pub fn epoch(&self) -> Epoch { + match self { + Self::ByBlockId { epoch, .. } => *epoch, + Self::ByTransactionId { epoch, .. } => *epoch, + } + } +} + +impl Display for ForeignProposalRequestMessage { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + match self { + Self::ByBlockId { + block_id, + for_shard_group, + epoch, + } => { + write!( + f, + "ForeignProposalRequestMessage(ByBlockId, {}, {}, {})", + epoch, for_shard_group, block_id + ) + }, + Self::ByTransactionId { + transaction_id, + for_shard_group, + epoch, + } => { + write!( + f, + "ForeignProposalRequestMessage(ByTransactionId, {}, {}, {})", + epoch, for_shard_group, transaction_id + ) + }, + } + } +} diff --git a/dan_layer/consensus/src/messages/message.rs b/dan_layer/consensus/src/messages/message.rs index f920df8df..3394ad4bd 100644 --- a/dan_layer/consensus/src/messages/message.rs +++ b/dan_layer/consensus/src/messages/message.rs @@ -6,7 +6,15 @@ use std::fmt::Display; use serde::Serialize; use tari_dan_common_types::Epoch; -use super::{ForeignProposalMessage, MissingTransactionsResponse, NewViewMessage, ProposalMessage, VoteMessage}; +use super::{ + ForeignProposalMessage, + ForeignProposalNotificationMessage, + ForeignProposalRequestMessage, + MissingTransactionsResponse, + NewViewMessage, + ProposalMessage, + VoteMessage, +}; use crate::messages::{MissingTransactionsRequest, SyncRequestMessage, SyncResponseMessage}; // Serialize is implemented for the message logger @@ -15,6 +23,8 @@ pub enum HotstuffMessage { NewView(NewViewMessage), Proposal(ProposalMessage), ForeignProposal(ForeignProposalMessage), + ForeignProposalNotification(ForeignProposalNotificationMessage), + ForeignProposalRequest(ForeignProposalRequestMessage), Vote(VoteMessage), MissingTransactionsRequest(MissingTransactionsRequest), MissingTransactionsResponse(MissingTransactionsResponse), @@ -26,14 +36,16 @@ pub enum HotstuffMessage { impl HotstuffMessage { pub fn as_type_str(&self) -> &'static str { match self { - HotstuffMessage::NewView(_) => "NewView", - HotstuffMessage::Proposal(_) => "Proposal", - HotstuffMessage::ForeignProposal(_) => "ForeignProposal", - HotstuffMessage::Vote(_) => "Vote", - HotstuffMessage::MissingTransactionsRequest(_) => "MissingTransactionsRequest", - HotstuffMessage::MissingTransactionsResponse(_) => "MissingTransactionsResponse", - HotstuffMessage::CatchUpSyncRequest(_) => "CatchUpSyncRequest", - HotstuffMessage::SyncResponse(_) => "SyncResponse", + Self::NewView(_) => "NewView", + Self::Proposal(_) => "Proposal", + Self::ForeignProposal(_) => "ForeignProposal", + Self::ForeignProposalNotification(_) => "ForeignProposalNotification", + Self::ForeignProposalRequest(_) => "ForeignProposalRequest", + Self::Vote(_) => "Vote", + Self::MissingTransactionsRequest(_) => "MissingTransactionsRequest", + Self::MissingTransactionsResponse(_) => "MissingTransactionsResponse", + Self::CatchUpSyncRequest(_) => "CatchUpSyncRequest", + Self::SyncResponse(_) => "SyncResponse", } } @@ -42,6 +54,8 @@ impl HotstuffMessage { Self::NewView(msg) => msg.high_qc.epoch(), Self::Proposal(msg) => msg.block.epoch(), Self::ForeignProposal(msg) => msg.block.epoch(), + Self::ForeignProposalNotification(msg) => msg.epoch, + Self::ForeignProposalRequest(msg) => msg.epoch(), Self::Vote(msg) => msg.epoch, Self::MissingTransactionsRequest(msg) => msg.epoch, Self::MissingTransactionsResponse(msg) => msg.epoch, @@ -80,6 +94,8 @@ impl Display for HotstuffMessage { ) }, HotstuffMessage::ForeignProposal(msg) => write!(f, "ForeignProposal({})", msg), + HotstuffMessage::ForeignProposalNotification(msg) => write!(f, "ForeignProposalNotification({})", msg), + HotstuffMessage::ForeignProposalRequest(msg) => write!(f, "ForeignProposalRequest({})", msg), HotstuffMessage::Vote(msg) => write!( f, "Vote({}, {}, {}, {})", diff --git a/dan_layer/consensus/src/messages/mod.rs b/dan_layer/consensus/src/messages/mod.rs index eab49ccd8..4155b0c56 100644 --- a/dan_layer/consensus/src/messages/mod.rs +++ b/dan_layer/consensus/src/messages/mod.rs @@ -9,6 +9,9 @@ pub use new_view::*; mod proposal; pub use proposal::*; +mod foreign_proposal; +pub use foreign_proposal::*; + mod vote; pub use vote::*; @@ -19,4 +22,5 @@ mod requested_transaction; pub use requested_transaction::*; mod sync; + pub use sync::*; diff --git a/dan_layer/consensus/src/messages/proposal.rs b/dan_layer/consensus/src/messages/proposal.rs index 64a8f9738..6fd16c892 100644 --- a/dan_layer/consensus/src/messages/proposal.rs +++ b/dan_layer/consensus/src/messages/proposal.rs @@ -4,13 +4,7 @@ use std::fmt::{Display, Formatter}; use serde::Serialize; -use tari_dan_storage::consensus_models::{ - Block, - BlockPledge, - ForeignParkedProposal, - ForeignProposal, - QuorumCertificate, -}; +use tari_dan_storage::consensus_models::{Block, ForeignProposal}; #[derive(Debug, Clone, Serialize)] pub struct ProposalMessage { @@ -23,55 +17,3 @@ impl Display for ProposalMessage { write!(f, "ProposalMessage({})", self.block) } } - -#[derive(Debug, Clone, Serialize)] -pub struct ForeignProposalMessage { - pub block: Block, - pub justify_qc: QuorumCertificate, - pub block_pledge: BlockPledge, -} - -impl From for ForeignParkedProposal { - fn from(msg: ForeignProposalMessage) -> Self { - ForeignParkedProposal::new(msg.into()) - } -} - -impl From for ForeignProposal { - fn from(msg: ForeignProposalMessage) -> Self { - ForeignProposal::new(msg.block, msg.block_pledge, msg.justify_qc) - } -} - -impl From for ForeignProposalMessage { - fn from(proposal: ForeignProposal) -> Self { - ForeignProposalMessage { - block: proposal.block, - justify_qc: proposal.justify_qc, - block_pledge: proposal.block_pledge, - } - } -} - -impl From for ForeignProposalMessage { - fn from(proposal: ForeignParkedProposal) -> Self { - let proposal = proposal.into_proposal(); - ForeignProposalMessage { - block: proposal.block, - justify_qc: proposal.justify_qc, - block_pledge: proposal.block_pledge, - } - } -} - -impl Display for ForeignProposalMessage { - fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { - write!( - f, - "ForeignProposalMessage({}, {}, {} pledged substate(s))", - self.block, - self.justify_qc, - self.block_pledge.num_substates_pledged() - ) - } -} diff --git a/dan_layer/consensus/src/traits/messaging.rs b/dan_layer/consensus/src/traits/messaging.rs index 87126ecec..e9e2d7da2 100644 --- a/dan_layer/consensus/src/traits/messaging.rs +++ b/dan_layer/consensus/src/traits/messaging.rs @@ -26,21 +26,38 @@ use tari_dan_common_types::{NodeAddressable, ShardGroup}; use crate::messages::HotstuffMessage; +/// Defines outbound messaging capabilities for a consensus node pub trait OutboundMessaging { type Addr: NodeAddressable + Send + 'static; + /// Send a message to self fn send_self + Send>( &mut self, message: T, ) -> impl Future> + Send; + /// Send a message to a specific node fn send + Send>( &mut self, to: Self::Addr, message: T, ) -> impl Future> + Send; - fn multicast( + /// Send a direct message to all nodes in a shard group. Each message is separately queued and sent directly to each + /// node in a shard group. + fn multicast( + &mut self, + addresses: I, + message: T, + ) -> impl Future> + Send + where + I: IntoIterator + Send, + T: Into + Send; + + /// Broadcast/gossip a message to all nodes in a shard group. This is a best-effort broadcast and may not reach all + /// nodes. Since gossiped messages are sent and may be received multiple times, the message byte size should be + /// small e.g. <= `6KiB`. If the message is larger, consider using `multicast` instead. + fn broadcast( &mut self, shard_group: ShardGroup, message: T, diff --git a/dan_layer/consensus_tests/fixtures/block.json b/dan_layer/consensus_tests/fixtures/block.json new file mode 100644 index 000000000..8ed242d5e --- /dev/null +++ b/dan_layer/consensus_tests/fixtures/block.json @@ -0,0 +1,237 @@ +{ + "header": { + "id": "1cdbe5c1a894bcc254b47cf017d4d17608839b7048d1c02162bccd39e7635288", + "network": "localnet", + "parent": "60e452539750d7d9c628f0b729f5a4ffb6a3f4343be734b230cf513bb21dbb53", + "justify_id": "5b8092cd68b5df33b27aeb2830a2a9a951f994536b9a22803bb567e08640e7c6", + "height": 66, + "epoch": 5, + "shard_group": { + "start": 0, + "end_inclusive": 255 + }, + "proposed_by": "5e13c16840aa8d2e7e68390d0eb1b45c86bc363db0419f7ec5daa534e63bdb35", + "total_leader_fee": 0, + "state_merkle_root": [ + 247, + 115, + 121, + 67, + 152, + 239, + 4, + 213, + 134, + 205, + 188, + 237, + 238, + 135, + 251, + 0, + 201, + 163, + 1, + 210, + 90, + 179, + 146, + 172, + 69, + 197, + 43, + 40, + 1, + 120, + 253, + 141 + ], + "command_merkle_root": [ + 231, + 9, + 182, + 13, + 242, + 171, + 86, + 197, + 164, + 182, + 2, + 28, + 201, + 247, + 92, + 220, + 138, + 31, + 216, + 74, + 157, + 216, + 74, + 61, + 1, + 17, + 255, + 134, + 70, + 63, + 96, + 59 + ], + "is_dummy": false, + "foreign_indexes": {}, + "signature": { + "public_nonce": "2846178a36d464460afc23c230cd5b5ed537fc214126e0ed4a2c972580068828", + "signature": "16f4be46fb4c5736e6b5be0771bf5e108c254a8cf28b2c407b089f466ec73305" + }, + "timestamp": 1732873628, + "base_layer_block_height": 50, + "base_layer_block_hash": [ + 25, + 244, + 181, + 192, + 179, + 56, + 148, + 2, + 152, + 84, + 182, + 233, + 186, + 146, + 40, + 18, + 183, + 41, + 1, + 114, + 211, + 244, + 142, + 109, + 211, + 160, + 8, + 20, + 68, + 17, + 58, + 112 + ], + "extra_data": {} + }, + "justify": { + "qc_id": "5b8092cd68b5df33b27aeb2830a2a9a951f994536b9a22803bb567e08640e7c6", + "block_id": "60e452539750d7d9c628f0b729f5a4ffb6a3f4343be734b230cf513bb21dbb53", + "header_hash": [ + 169, + 8, + 134, + 26, + 74, + 77, + 45, + 43, + 228, + 253, + 24, + 19, + 82, + 251, + 73, + 146, + 73, + 88, + 12, + 6, + 108, + 174, + 118, + 27, + 159, + 7, + 75, + 128, + 104, + 233, + 19, + 122 + ], + "parent_id": "75cd035fcf70444dfcd547f76838a8168c2e48bc7fd1217be05fcb28c4bf25dd", + "block_height": 65, + "epoch": 5, + "shard_group": { + "start": 0, + "end_inclusive": 255 + }, + "signatures": [ + { + "public_key": "5e13c16840aa8d2e7e68390d0eb1b45c86bc363db0419f7ec5daa534e63bdb35", + "signature": { + "public_nonce": "cabbbf993a27e0b55bb5bf80d24b49d70dc4199658d145a0f96ec96dc61a0e7f", + "signature": "34f7a9a5d97da003b0793a95277386146d2ce008b1e62e33ba27c93d8e376e03" + } + }, + { + "public_key": "048c457bddf93adc0cc7c8a934437cacb77998c2469bb2028b83d4e1d2ea344e", + "signature": { + "public_nonce": "aadeb13bfc9f164f06234e480dbdb243d87088e3b20d78da526ed2ca98ff9154", + "signature": "97c24ea6fb1f086b8dc403fc7edbcc0e785277e55e8d3416f20e667be8f8710a" + } + }, + { + "public_key": "f02cc332c74ac694bcfd1740896bae20d7d7d2676f1a5ae8ad9bce21f8156444", + "signature": { + "public_nonce": "9256b1b65e8abc1860fb960f97941e6fbe07710c09a56575493c97bf32d9a823", + "signature": "6c08e68e35dfd40d5a81d85b4f66c7ec631d8f2ea6ee7141228c3efcf4a99301" + } + }, + { + "public_key": "d6915bb1c499c289cdc78a0170e9649c1bc3e3534fa864cd3a6953f05a067e28", + "signature": { + "public_nonce": "8aaa7341a6de2dbcad79f9dd48f4e8da965d7aa9c45ee81a0517dabdeb087f0b", + "signature": "e796cb3da75a9ec9b6a6390f274e9260d584e021fa8b36a1cc9a58d9d72fc806" + } + }, + { + "public_key": "c8939413cbd8df92f65d7f9fd8316a55ca5e333e22a07f8041831a43eb20357b", + "signature": { + "public_nonce": "9ea60805e9e96686be87eaaed49b4ed1b2d41f263e81c76ba3353a29110bca50", + "signature": "e15c31cb1118cec1e9427fdabbb54fa5579b87f93e54493c6febcd620dc71a0e" + } + } + ], + "leaf_hashes": [ + "1a587fa378749abb7d246957dab8cd4b3325ab1270ca2eeeb1f41c575e3fe2e4", + "2ba1515d0b9ea4da1232672a9c1b0cf73f36dc82c96e74fb293f1d18365dda2f", + "4cd271e84e16899aee3ef451afcb00b1f141ff9b0aadaae61b63bf9d4fd7fb7f", + "506b980c526a79f8755acae1596917762ba171de32d1dbbcc576fcfae55e7619", + "6f1e1088364ee89c45a01cab358e55158fdb1eaf5f28702059c9316712100880" + ], + "decision": "Accept", + "is_shares_processed": true + }, + "commands": [ + { + "EvictNode": { + "public_key": "fac00ae089a2a49052fb232926ff88a0be1e3587ff0ed0620b55d83b53f05c31" + } + } + ], + "is_justified": true, + "is_committed": true, + "block_time": 9, + "stored_at": [ + 2024, + 334, + 9, + 47, + 8, + 0 + ] +} + diff --git a/dan_layer/consensus_tests/fixtures/block_with_dummies.json b/dan_layer/consensus_tests/fixtures/block_with_dummies.json new file mode 100644 index 000000000..76242cd7f --- /dev/null +++ b/dan_layer/consensus_tests/fixtures/block_with_dummies.json @@ -0,0 +1,181 @@ +{ + "header": { + "id": "5f90956e17e7ac2cec69543d0722311b15ce5abdfa6227da13e9fd7865fdb3fe", + "network": "localnet", + "parent": "9e8cb3302fc9b26e32f8456a8e5252b1c285220b0e181bba7d958eed8b20b5e9", + "justify_id": "58f12b31ec21f45134bd04f9324ac2f75e8df5609cb5fc6be20808de5160d6e8", + "height": 18, + "epoch": 5, + "shard_group": { + "start": 0, + "end_inclusive": 127 + }, + "proposed_by": "584b42ac801387ab50e4af50aaea63ff9cf0b4ae8fe199157e811b0eae67cf51", + "total_leader_fee": 0, + "state_merkle_root": [ + 148, + 230, + 207, + 171, + 24, + 199, + 113, + 53, + 144, + 42, + 67, + 232, + 117, + 53, + 209, + 153, + 79, + 181, + 98, + 14, + 179, + 234, + 76, + 224, + 195, + 203, + 225, + 131, + 82, + 24, + 121, + 84 + ], + "command_merkle_root": [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + ], + "is_dummy": false, + "foreign_indexes": {}, + "signature": { + "public_nonce": "7ccbbd21687bd38a1f42eb84ba814d9aa86d61a1c71725a5177ac21d8e7ecc0d", + "signature": "b5f697783b4b625caf0e1a90b36471805bdfae8f40ec8bfce3752fcf9e8c7a03" + }, + "timestamp": 1733818570, + "base_layer_block_height": 51, + "base_layer_block_hash": [ + 153, + 197, + 208, + 177, + 128, + 69, + 241, + 198, + 117, + 197, + 94, + 201, + 221, + 75, + 160, + 142, + 6, + 225, + 1, + 229, + 123, + 155, + 12, + 140, + 68, + 246, + 236, + 0, + 247, + 37, + 126, + 148 + ], + "extra_data": {} + }, + "justify": { + "qc_id": "58f12b31ec21f45134bd04f9324ac2f75e8df5609cb5fc6be20808de5160d6e8", + "block_id": "0000000000000000000000000000000000000000000000000000000000000000", + "header_hash": [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + ], + "parent_id": "0000000000000000000000000000000000000000000000000000000000000000", + "block_height": 0, + "epoch": 5, + "shard_group": { + "start": 0, + "end_inclusive": 127 + }, + "signatures": [], + "leaf_hashes": [], + "decision": "Accept", + "is_shares_processed": false + }, + "commands": [], + "is_justified": false, + "is_committed": false, + "block_time": null, + "stored_at": null +} diff --git a/dan_layer/consensus_tests/fixtures/committee.json b/dan_layer/consensus_tests/fixtures/committee.json new file mode 100644 index 000000000..17ef87bf5 --- /dev/null +++ b/dan_layer/consensus_tests/fixtures/committee.json @@ -0,0 +1,36 @@ +{ + "members": [ + [ + "12D3L7AUza5RLY6xxPYfcKbWPvSoP2iScUyAXBwWwt92WqTYt4gQ", + "381fe5f57fb1a780c9c21cf910caba25e2cf5ae1c72691870368b987039c8701" + ], + [ + "12D3L7AV61FufHRfY3A5SrxYiwia4Zq4XEEt1hQHTDkytMi52pPZ", + "88ddb65b4349ff60e3b9f69c5dcc6a3e6c51e1a4393e97eb1dbfcd40807f7e40" + ], + [ + "12D3L7AV2jepJr21tjy2kcfUZUkHD2sqqd8BAg2zrfjm1wt9wvjA", + "584b42ac801387ab50e4af50aaea63ff9cf0b4ae8fe199157e811b0eae67cf51" + ], + [ + "12D3L7AUz3VVR9YpAyFWDkqrT3oy3C5k2rrcwTiEzDPPo3RVn5WC", + "304a1c0f8681f3b133fcf3ed0443932a69a88735358f8b6ab01ea07fde35f275" + ], + [ + "12D3L7AVABSfUgLXTzmZhNYbqrnGzcoBQ2ZxoTBf5Rt6nqH7PiUq", + "c6e86deb61a147d94fe665363cb5f6fa18c01709169746fe3109edc4f66ec062" + ], + [ + "12D3L7AVBDL1yohJxRzq2nE3AEZZ76rg5DSnCtewmKo8g79MNMxy", + "d63fc33effb5088b6240f3f1d83a584e32bfcde84b676118979e03eae62d2506" + ], + [ + "12D3L7AV4DKJUKxEDcPcmPzruGVTjoQyY5HxPpQHg7mRmWrYADtA", + "6e3d251e83d6c256cb9816ef2da17539588eb12077532bd6acb60f1a9270707f" + ], + [ + "12D3L7AVDgi1YmAtwFPas7E2N3bhpq1KRyZgBV7B4GXpimaGK1ds", + "fafaaf78f615fe666628e421a8b54e4148d6430af28ed6d5e78caab9d004dd3a" + ] + ] +} diff --git a/dan_layer/consensus_tests/src/consensus.rs b/dan_layer/consensus_tests/src/consensus.rs index 028cbb4d2..062c43b00 100644 --- a/dan_layer/consensus_tests/src/consensus.rs +++ b/dan_layer/consensus_tests/src/consensus.rs @@ -11,7 +11,7 @@ use std::time::Duration; use tari_common_types::types::PrivateKey; -use tari_consensus::hotstuff::HotStuffError; +use tari_consensus::{hotstuff::HotStuffError, messages::HotstuffMessage}; use tari_dan_common_types::{optional::Optional, Epoch, LockIntent, NodeHeight, SubstateRequirement}; use tari_dan_storage::{ consensus_models::{ @@ -981,15 +981,19 @@ async fn leader_failure_node_goes_down() { async fn foreign_block_distribution() { setup_logger(); let mut test = Test::builder() + .debug_sql("/tmp/test{}.db") .with_test_timeout(Duration::from_secs(60)) - .with_message_filter(Box::new(move |from: &TestAddress, to: &TestAddress, _| { - match from.0.as_str() { - // We filter our message from each leader to the foreign committees. So we will rely on other members of - // the local committees to send the message to the foreign committee members. And then on - // the distribution within the foreign committee. - "1" => *to == TestAddress::new("1") || *to == TestAddress::new("2") || *to == TestAddress::new("3"), - "4" => *to == TestAddress::new("4") || *to == TestAddress::new("5") || *to == TestAddress::new("6"), - "7" => *to == TestAddress::new("7") || *to == TestAddress::new("8") || *to == TestAddress::new("9"), + .with_message_filter(Box::new(move |from: &TestAddress, to: &TestAddress, msg| { + if !matches!(msg, HotstuffMessage::ForeignProposalNotification(_)) { + return true; + } + + match from.as_str() { + // We filter out some messages from each node to foreign committees to ensure we sometimes have to + // rely on other members of the foreign and local committees to receive the foreign proposal. + "1" => to == "1" || to == "2" || to == "3", + "4" => to == "4" || to == "5" || to == "6", + "7" => to == "7" || to == "8" || to == "9", _ => true, } })) diff --git a/dan_layer/consensus_tests/src/dummy_blocks.rs b/dan_layer/consensus_tests/src/dummy_blocks.rs new file mode 100644 index 000000000..041e06b4c --- /dev/null +++ b/dan_layer/consensus_tests/src/dummy_blocks.rs @@ -0,0 +1,111 @@ +// Copyright 2024 The Tari Project +// SPDX-License-Identifier: BSD-3-Clause + +use tari_common::configuration::Network; +use tari_common_types::types::{FixedHash, PrivateKey, PublicKey}; +use tari_consensus::hotstuff::{ + calculate_dummy_blocks, + calculate_dummy_blocks_from_justify, + calculate_last_dummy_block, +}; +use tari_crypto::{keys::PublicKey as _, tari_utilities::ByteArray}; +use tari_dan_common_types::{committee::Committee, DerivableFromPublicKey, Epoch, NodeHeight, PeerAddress, ShardGroup}; +use tari_dan_storage::consensus_models::Block; + +use crate::support::{load_fixture, RoundRobinLeaderStrategy}; + +#[test] +fn dummy_blocks() { + let genesis = Block::genesis( + Network::LocalNet, + Epoch(1), + ShardGroup::new(0, 127), + FixedHash::zero(), + None, + ); + let committee = (0u8..2) + .map(public_key_from_seed) + .map(|pk| (PeerAddress::derive_from_public_key(&pk), pk)) + .collect(); + + let dummy = calculate_dummy_blocks( + NodeHeight(0), + NodeHeight(30), + Network::LocalNet, + Epoch(1), + ShardGroup::new(0, 127), + *genesis.id(), + genesis.justify(), + genesis.id(), + FixedHash::zero(), + &RoundRobinLeaderStrategy, + &committee, + genesis.timestamp(), + 0, + FixedHash::zero(), + ); + let last = calculate_last_dummy_block( + NodeHeight(0), + NodeHeight(30), + Network::LocalNet, + Epoch(1), + ShardGroup::new(0, 127), + *genesis.id(), + genesis.justify(), + FixedHash::zero(), + &RoundRobinLeaderStrategy, + &committee, + genesis.timestamp(), + 0, + FixedHash::zero(), + ) + .expect("last dummy block"); + assert_eq!(dummy[0].parent(), genesis.id()); + for i in 1..dummy.len() { + assert_eq!(dummy[i].parent(), dummy[i - 1].id()); + } + assert_eq!(dummy.last().unwrap().id(), last.block_id()); + assert_eq!(dummy.len(), 29); +} + +fn public_key_from_seed(seed: u8) -> PublicKey { + PublicKey::from_secret_key(&PrivateKey::from_canonical_bytes(&[seed; 32]).unwrap()) +} + +#[test] +fn last_matches_generated_using_real_data() { + let candidate = load_fixture::("block_with_dummies.json"); + + let committee = load_fixture::("committee.json"); + let committee: Vec<(PeerAddress, PublicKey)> = serde_json::from_value(committee["members"].clone()).unwrap(); + let committee = Committee::new(committee); + + let justify = Block::genesis( + Network::LocalNet, + candidate.epoch(), + candidate.shard_group(), + FixedHash::zero(), + None, + ); + + let dummy = calculate_dummy_blocks_from_justify(&candidate, &justify, &RoundRobinLeaderStrategy, &committee); + + let last = calculate_last_dummy_block( + justify.height(), + candidate.height(), + Network::LocalNet, + justify.epoch(), + justify.shard_group(), + *justify.id(), + justify.justify(), + *justify.state_merkle_root(), + &RoundRobinLeaderStrategy, + &committee, + justify.timestamp(), + justify.base_layer_block_height(), + *justify.base_layer_block_hash(), + ) + .expect("last dummy block"); + + assert_eq!(dummy.last().unwrap().id(), last.block_id()); +} diff --git a/dan_layer/consensus_tests/src/eviction_proof.rs b/dan_layer/consensus_tests/src/eviction_proof.rs new file mode 100644 index 000000000..ae604dd3e --- /dev/null +++ b/dan_layer/consensus_tests/src/eviction_proof.rs @@ -0,0 +1,59 @@ +// Copyright 2024 The Tari Project +// SPDX-License-Identifier: BSD-3-Clause + +use tari_consensus::hotstuff::eviction_proof::convert_block_to_sidechain_block_header; +use tari_dan_storage::consensus_models::Block; + +use crate::support::load_fixture; + +#[test] +fn it_produces_a_summarized_header_that_hashes_to_the_original() { + let block = load_fixture::("block.json"); + let sidechain_block = convert_block_to_sidechain_block_header(block.header()); + assert_eq!(sidechain_block.extra_data_hash, block.header().create_extra_data_hash()); + assert_eq!( + sidechain_block.base_layer_block_hash, + *block.header().base_layer_block_hash() + ); + assert_eq!( + sidechain_block.base_layer_block_height, + block.header().base_layer_block_height() + ); + assert_eq!(sidechain_block.timestamp, block.header().timestamp()); + assert_eq!( + sidechain_block.signature, + block.header().signature().expect("checked by caller").clone() + ); + assert_eq!( + sidechain_block.foreign_indexes_hash, + block.header().create_foreign_indexes_hash() + ); + assert_eq!(sidechain_block.is_dummy, block.header().is_dummy()); + assert_eq!( + sidechain_block.command_merkle_root, + *block.header().command_merkle_root() + ); + assert_eq!(sidechain_block.state_merkle_root, *block.header().state_merkle_root()); + assert_eq!(sidechain_block.total_leader_fee, block.header().total_leader_fee()); + assert_eq!(sidechain_block.proposed_by, block.header().proposed_by().clone()); + assert_eq!( + sidechain_block.shard_group.start, + block.header().shard_group().start().as_u32() + ); + assert_eq!( + sidechain_block.shard_group.end_inclusive, + block.header().shard_group().end().as_u32() + ); + assert_eq!(sidechain_block.epoch, block.header().epoch().as_u64()); + assert_eq!(sidechain_block.height, block.header().height().as_u64()); + assert_eq!(sidechain_block.justify_id, *block.header().justify_id().hash()); + assert_eq!(sidechain_block.parent_id, *block.header().parent().hash()); + assert_eq!(sidechain_block.network, block.header().network().as_byte()); + + // Finally check the hash matches + assert_eq!(sidechain_block.calculate_hash(), block.header().calculate_hash()); + assert_eq!( + sidechain_block.calculate_block_id(), + *block.header().calculate_id().hash() + ); +} diff --git a/dan_layer/consensus_tests/src/lib.rs b/dan_layer/consensus_tests/src/lib.rs index b54e95765..21f1bfd2c 100644 --- a/dan_layer/consensus_tests/src/lib.rs +++ b/dan_layer/consensus_tests/src/lib.rs @@ -3,6 +3,10 @@ #[cfg(test)] mod consensus; #[cfg(test)] +mod dummy_blocks; +#[cfg(test)] +mod eviction_proof; +#[cfg(test)] mod substate_store; #[cfg(test)] mod support; diff --git a/dan_layer/consensus_tests/src/support/address.rs b/dan_layer/consensus_tests/src/support/address.rs index de3c58d13..0ac10ccf2 100644 --- a/dan_layer/consensus_tests/src/support/address.rs +++ b/dan_layer/consensus_tests/src/support/address.rs @@ -8,7 +8,7 @@ use tari_common_types::types::PublicKey; use tari_dan_common_types::{DerivableFromPublicKey, NodeAddressable}; #[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)] -pub struct TestAddress(pub String); +pub struct TestAddress(String); impl TestAddress { pub fn new>(s: T) -> Self { @@ -18,6 +18,10 @@ impl TestAddress { pub fn as_bytes(&self) -> &[u8] { self.0.as_bytes() } + + pub fn as_str(&self) -> &str { + &self.0 + } } impl NodeAddressable for TestAddress { @@ -59,3 +63,9 @@ impl From<&str> for TestAddress { Self(value.to_string()) } } + +impl PartialEq for TestAddress { + fn eq(&self, other: &str) -> bool { + self.0 == other + } +} diff --git a/dan_layer/consensus_tests/src/support/epoch_manager.rs b/dan_layer/consensus_tests/src/support/epoch_manager.rs index d07b88fed..e1ef8c357 100644 --- a/dan_layer/consensus_tests/src/support/epoch_manager.rs +++ b/dan_layer/consensus_tests/src/support/epoch_manager.rs @@ -218,22 +218,40 @@ impl EpochManagerReader for TestEpochManager { async fn get_committee_info_by_validator_address( &self, _epoch: Epoch, - _address: &Self::Addr, + address: &Self::Addr, ) -> Result { - todo!() + let state = self.state_lock().await; + let (sg, committee) = state + .committees + .iter() + .find(|(_, committee)| committee.iter().any(|(addr, _)| addr == address)) + .unwrap_or_else(|| panic!("Validator {address} not found in any committee")); + let num_committees = state.committees.len() as u32; + let num_members = committee.len(); + Ok(CommitteeInfo::new( + TEST_NUM_PRESHARDS, + num_members as u32, + num_committees, + *sg, + )) } async fn get_committee_by_shard_group( &self, _epoch: Epoch, shard_group: ShardGroup, + limit: Option, ) -> Result, EpochManagerError> { let state = self.state_lock().await; - let Some(committee) = state.committees.get(&shard_group) else { + let Some(mut committee) = state.committees.get(&shard_group).cloned() else { panic!("Committee not found for shard group {}", shard_group); }; - Ok(committee.clone()) + if let Some(limit) = limit { + committee.members.truncate(limit); + } + + Ok(committee) } async fn get_committees_overlapping_shard_group( @@ -275,26 +293,6 @@ impl EpochManagerReader for TestEpochManager { )) } - // async fn get_committees_by_shards( - // &self, - // epoch: Epoch, - // shards: &HashSet, - // ) -> Result>, EpochManagerError> { let num_committees = - // self.get_num_committees(epoch).await?; - // - // let mut committees = HashMap::new(); - // let buckets = shards.iter().map(|shard| shard.to_committee_bucket(num_committees)); - // let state = self.state_lock().await; - // for bucket in buckets { - // if committees.contains_key(&bucket) { - // continue; - // } - // - // committees.insert(bucket, state.committees.get(&bucket).unwrap().clone()); - // } - // Ok(committees) - // } - async fn get_validator_node_by_public_key( &self, _epoch: Epoch, diff --git a/dan_layer/consensus/src/test_helpers.rs b/dan_layer/consensus_tests/src/support/fixtures.rs similarity index 87% rename from dan_layer/consensus/src/test_helpers.rs rename to dan_layer/consensus_tests/src/support/fixtures.rs index 32828724d..408a76994 100644 --- a/dan_layer/consensus/src/test_helpers.rs +++ b/dan_layer/consensus_tests/src/support/fixtures.rs @@ -4,7 +4,7 @@ use serde::de::DeserializeOwned; pub fn load_fixture(name: &str) -> T { - let path = format!("tests/fixtures/{name}"); + let path = format!("fixtures/{name}"); let file = std::fs::File::open(&path).unwrap_or_else(|_| { panic!("Could not open fixture file at path: {path}"); }); diff --git a/dan_layer/consensus_tests/src/support/harness.rs b/dan_layer/consensus_tests/src/support/harness.rs index fe9401498..566225437 100644 --- a/dan_layer/consensus_tests/src/support/harness.rs +++ b/dan_layer/consensus_tests/src/support/harness.rs @@ -336,7 +336,9 @@ impl Test { pub fn is_transaction_pool_empty(&self) -> bool { self.validators.values().all(|v| { let c = v.get_transaction_pool_count(); - log::info!("{} has {} transactions in pool", v.address, c); + if c > 0 { + log::info!("🐞 {} has {} transactions in pool", v.address, c); + } c == 0 }) } @@ -617,7 +619,7 @@ impl TestBuilder { true }) .map(|(vn, shard_group)| { - let sql_address = sql_address.replace("{}", &vn.address.0); + let sql_address = sql_address.replace("{}", vn.address.as_str()); let (sk, pk) = helpers::derive_keypair_from_address(&vn.address); let (channels, validator) = Validator::builder() @@ -641,7 +643,7 @@ impl TestBuilder { for path in self .committees .values() - .flat_map(|committee| committee.iter().map(|(addr, _)| sql_file.replace("{}", &addr.0))) + .flat_map(|committee| committee.iter().map(|(addr, _)| sql_file.replace("{}", addr.as_str()))) { let _ignore = std::fs::remove_file(&path); } diff --git a/dan_layer/consensus_tests/src/support/messaging_impls.rs b/dan_layer/consensus_tests/src/support/messaging_impls.rs index ceaf9c83c..bf340ee97 100644 --- a/dan_layer/consensus_tests/src/support/messaging_impls.rs +++ b/dan_layer/consensus_tests/src/support/messaging_impls.rs @@ -64,7 +64,21 @@ impl OutboundMessaging for TestOutboundMessaging { }) } - async fn multicast(&mut self, shard_group: ShardGroup, message: T) -> Result<(), OutboundMessagingError> + async fn multicast(&mut self, addresses: I, message: T) -> Result<(), OutboundMessagingError> + where + I: IntoIterator + Send, + T: Into + Send, + { + let peers = addresses.into_iter().collect(); + + self.tx_broadcast.send((peers, message.into())).await.map_err(|_| { + OutboundMessagingError::FailedToEnqueueMessage { + reason: "broadcast channel closed".to_string(), + } + }) + } + + async fn broadcast(&mut self, shard_group: ShardGroup, message: T) -> Result<(), OutboundMessagingError> where T: Into + Send { // TODO: technically we should use the consensus epoch here, but current tests will not cause this issue let epoch = self @@ -74,18 +88,11 @@ impl OutboundMessaging for TestOutboundMessaging { .map_err(|e| OutboundMessagingError::UpstreamError(e.into()))?; let peers = self .epoch_manager - .get_committee_by_shard_group(epoch, shard_group) + .get_committee_by_shard_group(epoch, shard_group, None) .await .map_err(|e| OutboundMessagingError::UpstreamError(e.into()))? - .into_iter() - .map(|(addr, _)| addr) - .collect(); - - self.tx_broadcast.send((peers, message.into())).await.map_err(|_| { - OutboundMessagingError::FailedToEnqueueMessage { - reason: "broadcast channel closed".to_string(), - } - }) + .into_addresses(); + self.multicast(peers, message).await } } diff --git a/dan_layer/consensus_tests/src/support/mod.rs b/dan_layer/consensus_tests/src/support/mod.rs index 03f95ce79..5f8ef2b9a 100644 --- a/dan_layer/consensus_tests/src/support/mod.rs +++ b/dan_layer/consensus_tests/src/support/mod.rs @@ -9,6 +9,7 @@ pub const TEST_NUM_PRESHARDS: NumPreshards = NumPreshards::P64; mod address; mod epoch_manager; mod executions_store; +mod fixtures; mod harness; pub mod helpers; mod leader_strategy; @@ -24,6 +25,7 @@ mod validator; pub use address::*; pub use executions_store::ExecuteSpec; +pub use fixtures::*; pub use harness::*; pub use leader_strategy::*; pub use network::*; diff --git a/dan_layer/consensus_tests/src/support/validator/builder.rs b/dan_layer/consensus_tests/src/support/validator/builder.rs index e1f04c7d3..cc3d4ca4c 100644 --- a/dan_layer/consensus_tests/src/support/validator/builder.rs +++ b/dan_layer/consensus_tests/src/support/validator/builder.rs @@ -157,7 +157,7 @@ impl ValidatorBuilder { tx_current_state: tx_current_state.clone(), }; - let mut worker = ConsensusWorker::new(shutdown_signal); + let mut worker = ConsensusWorker::new(shutdown_signal).no_initial_delay(); let handle = tokio::spawn(async move { worker.run(context).await }); let channels = ValidatorChannels { diff --git a/dan_layer/epoch_manager/src/base_layer/base_layer_epoch_manager.rs b/dan_layer/epoch_manager/src/base_layer/base_layer_epoch_manager.rs index 50bf46640..b6dc99270 100644 --- a/dan_layer/epoch_manager/src/base_layer/base_layer_epoch_manager.rs +++ b/dan_layer/epoch_manager/src/base_layer/base_layer_epoch_manager.rs @@ -475,7 +475,7 @@ where let shard_group = substate_address.to_shard_group(self.config.num_preshards, num_committees); // TODO(perf): fetch full validator node records for the shard group in single query (current O(n + 1) queries) - let committees = self.get_committee_for_shard_group(epoch, shard_group)?; + let committees = self.get_committee_for_shard_group(epoch, shard_group, false, None)?; let mut res = vec![]; for (_, pub_key) in committees { @@ -489,6 +489,7 @@ where })?; res.push(vn); } + res.sort_by(|a, b| a.shard_key.cmp(&b.shard_key)); Ok(res) } @@ -611,10 +612,17 @@ where &self, epoch: Epoch, shard_group: ShardGroup, + shuffle: bool, + limit: Option, ) -> Result, EpochManagerError> { let mut tx = self.global_db.create_transaction()?; let mut validator_node_db = self.global_db.validator_nodes(&mut tx); - let committees = validator_node_db.get_committee_for_shard_group(epoch, shard_group)?; + let committees = validator_node_db.get_committee_for_shard_group( + epoch, + shard_group, + shuffle, + limit.unwrap_or(usize::MAX), + )?; Ok(committees) } diff --git a/dan_layer/epoch_manager/src/base_layer/epoch_manager_service.rs b/dan_layer/epoch_manager/src/base_layer/epoch_manager_service.rs index 59db56301..ffedf18eb 100644 --- a/dan_layer/epoch_manager/src/base_layer/epoch_manager_service.rs +++ b/dan_layer/epoch_manager/src/base_layer/epoch_manager_service.rs @@ -259,10 +259,12 @@ where EpochManagerRequest::GetCommitteeForShardGroup { epoch, shard_group, + limit, reply, } => handle( reply, - self.inner.get_committee_for_shard_group(epoch, shard_group), + self.inner + .get_committee_for_shard_group(epoch, shard_group, true, limit), context, ), EpochManagerRequest::GetCommitteesOverlappingShardGroup { diff --git a/dan_layer/epoch_manager/src/base_layer/handle.rs b/dan_layer/epoch_manager/src/base_layer/handle.rs index 3755e590d..9f8f4bb82 100644 --- a/dan_layer/epoch_manager/src/base_layer/handle.rs +++ b/dan_layer/epoch_manager/src/base_layer/handle.rs @@ -414,12 +414,14 @@ impl EpochManagerReader for EpochManagerHandle { &self, epoch: Epoch, shard_group: ShardGroup, + limit: Option, ) -> Result, EpochManagerError> { let (tx, rx) = oneshot::channel(); self.tx_request .send(EpochManagerRequest::GetCommitteeForShardGroup { epoch, shard_group, + limit, reply: tx, }) .await diff --git a/dan_layer/epoch_manager/src/base_layer/types.rs b/dan_layer/epoch_manager/src/base_layer/types.rs index a959e3b06..4c74276ed 100644 --- a/dan_layer/epoch_manager/src/base_layer/types.rs +++ b/dan_layer/epoch_manager/src/base_layer/types.rs @@ -128,6 +128,7 @@ pub enum EpochManagerRequest { GetCommitteeForShardGroup { epoch: Epoch, shard_group: ShardGroup, + limit: Option, reply: Reply>, }, GetCommitteesOverlappingShardGroup { diff --git a/dan_layer/epoch_manager/src/traits.rs b/dan_layer/epoch_manager/src/traits.rs index 804dd12d8..d6550c6f5 100644 --- a/dan_layer/epoch_manager/src/traits.rs +++ b/dan_layer/epoch_manager/src/traits.rs @@ -119,6 +119,7 @@ pub trait EpochManagerReader: Send + Sync { &self, epoch: Epoch, shards: ShardGroup, + limit: Option, ) -> Result, EpochManagerError>; async fn get_committees_overlapping_shard_group( &self, diff --git a/dan_layer/p2p/proto/consensus.proto b/dan_layer/p2p/proto/consensus.proto index a56b95246..c38af5bd5 100644 --- a/dan_layer/p2p/proto/consensus.proto +++ b/dan_layer/p2p/proto/consensus.proto @@ -13,11 +13,13 @@ message HotStuffMessage { NewViewMessage new_view = 1; ProposalMessage proposal = 2; ForeignProposalMessage foreign_proposal = 3; - VoteMessage vote = 4; - MissingTransactionsRequest request_missing_transactions = 5; - MissingTransactionsResponse requested_transaction = 6; - SyncRequest sync_request = 7; - SyncResponse sync_response = 8; + ForeignProposalNotification foreign_proposal_notification = 4; + ForeignProposalRequest foreign_proposal_request = 5; + VoteMessage vote = 6; + MissingTransactionsRequest request_missing_transactions = 7; + MissingTransactionsResponse requested_transaction = 8; + SyncRequest sync_request = 9; + SyncResponse sync_response = 10; } } @@ -36,6 +38,30 @@ message ForeignProposalMessage { ForeignProposal proposal = 1; } +message ForeignProposalNotification { + bytes block_id = 1; + uint64 epoch = 2; +} + +message ForeignProposalRequest { + oneof request { + ForeignProposalRequestByBlockId by_block_id = 1; + ForeignProposalRequestByTransactionId by_transaction_id = 2; + } +} + +message ForeignProposalRequestByBlockId { + bytes block_id = 1; + uint32 for_shard_group = 2; + uint64 epoch = 3; +} + +message ForeignProposalRequestByTransactionId { + bytes transaction_id = 1; + uint32 for_shard_group = 2; + uint64 epoch = 3; +} + message ForeignProposal { Block block = 1; QuorumCertificate justify_qc = 2; diff --git a/dan_layer/p2p/src/conversions/consensus.rs b/dan_layer/p2p/src/conversions/consensus.rs index c7e619161..59c35eca6 100644 --- a/dan_layer/p2p/src/conversions/consensus.rs +++ b/dan_layer/p2p/src/conversions/consensus.rs @@ -30,6 +30,8 @@ use tari_bor::{decode_exact, encode}; use tari_common_types::types::PublicKey; use tari_consensus::messages::{ ForeignProposalMessage, + ForeignProposalNotificationMessage, + ForeignProposalRequestMessage, FullBlock, HotstuffMessage, MissingTransactionsRequest, @@ -92,6 +94,12 @@ impl From<&HotstuffMessage> for proto::consensus::HotStuffMessage { HotstuffMessage::ForeignProposal(msg) => { proto::consensus::hot_stuff_message::Message::ForeignProposal(msg.into()) }, + HotstuffMessage::ForeignProposalNotification(msg) => { + proto::consensus::hot_stuff_message::Message::ForeignProposalNotification(msg.into()) + }, + HotstuffMessage::ForeignProposalRequest(msg) => { + proto::consensus::hot_stuff_message::Message::ForeignProposalRequest(msg.into()) + }, HotstuffMessage::Vote(msg) => proto::consensus::hot_stuff_message::Message::Vote(msg.into()), HotstuffMessage::MissingTransactionsRequest(msg) => { proto::consensus::hot_stuff_message::Message::RequestMissingTransactions(msg.into()) @@ -121,6 +129,12 @@ impl TryFrom for HotstuffMessage { proto::consensus::hot_stuff_message::Message::ForeignProposal(msg) => { HotstuffMessage::ForeignProposal(msg.try_into()?) }, + proto::consensus::hot_stuff_message::Message::ForeignProposalNotification(msg) => { + HotstuffMessage::ForeignProposalNotification(msg.try_into()?) + }, + proto::consensus::hot_stuff_message::Message::ForeignProposalRequest(msg) => { + HotstuffMessage::ForeignProposalRequest(msg.try_into()?) + }, proto::consensus::hot_stuff_message::Message::Vote(msg) => HotstuffMessage::Vote(msg.try_into()?), proto::consensus::hot_stuff_message::Message::RequestMissingTransactions(msg) => { HotstuffMessage::MissingTransactionsRequest(msg.try_into()?) @@ -260,6 +274,85 @@ impl TryFrom for ForeignProposal { } } +impl From<&ForeignProposalNotificationMessage> for proto::consensus::ForeignProposalNotification { + fn from(value: &ForeignProposalNotificationMessage) -> Self { + Self { + block_id: value.block_id.as_bytes().to_vec(), + epoch: value.epoch.as_u64(), + } + } +} + +impl TryFrom for ForeignProposalNotificationMessage { + type Error = anyhow::Error; + + fn try_from(value: proto::consensus::ForeignProposalNotification) -> Result { + Ok(Self { + block_id: BlockId::try_from(value.block_id)?, + epoch: Epoch(value.epoch), + }) + } +} + +impl From<&ForeignProposalRequestMessage> for proto::consensus::ForeignProposalRequest { + fn from(value: &ForeignProposalRequestMessage) -> Self { + match value { + ForeignProposalRequestMessage::ByBlockId { + block_id, + for_shard_group, + epoch, + } => Self { + request: Some(proto::consensus::foreign_proposal_request::Request::ByBlockId( + proto::consensus::ForeignProposalRequestByBlockId { + block_id: block_id.as_bytes().to_vec(), + for_shard_group: for_shard_group.encode_as_u32(), + epoch: epoch.as_u64(), + }, + )), + }, + ForeignProposalRequestMessage::ByTransactionId { + transaction_id, + for_shard_group, + epoch, + } => Self { + request: Some(proto::consensus::foreign_proposal_request::Request::ByTransactionId( + proto::consensus::ForeignProposalRequestByTransactionId { + transaction_id: transaction_id.as_bytes().to_vec(), + for_shard_group: for_shard_group.encode_as_u32(), + epoch: epoch.as_u64(), + }, + )), + }, + } + } +} + +impl TryFrom for ForeignProposalRequestMessage { + type Error = anyhow::Error; + + fn try_from(value: proto::consensus::ForeignProposalRequest) -> Result { + let request = value.request.ok_or_else(|| anyhow!("Request is missing"))?; + Ok(match request { + proto::consensus::foreign_proposal_request::Request::ByBlockId(by_block_id) => { + ForeignProposalRequestMessage::ByBlockId { + block_id: BlockId::try_from(by_block_id.block_id)?, + for_shard_group: ShardGroup::decode_from_u32(by_block_id.for_shard_group) + .ok_or_else(|| anyhow!("Invalid ShardGroup"))?, + epoch: Epoch(by_block_id.epoch), + } + }, + proto::consensus::foreign_proposal_request::Request::ByTransactionId(by_transaction_id) => { + ForeignProposalRequestMessage::ByTransactionId { + transaction_id: TransactionId::try_from(by_transaction_id.transaction_id)?, + for_shard_group: ShardGroup::decode_from_u32(by_transaction_id.for_shard_group) + .ok_or_else(|| anyhow!("Invalid ShardGroup"))?, + epoch: Epoch(by_transaction_id.epoch), + } + }, + }) + } +} + // -------------------------------- TransactionPledge -------------------------------- // impl From<(&TransactionId, &SubstatePledges)> for proto::consensus::TransactionPledge { 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 142939624..98e6ed7e1 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 @@ -301,6 +301,7 @@ create table lock_conflicts transaction_id text not null, depends_on_tx text not null, lock_type text not null CHECK (lock_type IN ('Write', 'Read', 'Output')), + is_local_only boolean not null, created_at timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, -- Note: cannot use foreign key for block_id since it does not yet exist when proposing FOREIGN KEY (transaction_id) REFERENCES transaction_pool (transaction_id) ON DELETE CASCADE, diff --git a/dan_layer/state_store_sqlite/src/reader.rs b/dan_layer/state_store_sqlite/src/reader.rs index dd6e401ba..b05ad1f3b 100644 --- a/dan_layer/state_store_sqlite/src/reader.rs +++ b/dan_layer/state_store_sqlite/src/reader.rs @@ -573,7 +573,7 @@ impl<'tx, TAddr: NodeAddressable + Serialize + DeserializeOwned + 'tx> StateStor use crate::schema::foreign_proposals; let foreign_proposals = foreign_proposals::table - .filter(foreign_proposals::epoch.eq(epoch.as_u64() as i64)) + .filter(foreign_proposals::epoch.le(epoch.as_u64() as i64)) .filter(foreign_proposals::status.ne(ForeignProposalStatus::Confirmed.to_string())) .count() .limit(1) @@ -605,7 +605,8 @@ impl<'tx, TAddr: NodeAddressable + Serialize + DeserializeOwned + 'tx> StateStor let foreign_proposals = foreign_proposals::table .left_join(quorum_certificates::table.on(foreign_proposals::justify_qc_id.eq(quorum_certificates::qc_id))) - .filter(foreign_proposals::epoch.eq(locked.epoch.as_u64() as i64)) + .filter(foreign_proposals::epoch.le(locked.epoch.as_u64() as i64)) + .filter(foreign_proposals::status.ne(ForeignProposalStatus::Confirmed.to_string())) .filter( foreign_proposals::proposed_in_block .is_null() @@ -1622,11 +1623,12 @@ impl<'tx, TAddr: NodeAddressable + Serialize + DeserializeOwned + 'tx> StateStor }); } - let mut ready_txs = transaction_pool::table + let ready_txs = transaction_pool::table // Exclude new transactions .filter(transaction_pool::stage.ne(TransactionPoolStage::New.to_string())) .filter(transaction_pool::is_ready.eq(true)) .order_by(transaction_pool::transaction_id.asc()) + .limit(max_txs as i64) .get_results::(self.connection()) .map_err(|e| SqliteStorageError::DieselError { operation: "transaction_pool_get_many_ready", @@ -1640,35 +1642,6 @@ impl<'tx, TAddr: NodeAddressable + Serialize + DeserializeOwned + 'tx> StateStor ready_txs.len() ); - let new_limit = max_txs.saturating_sub(ready_txs.len()); - if new_limit > 0 { - let new_txs = transaction_pool::table - .filter(transaction_pool::stage.eq(TransactionPoolStage::New.to_string())) - .filter(transaction_pool::is_ready.eq(true)) - // Filter out any transactions that are in lock conflict - .filter(transaction_pool::transaction_id.ne_all(lock_conflicts::table.select(lock_conflicts::transaction_id))) - .order_by(transaction_pool::transaction_id.asc()) - .limit(new_limit as i64) - .get_results::(self.connection()) - .map_err(|e| SqliteStorageError::DieselError { - operation: "transaction_pool_get_many_ready", - source: e, - })?; - - debug!( - target: LOG_TARGET, - "🛢️ transaction_pool_get_many_ready: block_id={}, new ready_txs={}, total ready_txs={}", - block_id, - new_txs.len(), - ready_txs.len() + new_txs.len() - ); - ready_txs.extend(new_txs); - } - - if ready_txs.is_empty() { - return Ok(Vec::new()); - } - // Fetch all applicable block ids between the locked block and the given block let locked = self.get_current_locked_block()?; @@ -1686,16 +1659,68 @@ impl<'tx, TAddr: NodeAddressable + Serialize + DeserializeOwned + 'tx> StateStor ready_txs.len(), updates.len() ); - - ready_txs + let num_ready = ready_txs.len(); + let ready_txs = ready_txs .into_iter() .map(|rec| { let maybe_update = updates.swap_remove(&rec.transaction_id); rec.try_convert(maybe_update) }) // Filter only Ok where is_ready == true (after update) or Err - .filter(|result| result.as_ref().map_or(true, |rec| rec.is_ready())) - .take(max_txs) + .filter(|result| result.as_ref().map_or(true, |rec| rec.is_ready())); + + // Prioritise already sequenced transactions, if there is still space, add transactions that are not previously + // sequenced (new) + let new_limit = max_txs.saturating_sub(num_ready); + if new_limit == 0 { + debug!( + target: LOG_TARGET, + "transaction_pool_get_many_ready: locked.block_id={}, leaf.block_id={}, len(ready_txs)={}", + locked.block_id, + block_id, + num_ready + ); + + return ready_txs.collect(); + } + + let new_txs = transaction_pool::table + .filter(transaction_pool::stage.eq(TransactionPoolStage::New.to_string())) + // Filter out any transactions that are in lock conflict + .filter(transaction_pool::transaction_id.ne_all(lock_conflicts::table.select(lock_conflicts::transaction_id).filter(lock_conflicts::is_local_only.eq(false)))) + .order_by(transaction_pool::transaction_id.asc()) + .limit(new_limit as i64) + .get_results::(self.connection()) + .map_err(|e| SqliteStorageError::DieselError { + operation: "transaction_pool_get_many_ready", + source: e, + })?; + let mut updates = self.get_transaction_atom_state_updates_between_blocks( + &locked.block_id, + block_id, + new_txs.iter().map(|s| s.transaction_id.as_str()), + )?; + + debug!( + target: LOG_TARGET, + "🛢️ transaction_pool_get_many_ready: block_id={}, new ready_txs={}, total ready_txs={}, updates={}", + block_id, + new_txs.len(), + num_ready + new_txs.len(), + updates.len() + ); + + ready_txs + .chain( + new_txs + .into_iter() + .map(|rec| { + let maybe_update = updates.swap_remove(&rec.transaction_id); + rec.try_convert(maybe_update) + }) + // Filter only Ok where is_ready == true (after update) or Err + .filter(|result| result.as_ref().map_or(true, |rec| rec.is_ready())), + ) .collect() } diff --git a/dan_layer/state_store_sqlite/src/schema.rs b/dan_layer/state_store_sqlite/src/schema.rs index 2529052e6..292aeaf39 100644 --- a/dan_layer/state_store_sqlite/src/schema.rs +++ b/dan_layer/state_store_sqlite/src/schema.rs @@ -275,6 +275,7 @@ diesel::table! { transaction_id -> Text, depends_on_tx -> Text, lock_type -> Text, + is_local_only -> Bool, created_at -> Timestamp, } } diff --git a/dan_layer/state_store_sqlite/src/writer.rs b/dan_layer/state_store_sqlite/src/writer.rs index 80b87d819..e70b3a05c 100644 --- a/dan_layer/state_store_sqlite/src/writer.rs +++ b/dan_layer/state_store_sqlite/src/writer.rs @@ -9,6 +9,7 @@ use diesel::{ sql_query, sql_types::Text, AsChangeset, + BoolExpressionMethods, ExpressionMethods, NullableExpressionMethods, OptionalExtension, @@ -2105,6 +2106,7 @@ impl<'tx, TAddr: NodeAddressable + 'tx> StateStoreWriteTransaction for SqliteSta lock_conflicts::transaction_id.eq(serialize_hex(tx_id)), lock_conflicts::depends_on_tx.eq(serialize_hex(conflict.transaction_id)), lock_conflicts::lock_type.eq(conflict.requested_lock.to_string()), + lock_conflicts::is_local_only.eq(conflict.is_local_only), ) }) }) @@ -2121,6 +2123,47 @@ impl<'tx, TAddr: NodeAddressable + 'tx> StateStoreWriteTransaction for SqliteSta Ok(()) } + fn lock_conflicts_remove_by_transaction_ids<'a, I: IntoIterator>( + &mut self, + transaction_ids: I, + ) -> Result<(), StorageError> { + use crate::schema::lock_conflicts; + + let tx_ids = transaction_ids.into_iter().map(serialize_hex).collect::>(); + let num_deleted = diesel::delete(lock_conflicts::table) + .filter( + lock_conflicts::depends_on_tx + .eq_any(&tx_ids) + .or(lock_conflicts::transaction_id.eq_any(&tx_ids)), + ) + .execute(self.connection()) + .map_err(|e| SqliteStorageError::DieselError { + operation: "lock_conflicts_remove_by_transaction_ids", + source: e, + })?; + + debug!( + target: LOG_TARGET, + "Deleted {num_deleted} lock conflicts", + ); + + Ok(()) + } + + fn lock_conflicts_remove_by_block_id(&mut self, block_id: &BlockId) -> Result<(), StorageError> { + use crate::schema::lock_conflicts; + + diesel::delete(lock_conflicts::table) + .filter(lock_conflicts::block_id.eq(serialize_hex(block_id))) + .execute(self.connection()) + .map_err(|e| SqliteStorageError::DieselError { + operation: "lock_conflicts_remove_by_block_id", + source: e, + })?; + + Ok(()) + } + fn validator_epoch_stats_add_participation_share(&mut self, qc_id: &QcId) -> Result<(), StorageError> { use crate::schema::{quorum_certificates, validator_epoch_stats}; diff --git a/dan_layer/storage/src/consensus_models/block.rs b/dan_layer/storage/src/consensus_models/block.rs index e6619b749..55ed7a4b5 100644 --- a/dan_layer/storage/src/consensus_models/block.rs +++ b/dan_layer/storage/src/consensus_models/block.rs @@ -473,6 +473,22 @@ impl Block { tx.blocks_get_all_ids_by_height(epoch, height) } + pub fn get_genesis_for_epoch(tx: &TTx, epoch: Epoch) -> Result { + let ids = Self::get_ids_by_epoch_and_height(tx, epoch, NodeHeight::zero())?; + if ids.is_empty() { + return Err(StorageError::DataInconsistency { + details: format!("No genesis block found for epoch {}", epoch), + }); + } + if ids.len() > 1 { + return Err(StorageError::DataInconsistency { + details: format!("Multiple genesis blocks found for epoch {}", epoch), + }); + } + + Self::get(tx, &ids[0]) + } + /// Returns all blocks from and excluding the start block (lower height) to the end block (inclusive) pub fn get_all_blocks_between( tx: &TTx, @@ -1168,6 +1184,7 @@ where tx.transaction_executions_remove_any_by_block_id(block_id)?; tx.foreign_proposals_clear_proposed_in(block_id)?; tx.burnt_utxos_clear_proposed_block(block_id)?; + tx.lock_conflicts_remove_by_block_id(block_id)?; Block::delete_record(tx, block_id)?; diff --git a/dan_layer/storage/src/consensus_models/block_pledges.rs b/dan_layer/storage/src/consensus_models/block_pledges.rs index b91c7ec10..25a75bc73 100644 --- a/dan_layer/storage/src/consensus_models/block_pledges.rs +++ b/dan_layer/storage/src/consensus_models/block_pledges.rs @@ -9,6 +9,8 @@ use std::{ use serde::{Deserialize, Serialize}; use tari_dan_common_types::{ + NumPreshards, + ShardGroup, SubstateAddress, SubstateLockType, SubstateRequirement, @@ -33,6 +35,14 @@ impl BlockPledge { } } + pub fn len(&self) -> usize { + self.pledges.len() + } + + pub fn is_empty(&self) -> bool { + self.pledges.is_empty() + } + pub fn contains(&self, transaction_id: &TransactionId) -> bool { self.pledges.contains_key(transaction_id) } @@ -49,6 +59,28 @@ impl BlockPledge { self.pledges.values().map(|s| s.len()).sum() } + pub fn into_filtered_for_shard_group( + mut self, + num_preshards: NumPreshards, + num_committees: u32, + shard_group: ShardGroup, + ) -> Self { + self.pledges.retain(|_, substate_pledges| { + substate_pledges.iter().any(|pledge| { + pledge + .to_substate_address() + .to_shard_group(num_preshards, num_committees) == + shard_group + }) + }); + self + } + + pub fn retain_transactions(&mut self, transaction_ids: &HashSet) -> &mut Self { + self.pledges.retain(|tx, _| transaction_ids.contains(tx)); + self + } + pub fn iter(&self) -> impl Iterator + '_ { self.pledges.iter() } diff --git a/dan_layer/storage/src/consensus_models/evidence.rs b/dan_layer/storage/src/consensus_models/evidence.rs index 6ac8b234a..5a39597eb 100644 --- a/dan_layer/storage/src/consensus_models/evidence.rs +++ b/dan_layer/storage/src/consensus_models/evidence.rs @@ -163,6 +163,16 @@ impl Evidence { self.evidence.keys() } + pub fn missing_evidence_iter(&self) -> impl Iterator { + self.evidence.iter().filter_map(|(sg, e)| { + if e.prepare_qc.is_none() || e.accept_qc.is_none() { + Some(sg) + } else { + None + } + }) + } + pub fn num_shard_groups(&self) -> usize { self.evidence.len() } diff --git a/dan_layer/storage/src/consensus_models/foreign_proposal.rs b/dan_layer/storage/src/consensus_models/foreign_proposal.rs index af80cd1a6..cef3457f1 100644 --- a/dan_layer/storage/src/consensus_models/foreign_proposal.rs +++ b/dan_layer/storage/src/consensus_models/foreign_proposal.rs @@ -89,7 +89,11 @@ impl ForeignProposal { } pub fn exists(&self, tx: &TTx) -> Result { - tx.foreign_proposals_exists(self.block.id()) + Self::record_exists(tx, self.block.id()) + } + + pub fn record_exists(tx: &TTx, block_id: &BlockId) -> Result { + tx.foreign_proposals_exists(block_id) } pub fn get_all_new( diff --git a/dan_layer/storage/src/consensus_models/lock_confict.rs b/dan_layer/storage/src/consensus_models/lock_confict.rs index 93d90a41d..a9a346009 100644 --- a/dan_layer/storage/src/consensus_models/lock_confict.rs +++ b/dan_layer/storage/src/consensus_models/lock_confict.rs @@ -9,4 +9,5 @@ pub struct LockConflict { pub transaction_id: TransactionId, pub existing_lock: SubstateLockType, pub requested_lock: SubstateLockType, + pub is_local_only: bool, } diff --git a/dan_layer/storage/src/consensus_models/quorum_certificate.rs b/dan_layer/storage/src/consensus_models/quorum_certificate.rs index f9e372f53..7a8641e6a 100644 --- a/dan_layer/storage/src/consensus_models/quorum_certificate.rs +++ b/dan_layer/storage/src/consensus_models/quorum_certificate.rs @@ -124,7 +124,7 @@ impl QuorumCertificate { } impl QuorumCertificate { - pub fn is_zero(&self) -> bool { + pub fn justifies_zero_block(&self) -> bool { self.block_id.is_zero() } diff --git a/dan_layer/storage/src/consensus_models/transaction_pool.rs b/dan_layer/storage/src/consensus_models/transaction_pool.rs index e2d14aa82..cc6630d21 100644 --- a/dan_layer/storage/src/consensus_models/transaction_pool.rs +++ b/dan_layer/storage/src/consensus_models/transaction_pool.rs @@ -109,6 +109,9 @@ impl TransactionPool { max: usize, block_id: &BlockId, ) -> Result, TransactionPoolError> { + if max == 0 { + return Ok(Vec::new()); + } let recs = tx.transaction_pool_get_many_ready(max, block_id)?; Ok(recs) } @@ -670,8 +673,11 @@ impl TransactionPoolRecord { I: IntoIterator, { let recs = tx.transaction_pool_remove_all(transaction_ids)?; + let iter = recs.iter().map(|rec| rec.transaction_id()); // Clear any related foreign pledges - tx.foreign_substate_pledges_remove_many(recs.iter().map(|rec| rec.transaction_id()))?; + tx.foreign_substate_pledges_remove_many(iter.clone())?; + // Clear any related lock_conflicts + tx.lock_conflicts_remove_by_transaction_ids(iter)?; Ok(recs) } diff --git a/dan_layer/storage/src/global/backend_adapter.rs b/dan_layer/storage/src/global/backend_adapter.rs index 8f4367b55..a1cae31ee 100644 --- a/dan_layer/storage/src/global/backend_adapter.rs +++ b/dan_layer/storage/src/global/backend_adapter.rs @@ -140,6 +140,8 @@ pub trait GlobalDbAdapter: AtomicDb + Send + Sync + Clone { tx: &mut Self::DbTransaction<'_>, epoch: Epoch, shard_group: ShardGroup, + shuffle: bool, + limit: usize, ) -> Result, Self::Error>; fn validator_nodes_get_overlapping_shard_group( diff --git a/dan_layer/storage/src/global/validator_node_db.rs b/dan_layer/storage/src/global/validator_node_db.rs index d5b817e6a..0fecee5fe 100644 --- a/dan_layer/storage/src/global/validator_node_db.rs +++ b/dan_layer/storage/src/global/validator_node_db.rs @@ -130,9 +130,11 @@ impl<'a, 'tx, TGlobalDbAdapter: GlobalDbAdapter> ValidatorNodeDb<'a, 'tx, TGloba &mut self, epoch: Epoch, shard_group: ShardGroup, + shuffle: bool, + limit: usize, ) -> Result, TGlobalDbAdapter::Error> { self.backend - .validator_nodes_get_for_shard_group(self.tx, epoch, shard_group) + .validator_nodes_get_for_shard_group(self.tx, epoch, shard_group, shuffle, limit) .map_err(TGlobalDbAdapter::Error::into) } diff --git a/dan_layer/storage/src/state_store/mod.rs b/dan_layer/storage/src/state_store/mod.rs index b41cd3d4c..6e191b136 100644 --- a/dan_layer/storage/src/state_store/mod.rs +++ b/dan_layer/storage/src/state_store/mod.rs @@ -595,6 +595,13 @@ pub trait StateStoreWriteTransaction { conflicts: I, ) -> Result<(), StorageError>; + fn lock_conflicts_remove_by_transaction_ids<'a, I: IntoIterator>( + &mut self, + transaction_ids: I, + ) -> Result<(), StorageError>; + + fn lock_conflicts_remove_by_block_id(&mut self, block_id: &BlockId) -> Result<(), StorageError>; + // -------------------------------- ParticipationShares -------------------------------- // fn validator_epoch_stats_add_participation_share(&mut self, qc_id: &QcId) -> Result<(), StorageError>; fn validator_epoch_stats_updates<'a, I: IntoIterator>>( diff --git a/dan_layer/storage_sqlite/src/global/backend_adapter.rs b/dan_layer/storage_sqlite/src/global/backend_adapter.rs index 369d4e34d..b6a8caa05 100644 --- a/dan_layer/storage_sqlite/src/global/backend_adapter.rs +++ b/dan_layer/storage_sqlite/src/global/backend_adapter.rs @@ -92,6 +92,10 @@ define_sql_function! { #[sql_name = "COALESCE"] fn coalesce_bigint(x: diesel::sql_types::Nullable, y: BigInt) -> BigInt; } +define_sql_function! { + #[sql_name = "random"] + fn sql_random() -> Integer; +} pub struct SqliteGlobalDbAdapter { connection: Arc>, @@ -576,15 +580,25 @@ impl GlobalDbAdapter for SqliteGlobalDbAdapter { tx: &mut Self::DbTransaction<'_>, epoch: Epoch, shard_group: ShardGroup, + shuffle: bool, + limit: usize, ) -> Result, Self::Error> { use crate::global::schema::{committees, validator_nodes}; - let validators = validator_nodes::table + let mut query = validator_nodes::table .inner_join(committees::table.on(committees::validator_node_id.eq(validator_nodes::id))) .select(validator_nodes::all_columns) .filter(committees::epoch.eq(epoch.as_u64() as i64)) .filter(committees::shard_start.eq(shard_group.start().as_u32() as i32)) .filter(committees::shard_end.eq(shard_group.end().as_u32() as i32)) + .into_boxed(); + + if shuffle { + query = query.order_by(sql_random()); + } + + let validators = query + .limit(i64::try_from(limit).unwrap_or(i64::MAX)) .get_results::(tx.connection()) .map_err(|source| SqliteStorageError::DieselError { source, diff --git a/dan_layer/storage_sqlite/tests/global_db.rs b/dan_layer/storage_sqlite/tests/global_db.rs index 0bbbfeeb3..bf0ab6520 100644 --- a/dan_layer/storage_sqlite/tests/global_db.rs +++ b/dan_layer/storage_sqlite/tests/global_db.rs @@ -99,7 +99,7 @@ fn change_committee_shard_group() { let count = validator_nodes.count(Epoch(3)).unwrap(); assert_eq!(count, 2); let vns = validator_nodes - .get_committee_for_shard_group(Epoch(3), ShardGroup::new(4, 5)) + .get_committee_for_shard_group(Epoch(3), ShardGroup::new(4, 5), false, 100) .unwrap(); assert_eq!(vns.len(), 2); } diff --git a/integration_tests/tests/features/eviction.feature b/integration_tests/tests/features/eviction.feature index 3449442cc..29d72b8cd 100644 --- a/integration_tests/tests/features/eviction.feature +++ b/integration_tests/tests/features/eviction.feature @@ -6,12 +6,18 @@ Feature: Eviction scenarios @flaky + @doit Scenario: Offline validator gets evicted # Initialize a base node, wallet, miner and several VNs Given a base node BASE Given a wallet WALLET connected to base node BASE Given a miner MINER connected to base node BASE and wallet WALLET + # Initialize an indexer + Given an indexer IDX connected to base node BASE + # Initialize the wallet daemon + Given a wallet daemon WALLET_D connected to indexer IDX + # Initialize VNs Given a seed validator node VN1 connected to base node BASE and wallet daemon WALLET_D Given a seed validator node VN2 connected to base node BASE and wallet daemon WALLET_D @@ -19,11 +25,6 @@ Feature: Eviction scenarios Given a seed validator node VN4 connected to base node BASE and wallet daemon WALLET_D Given a seed validator node VN5 connected to base node BASE and wallet daemon WALLET_D - # Initialize an indexer - Given an indexer IDX connected to base node BASE - # Initialize the wallet daemon - Given a wallet daemon WALLET_D connected to indexer IDX - When miner MINER mines 9 new blocks When wallet WALLET has at least 25000 T When validator node VN1 sends a registration transaction to base wallet WALLET @@ -55,9 +56,8 @@ Feature: Eviction scenarios When miner MINER mines 10 new blocks Then all validators have scanned to height 42 - # fixme: flaky -# When all validator nodes have started epoch 4 -# When miner MINER mines 10 new blocks -# Then all validators have scanned to height 52 -# When all validator nodes have started epoch 5 -# Then validator VN5 is not a member of the current network according to BASE + When all validator nodes have started epoch 4 + When miner MINER mines 10 new blocks + Then all validators have scanned to height 52 + When all validator nodes have started epoch 5 + Then validator VN5 is not a member of the current network according to BASE diff --git a/integration_tests/tests/log4rs/cucumber.yml b/integration_tests/tests/log4rs/cucumber.yml index e3f750d0e..f59e3e5a9 100644 --- a/integration_tests/tests/log4rs/cucumber.yml +++ b/integration_tests/tests/log4rs/cucumber.yml @@ -20,11 +20,11 @@ appenders: kind: compound trigger: kind: size - limit: 10mb + limit: 100mb roller: kind: fixed_window base: 1 - count: 5 + count: 10 pattern: "{{log_dir}}/dan_layer.{}.log" encoder: pattern: "{d(%Y-%m-%d %H:%M:%S)} [{t}] {l:5} {m}// {f}:{L}{n}" @@ -38,11 +38,11 @@ appenders: kind: compound trigger: kind: size - limit: 10mb + limit: 100mb roller: kind: fixed_window base: 1 - count: 5 + count: 10 pattern: "{{log_dir}}/network.{}.log" encoder: pattern: "{d(%Y-%m-%d %H:%M:%S.%f)} [{t}] [Thread:{I}] {l:5} {m} // {f}:{L}{n}" @@ -55,11 +55,11 @@ appenders: kind: compound trigger: kind: size - limit: 10mb + limit: 100mb roller: kind: fixed_window base: 1 - count: 5 + count: 10 pattern: "{{log_dir}}/base_layer.{}.log" encoder: pattern: "{d(%Y-%m-%d %H:%M:%S.%f)} [{t}] [{X(node-public-key)},{X(node-id)}] {l:5} {m} // {f}:{L}{n}" @@ -71,11 +71,11 @@ appenders: kind: compound trigger: kind: size - limit: 10mb + limit: 100mb roller: kind: fixed_window base: 1 - count: 5 + count: 10 pattern: "{{log_dir}}/wallet.{}.log" encoder: pattern: "{d(%Y-%m-%d %H:%M:%S.%f)} [{t}] [{X(node-public-key)},{X(node-id)}] {l:5} {m} // {f}:{L}{n}" @@ -87,11 +87,11 @@ appenders: kind: compound trigger: kind: size - limit: 10mb + limit: 100mb roller: kind: fixed_window base: 1 - count: 5 + count: 10 pattern: "log/validator-node/wallet_daemon.{}.log" encoder: pattern: "{d(%Y-%m-%d %H:%M:%S.%f)} [{t}] [{X(node-public-key)},{X(node-id)}] {l:5} {m} // {f}:{L}{n}" @@ -104,11 +104,11 @@ appenders: kind: compound trigger: kind: size - limit: 10mb + limit: 100mb roller: kind: fixed_window base: 1 - count: 5 + count: 10 pattern: "log/validator-node/other.{}.log" encoder: pattern: "{d(%Y-%m-%d %H:%M:%S.%f)} [{t}] [{X(node-public-key)},{X(node-id)}] {l:5} {m} // {f}:{L}{n}" diff --git a/networking/core/src/worker.rs b/networking/core/src/worker.rs index 174172aec..b454d0549 100644 --- a/networking/core/src/worker.rs +++ b/networking/core/src/worker.rs @@ -542,6 +542,14 @@ where .await?; }, None => { + // We accept all messages as we cannot validate them in this service. + // We could allow users to report back the validation result e.g. if a proposal is valid, however a + // naive implementation would likely incur a substantial cost for many messages. + self.swarm.behaviour_mut().gossipsub.report_message_validation_result( + &message_id, + &propagation_source, + gossipsub::MessageAcceptance::Ignore, + )?; warn!(target: LOG_TARGET, "📢 Discarding Gossipsub message [{topic}] ({bytes} bytes) with no source propagated by {propagation_source}", topic=message.topic, bytes=message.data.len()); }, }, diff --git a/networking/swarm/src/config.rs b/networking/swarm/src/config.rs index 298397583..871a4f172 100644 --- a/networking/swarm/src/config.rs +++ b/networking/swarm/src/config.rs @@ -40,9 +40,8 @@ impl Default for Config { relay_reservation_limits: RelayReservationLimits::default(), // This is the default for identify identify_interval: Duration::from_secs(5 * 60), - // 1MiB, 64 times the libp2p default - // TODO: change this to a lower limit when foreign proposal messages are smaller - gossip_sub_max_message_size: 1024 * 1024, + // 128KiB, 2 times the libp2p default + gossip_sub_max_message_size: 124 * 1024, } } }