From c9ae047c9a8679eceeac68405bf1569491fae1e3 Mon Sep 17 00:00:00 2001 From: Stan Bondi Date: Thu, 18 Aug 2022 14:34:06 +0400 Subject: [PATCH] merge fixes --- .../src/conversions/sidechain_features.rs | 102 ++- .../src/grpc/wallet_grpc_server.rs | 29 +- base_layer/core/src/covenants/fields.rs | 6 +- base_layer/core/src/covenants/filters/and.rs | 6 +- .../src/covenants/filters/fields_hashed_eq.rs | 2 +- .../src/covenants/filters/fields_preserved.rs | 8 +- base_layer/core/src/lib.rs | 74 +- .../core/src/proto/sidechain_features.proto | 138 ---- .../core/src/proto/sidechain_features.rs | 720 +----------------- .../transaction_components/output_features.rs | 8 +- .../transaction_components/side_chain/mod.rs | 8 - .../side_chain/sidechain_features.rs | 7 +- 12 files changed, 183 insertions(+), 925 deletions(-) diff --git a/applications/tari_app_grpc/src/conversions/sidechain_features.rs b/applications/tari_app_grpc/src/conversions/sidechain_features.rs index d459178bda..aa80844513 100644 --- a/applications/tari_app_grpc/src/conversions/sidechain_features.rs +++ b/applications/tari_app_grpc/src/conversions/sidechain_features.rs @@ -20,9 +20,14 @@ // WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE // USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -use std::convert::TryFrom; +use std::convert::{TryFrom, TryInto}; -use tari_core::transactions::transaction_components::{CodeTemplateRegistration, SideChainFeatures}; +use tari_common_types::types::{PublicKey, Signature}; +use tari_core::{ + consensus::MaxSizeString, + transactions::transaction_components::{BuildInfo, CodeTemplateRegistration, SideChainFeatures, TemplateType}, +}; +use tari_utilities::ByteArray; use crate::tari_rpc as grpc; @@ -46,3 +51,96 @@ impl TryFrom for SideChainFeatures { Ok(Self { template_registration }) } } + +// -------------------------------- TemplateRegistration -------------------------------- // +impl TryFrom for CodeTemplateRegistration { + type Error = String; + + fn try_from(value: grpc::TemplateRegistration) -> Result { + Ok(Self { + author_public_key: PublicKey::from_bytes(&value.author_public_key).map_err(|e| e.to_string())?, + author_signature: value + .author_signature + .map(Signature::try_from) + .ok_or("author_signature not provided")??, + template_name: MaxSizeString::try_from(value.template_name).map_err(|e| e.to_string())?, + template_version: value + .template_version + .try_into() + .map_err(|_| "Invalid template version")?, + template_type: value + .template_type + .map(TryFrom::try_from) + .ok_or("Template type not provided")??, + build_info: value + .build_info + .map(TryFrom::try_from) + .ok_or("Build info not provided")??, + binary_sha: value.binary_sha.try_into().map_err(|_| "Invalid commit sha")?, + binary_url: MaxSizeString::try_from(value.binary_url).map_err(|e| e.to_string())?, + }) + } +} + +impl From for grpc::TemplateRegistration { + fn from(value: CodeTemplateRegistration) -> Self { + Self { + author_public_key: value.author_public_key.to_vec(), + author_signature: Some(value.author_signature.into()), + template_name: value.template_name.to_string(), + template_version: u32::from(value.template_version), + template_type: Some(value.template_type.into()), + build_info: Some(value.build_info.into()), + binary_sha: value.binary_sha.to_vec(), + binary_url: value.binary_url.to_string(), + } + } +} + +// -------------------------------- TemplateType -------------------------------- // +impl TryFrom for TemplateType { + type Error = String; + + fn try_from(value: grpc::TemplateType) -> Result { + let template_type = value.template_type.ok_or("Template type not provided")?; + match template_type { + grpc::template_type::TemplateType::Wasm(wasm) => Ok(TemplateType::Wasm { + abi_version: wasm.abi_version.try_into().map_err(|_| "abi_version overflowed")?, + }), + } + } +} + +impl From for grpc::TemplateType { + fn from(value: TemplateType) -> Self { + match value { + TemplateType::Wasm { abi_version } => Self { + template_type: Some(grpc::template_type::TemplateType::Wasm(grpc::WasmInfo { + abi_version: abi_version.into(), + })), + }, + } + } +} + +// -------------------------------- BuildInfo -------------------------------- // + +impl TryFrom for BuildInfo { + type Error = String; + + fn try_from(value: grpc::BuildInfo) -> Result { + Ok(Self { + repo_url: value.repo_url.try_into().map_err(|_| "Invalid repo url")?, + commit_hash: value.commit_hash.try_into().map_err(|_| "Invalid commit hash")?, + }) + } +} + +impl From for grpc::BuildInfo { + fn from(value: BuildInfo) -> Self { + Self { + repo_url: value.repo_url.into_string(), + commit_hash: value.commit_hash.into_vec(), + } + } +} diff --git a/applications/tari_console_wallet/src/grpc/wallet_grpc_server.rs b/applications/tari_console_wallet/src/grpc/wallet_grpc_server.rs index f807929270..e05fb32a74 100644 --- a/applications/tari_console_wallet/src/grpc/wallet_grpc_server.rs +++ b/applications/tari_console_wallet/src/grpc/wallet_grpc_server.rs @@ -91,13 +91,19 @@ use tari_common_types::{ }; use tari_comms::{multiaddr::Multiaddr, types::CommsPublicKey, CommsNode}; use tari_core::transactions::{ - tari_amount::MicroTari, - transaction_components::{CodeTemplateRegistration, OutputFeatures, UnblindedOutput}, + tari_amount::{MicroTari, T}, + transaction_components::{ + CodeTemplateRegistration, + OutputFeatures, + OutputType, + SideChainFeatures, + UnblindedOutput, + }, }; use tari_utilities::{hex::Hex, ByteArray, Hashable}; use tari_wallet::{ connectivity_service::{OnlineStatus, WalletConnectivityInterface}, - output_manager_service::handle::OutputManagerHandle, + output_manager_service::{handle::OutputManagerHandle, UtxoSelectionCriteria}, transaction_service::{ handle::TransactionServiceHandle, storage::models::{self, WalletTransaction}, @@ -922,7 +928,7 @@ impl wallet_server::Wallet for WalletGrpcServer { &self, request: Request, ) -> Result, Status> { - let mut asset_manager = self.wallet.asset_manager.clone(); + let mut output_manager = self.wallet.output_manager_service.clone(); let mut transaction_service = self.wallet.transaction_service.clone(); let message = request.into_inner(); @@ -932,11 +938,22 @@ impl wallet_server::Wallet for WalletGrpcServer { .ok_or_else(|| Status::invalid_argument("template_registration is empty"))?, ) .map_err(|e| Status::invalid_argument(format!("template_registration is invalid: {}", e)))?; + let fee_per_gram = message.fee_per_gram; let message = format!("Template registration {}", template_registration.template_name); + let output = output_manager + .create_output_with_features(1 * T, OutputFeatures { + output_type: OutputType::CodeTemplateRegistration, + sidechain_features: Some(Box::new(SideChainFeatures { + template_registration: Some(template_registration), + })), + ..Default::default() + }) + .await + .map_err(|e| Status::internal(e.to_string()))?; - let (tx_id, transaction) = asset_manager - .create_code_template_registration(template_registration) + let (tx_id, transaction) = output_manager + .create_send_to_self_with_output(vec![output], fee_per_gram.into(), UtxoSelectionCriteria::default()) .await .map_err(|e| Status::internal(e.to_string()))?; diff --git a/base_layer/core/src/covenants/fields.rs b/base_layer/core/src/covenants/fields.rs index 9d48c224a4..38a92b2e37 100644 --- a/base_layer/core/src/covenants/fields.rs +++ b/base_layer/core/src/covenants/fields.rs @@ -358,7 +358,7 @@ mod test { fn it_returns_true_if_eq() { let output = create_outputs(1, UtxoTestParams { features: OutputFeatures { - sidechain_features: Some(Box::new(SideChainFeatures {})), + sidechain_features: Some(Box::new(SideChainFeatures::default())), ..Default::default() }, script: script![Drop Nop], @@ -377,7 +377,7 @@ mod test { .is_eq(&output, &output.features.output_type) .unwrap()); assert!(OutputField::FeaturesSideChainFeatures - .is_eq(&output, &SideChainFeatures {}) + .is_eq(&output, &SideChainFeatures::default()) .unwrap()); assert!(OutputField::FeaturesSideChainFeatures .is_eq(&output, output.features.sidechain_features.as_ref().unwrap()) @@ -394,7 +394,7 @@ mod test { fn it_returns_false_if_not_eq() { let output = create_outputs(1, UtxoTestParams { features: OutputFeatures { - sidechain_features: Some(Box::new(SideChainFeatures {})), + sidechain_features: Some(Box::new(SideChainFeatures::default())), ..Default::default() }, script: script![Drop Nop], diff --git a/base_layer/core/src/covenants/filters/and.rs b/base_layer/core/src/covenants/filters/and.rs index 726b7e16e1..1473f21111 100644 --- a/base_layer/core/src/covenants/filters/and.rs +++ b/base_layer/core/src/covenants/filters/and.rs @@ -56,12 +56,12 @@ mod test { let input = create_input(); let (mut context, outputs) = setup_filter_test(&covenant, &input, 0, |outputs| { outputs[5].features.maturity = 42; - outputs[5].features.sidechain_features = Some(Box::new(SideChainFeatures {})); + outputs[5].features.sidechain_features = Some(Box::new(SideChainFeatures::default())); outputs[7].features.maturity = 42; - outputs[7].features.sidechain_features = Some(Box::new(SideChainFeatures {})); + outputs[7].features.sidechain_features = Some(Box::new(SideChainFeatures::default())); // Does not have maturity = 42 outputs[8].features.maturity = 123; - outputs[8].features.sidechain_features = Some(Box::new(SideChainFeatures {})); + outputs[8].features.sidechain_features = Some(Box::new(SideChainFeatures::default())); }); let mut output_set = OutputSet::new(&outputs); diff --git a/base_layer/core/src/covenants/filters/fields_hashed_eq.rs b/base_layer/core/src/covenants/filters/fields_hashed_eq.rs index 32a6922de3..b88ba4d2f9 100644 --- a/base_layer/core/src/covenants/filters/fields_hashed_eq.rs +++ b/base_layer/core/src/covenants/filters/fields_hashed_eq.rs @@ -55,7 +55,7 @@ mod test { fn it_filters_outputs_with_fields_that_hash_to_given_hash() { let features = OutputFeatures { maturity: 42, - sidechain_features: Some(Box::new(SideChainFeatures {})), + sidechain_features: Some(Box::new(SideChainFeatures::default())), ..Default::default() }; let hashed = Challenge::new().chain(features.to_consensus_bytes()).finalize(); diff --git a/base_layer/core/src/covenants/filters/fields_preserved.rs b/base_layer/core/src/covenants/filters/fields_preserved.rs index a7ca7b869a..be69a87383 100644 --- a/base_layer/core/src/covenants/filters/fields_preserved.rs +++ b/base_layer/core/src/covenants/filters/fields_preserved.rs @@ -49,17 +49,17 @@ mod test { let covenant = covenant!(fields_preserved(@fields(@field::features_maturity, @field::features_flags))); let mut input = create_input(); input.set_maturity(42).unwrap(); - input.features_mut().unwrap().sidechain_features = Some(Box::new(SideChainFeatures {})); + input.features_mut().unwrap().sidechain_features = Some(Box::new(SideChainFeatures::default())); input.features_mut().unwrap().output_type = OutputType::Standard; let (mut context, outputs) = setup_filter_test(&covenant, &input, 0, |outputs| { outputs[5].features.maturity = 42; - outputs[5].features.sidechain_features = Some(Box::new(SideChainFeatures {})); + outputs[5].features.sidechain_features = Some(Box::new(SideChainFeatures::default())); outputs[5].features.output_type = OutputType::Standard; outputs[7].features.maturity = 42; outputs[7].features.output_type = OutputType::Standard; - outputs[7].features.sidechain_features = Some(Box::new(SideChainFeatures {})); + outputs[7].features.sidechain_features = Some(Box::new(SideChainFeatures::default())); outputs[8].features.maturity = 42; - outputs[8].features.sidechain_features = Some(Box::new(SideChainFeatures {})); + outputs[8].features.sidechain_features = Some(Box::new(SideChainFeatures::default())); outputs[8].features.output_type = OutputType::Coinbase; }); let mut output_set = OutputSet::new(&outputs); diff --git a/base_layer/core/src/lib.rs b/base_layer/core/src/lib.rs index 77b6439910..b214b596dd 100644 --- a/base_layer/core/src/lib.rs +++ b/base_layer/core/src/lib.rs @@ -68,41 +68,47 @@ pub mod large_ints { } pub use large_ints::{U256, U512}; -use tari_crypto::{hash::blake2::Blake256, hash_domain, hashing::DomainSeparatedHasher}; -use tari_mmr::{pruned_hashset::PrunedHashSet, Hash, MerkleMountainRange, MutableMmr}; -hash_domain!( - KernelMmrHashDomain, - "com.tari.tari_project.base_layer.core.kernel_mmr", - 1 -); -pub type KernelMmrHasherBlake256 = DomainSeparatedHasher; -pub type KernelMmr = MerkleMountainRange>; -pub type PrunedKernelMmr = MerkleMountainRange; +#[cfg(feature = "base_node")] +mod mmr_hashing { + use tari_crypto::{hash::blake2::Blake256, hash_domain, hashing::DomainSeparatedHasher}; + use tari_mmr::{pruned_hashset::PrunedHashSet, Hash, MerkleMountainRange, MutableMmr}; + + hash_domain!( + KernelMmrHashDomain, + "com.tari.tari_project.base_layer.core.kernel_mmr", + 1 + ); + pub type KernelMmrHasherBlake256 = DomainSeparatedHasher; + pub type KernelMmr = MerkleMountainRange>; + pub type PrunedKernelMmr = MerkleMountainRange; -hash_domain!( - WitnessMmrHashDomain, - "com.tari.tari_project.base_layer.core.witness_mmr", - 1 -); -pub type WitnessMmrHasherBlake256 = DomainSeparatedHasher; -pub type WitnessMmr = MerkleMountainRange>; -pub type PrunedWitnessMmr = MerkleMountainRange; + hash_domain!( + WitnessMmrHashDomain, + "com.tari.tari_project.base_layer.core.witness_mmr", + 1 + ); + pub type WitnessMmrHasherBlake256 = DomainSeparatedHasher; + pub type WitnessMmr = MerkleMountainRange>; + pub type PrunedWitnessMmr = MerkleMountainRange; -hash_domain!( - OutputMmrHashDomain, - "com.tari.tari_project.base_layer.core.output_mmr", - 1 -); -pub type OutputMmrHasherBlake256 = DomainSeparatedHasher; -pub type MutableOutputMmr = MutableMmr>; -pub type PrunedOutputMmr = MerkleMountainRange; -pub type MutablePrunedOutputMmr = MutableMmr; + hash_domain!( + OutputMmrHashDomain, + "com.tari.tari_project.base_layer.core.output_mmr", + 1 + ); + pub type OutputMmrHasherBlake256 = DomainSeparatedHasher; + pub type MutableOutputMmr = MutableMmr>; + pub type PrunedOutputMmr = MerkleMountainRange; + pub type MutablePrunedOutputMmr = MutableMmr; -hash_domain!( - InputMmrHashDomain, - "com.tari.tari_project.base_layer.core.output_mmr", - 1 -); -pub type InputMmrHasherBlake256 = DomainSeparatedHasher; -pub type PrunedInputMmr = MerkleMountainRange; + hash_domain!( + InputMmrHashDomain, + "com.tari.tari_project.base_layer.core.output_mmr", + 1 + ); + pub type InputMmrHasherBlake256 = DomainSeparatedHasher; + pub type PrunedInputMmr = MerkleMountainRange; +} +#[cfg(feature = "base_node")] +pub use mmr_hashing::*; diff --git a/base_layer/core/src/proto/sidechain_features.proto b/base_layer/core/src/proto/sidechain_features.proto index 801b6e0d3a..b353c2f468 100644 --- a/base_layer/core/src/proto/sidechain_features.proto +++ b/base_layer/core/src/proto/sidechain_features.proto @@ -8,15 +8,7 @@ import "types.proto"; package tari.types; message SideChainFeatures { - bytes contract_id = 1; - ContractDefinition definition = 2; TemplateRegistration template_registration = 3; - ContractConstitution constitution = 4; - ContractAcceptance acceptance = 5; - ContractUpdateProposal update_proposal = 6; - ContractUpdateProposalAcceptance update_proposal_acceptance = 7; - ContractAmendment amendment = 8; - ContractCheckpoint checkpoint = 9; } message TemplateRegistration { @@ -43,133 +35,3 @@ message TemplateType { string repo_url = 1; bytes commit_hash = 2; } - -message ContractCheckpoint { - uint64 checkpoint_number = 1; - bytes merkle_root = 2; - CommitteeSignatures signatures = 3; -} - -message ContractConstitution { - CommitteeMembers validator_committee = 1; - ContractAcceptanceRequirements acceptance_requirements = 2; - SideChainConsensus consensus = 3; - CheckpointParameters checkpoint_params = 4; - ConstitutionChangeRules constitution_change_rules = 5; -} - -message ContractAcceptanceRequirements { - uint64 acceptance_period_expiry = 1; - uint32 minimum_quorum_required = 2; -} - -message CommitteeMembers { - repeated bytes members = 1; -} - -message CheckpointParameters { - uint64 abandoned_interval = 1; - uint32 minimum_quorum_required = 2; - uint64 quarantine_interval = 3; -} - -message ConstitutionChangeRules { - uint32 change_flags = 1; - RequirementsForConstitutionChange requirements_for_constitution_change = 2; -} - -message RequirementsForConstitutionChange { - // The minimum required constitution committee signatures required for a constitution change proposal to pass. - uint32 minimum_constitution_committee_signatures = 1; - // An allowlist of keys that are able to accept and ratify the initial constitution and its amendments. If this is - // None, the constitution cannot be amended. - CommitteeMembers constitution_committee = 2; - // An allowlist of keys that can be used in case of checkpoint abandonment. These keys can quarantine the the constitution - // and if the quarantine period is exceeded, the backup keys can take over. - CommitteeMembers backup_keys = 3; -} - -enum SideChainConsensus { - UNSPECIFIED = 0; - BFT = 1; - PROOF_OF_WORK = 2; - MERKLE_ROOT = 3; -} - -// TODO: deprecated -message AssetOutputFeatures { - bytes public_key = 1; - repeated uint32 template_ids_implemented = 2; - repeated TemplateParameter template_parameters = 3; -} - -message TemplateParameter { - uint32 template_id = 1; - uint32 template_data_version = 2; - bytes template_data = 3; -} - -message MintNonFungibleFeatures { - bytes asset_public_key = 1; - Commitment asset_owner_commitment = 2; -} - -message SideChainCheckpointFeatures { - bytes merkle_root = 1; - repeated bytes committee = 2; -} - -message CommitteeDefinitionFeatures { - repeated bytes committee = 1; - uint64 effective_sidechain_height = 2; -} - -message ContractDefinition { - bytes contract_name = 1; - bytes contract_issuer = 2; - ContractSpecification contract_spec = 3; -} - -message ContractSpecification { - bytes runtime = 1; - repeated PublicFunction public_functions = 2; -} - -message PublicFunction { - bytes name = 1; - FunctionRef function = 2; -} - -message FunctionRef { - bytes template_id = 1; - uint32 function_id = 2; -} - -message ContractAcceptance { - bytes validator_node_public_key = 1; - Signature signature = 2; -} - -message ContractUpdateProposal { - uint64 proposal_id = 1; - Signature signature = 2; - ContractConstitution updated_constitution = 3; -} - -message ContractUpdateProposalAcceptance { - uint64 proposal_id = 1; - bytes validator_node_public_key = 2; - Signature signature = 3; -} - -message ContractAmendment { - uint64 proposal_id = 1; - CommitteeMembers validator_committee = 2; - CommitteeSignatures validator_signatures = 3; - ContractConstitution updated_constitution = 4; - uint64 activation_window = 5; -} - -message CommitteeSignatures { - repeated SignerSignature signatures = 1; -} diff --git a/base_layer/core/src/proto/sidechain_features.rs b/base_layer/core/src/proto/sidechain_features.rs index 1473e716d6..10b1fb2b3a 100644 --- a/base_layer/core/src/proto/sidechain_features.rs +++ b/base_layer/core/src/proto/sidechain_features.rs @@ -24,58 +24,20 @@ use std::convert::{TryFrom, TryInto}; -use tari_common_types::types::{Commitment, FixedHash, PublicKey, Signature}; -use tari_crypto::tari_utilities::ByteArray; +use tari_common_types::types::{PublicKey, Signature}; +use tari_utilities::ByteArray; use crate::{ consensus::MaxSizeString, proto, - transactions::transaction_components::{ - bytes_into_fixed_string, - AssetOutputFeatures, - BuildInfo, - CheckpointParameters, - CodeTemplateRegistration, - CommitteeDefinitionFeatures, - CommitteeMembers, - CommitteeSignatures, - ConstitutionChangeFlags, - ConstitutionChangeRules, - ContractAcceptance, - ContractAcceptanceRequirements, - ContractAmendment, - ContractCheckpoint, - ContractConstitution, - ContractDefinition, - ContractSpecification, - ContractUpdateProposal, - ContractUpdateProposalAcceptance, - FunctionRef, - MintNonFungibleFeatures, - PublicFunction, - RequirementsForConstitutionChange, - SideChainCheckpointFeatures, - SideChainConsensus, - SideChainFeatures, - SignerSignature, - TemplateParameter, - TemplateType, - }, + transactions::transaction_components::{BuildInfo, CodeTemplateRegistration, SideChainFeatures, TemplateType}, }; //---------------------------------- SideChainFeatures --------------------------------------------// impl From for proto::types::SideChainFeatures { fn from(value: SideChainFeatures) -> Self { Self { - contract_id: value.contract_id.to_vec(), - definition: value.definition.map(Into::into), template_registration: value.template_registration.map(Into::into), - constitution: value.constitution.map(Into::into), - acceptance: value.acceptance.map(Into::into), - update_proposal: value.update_proposal.map(Into::into), - update_proposal_acceptance: value.update_proposal_acceptance.map(Into::into), - amendment: value.amendment.map(Into::into), - checkpoint: value.checkpoint.map(Into::into), } } } @@ -84,36 +46,12 @@ impl TryFrom for SideChainFeatures { type Error = String; fn try_from(features: proto::types::SideChainFeatures) -> Result { - let contract_id = features.contract_id.try_into().map_err(|_| "Invalid contract_id")?; - let definition = features.definition.map(ContractDefinition::try_from).transpose()?; - let constitution = features.constitution.map(ContractConstitution::try_from).transpose()?; - let acceptance = features.acceptance.map(ContractAcceptance::try_from).transpose()?; let template_registration = features .template_registration .map(CodeTemplateRegistration::try_from) .transpose()?; - let update_proposal = features - .update_proposal - .map(ContractUpdateProposal::try_from) - .transpose()?; - let update_proposal_acceptance = features - .update_proposal_acceptance - .map(ContractUpdateProposalAcceptance::try_from) - .transpose()?; - let amendment = features.amendment.map(ContractAmendment::try_from).transpose()?; - let checkpoint = features.checkpoint.map(ContractCheckpoint::try_from).transpose()?; - Ok(Self { - contract_id, - definition, - template_registration, - constitution, - acceptance, - update_proposal, - update_proposal_acceptance, - amendment, - checkpoint, - }) + Ok(Self { template_registration }) } } @@ -211,653 +149,3 @@ impl From for proto::types::BuildInfo { } } } - -//---------------------------------- ContractConstitution --------------------------------------------// -impl From for proto::types::ContractConstitution { - fn from(value: ContractConstitution) -> Self { - Self { - validator_committee: Some(value.validator_committee.into()), - acceptance_requirements: Some(value.acceptance_requirements.into()), - consensus: value.consensus.into(), - checkpoint_params: Some(value.checkpoint_params.into()), - constitution_change_rules: Some(value.constitution_change_rules.into()), - } - } -} - -impl TryFrom for ContractConstitution { - type Error = String; - - fn try_from(value: proto::types::ContractConstitution) -> Result { - use num_traits::FromPrimitive; - let validator_committee = value - .validator_committee - .map(TryInto::try_into) - .ok_or("validator_committee not provided")??; - let acceptance_requirements = value - .acceptance_requirements - .map(TryInto::try_into) - .ok_or("acceptance_requirements not provided")??; - let consensus = SideChainConsensus::from_i32(value.consensus).ok_or("Invalid SideChainConsensus")?; - let checkpoint_params = value - .checkpoint_params - .map(TryInto::try_into) - .ok_or("checkpoint_params not provided")??; - let constitution_change_rules = value - .constitution_change_rules - .map(TryInto::try_into) - .ok_or("constitution_change_rules not provided")??; - - Ok(Self { - validator_committee, - acceptance_requirements, - consensus, - checkpoint_params, - constitution_change_rules, - }) - } -} - -//---------------------------------- ContractCheckpoint --------------------------------------------// -impl From for proto::types::ContractCheckpoint { - fn from(value: ContractCheckpoint) -> Self { - Self { - checkpoint_number: value.checkpoint_number, - merkle_root: value.merkle_root.to_vec(), - signatures: Some(value.signatures.into()), - } - } -} - -impl TryFrom for ContractCheckpoint { - type Error = String; - - fn try_from(value: proto::types::ContractCheckpoint) -> Result { - let merkle_root = value.merkle_root.try_into().map_err(|_| "Invalid merkle root")?; - let signatures = value.signatures.map(TryInto::try_into).transpose()?.unwrap_or_default(); - Ok(Self { - checkpoint_number: value.checkpoint_number, - merkle_root, - signatures, - }) - } -} - -//---------------------------------- ContractAcceptanceRequirements --------------------------------------------// -impl From for proto::types::ContractAcceptanceRequirements { - fn from(value: ContractAcceptanceRequirements) -> Self { - Self { - acceptance_period_expiry: value.acceptance_period_expiry, - minimum_quorum_required: value.minimum_quorum_required, - } - } -} - -impl TryFrom for ContractAcceptanceRequirements { - type Error = String; - - fn try_from(value: proto::types::ContractAcceptanceRequirements) -> Result { - Ok(Self { - acceptance_period_expiry: value.acceptance_period_expiry, - minimum_quorum_required: value.minimum_quorum_required, - }) - } -} - -//---------------------------------- ContractAcceptance --------------------------------------------// - -impl From for proto::types::ContractAcceptance { - fn from(value: ContractAcceptance) -> Self { - Self { - validator_node_public_key: value.validator_node_public_key.as_bytes().to_vec(), - signature: Some(value.signature.into()), - } - } -} - -impl TryFrom for ContractAcceptance { - type Error = String; - - fn try_from(value: proto::types::ContractAcceptance) -> Result { - let validator_node_public_key = - PublicKey::from_bytes(value.validator_node_public_key.as_bytes()).map_err(|err| format!("{:?}", err))?; - let signature = value - .signature - .ok_or_else(|| "signature not provided".to_string())? - .try_into()?; - - Ok(Self { - validator_node_public_key, - signature, - }) - } -} - -//---------------------------------- ContractUpdateProposal --------------------------------------------// - -impl From for proto::types::ContractUpdateProposal { - fn from(value: ContractUpdateProposal) -> Self { - Self { - proposal_id: value.proposal_id, - signature: Some(value.signature.into()), - updated_constitution: Some(value.updated_constitution.into()), - } - } -} - -impl TryFrom for ContractUpdateProposal { - type Error = String; - - fn try_from(value: proto::types::ContractUpdateProposal) -> Result { - let signature = value - .signature - .ok_or_else(|| "signature not provided".to_string())? - .try_into()?; - - let updated_constitution = value - .updated_constitution - .ok_or_else(|| "updated_constiution not provided".to_string())? - .try_into()?; - - Ok(Self { - proposal_id: value.proposal_id, - signature, - updated_constitution, - }) - } -} - -//---------------------------------- ContractUpdateProposalAcceptance --------------------------------------------// - -impl From for proto::types::ContractUpdateProposalAcceptance { - fn from(value: ContractUpdateProposalAcceptance) -> Self { - Self { - proposal_id: value.proposal_id, - validator_node_public_key: value.validator_node_public_key.as_bytes().to_vec(), - signature: Some(value.signature.into()), - } - } -} - -impl TryFrom for ContractUpdateProposalAcceptance { - type Error = String; - - fn try_from(value: proto::types::ContractUpdateProposalAcceptance) -> Result { - let validator_node_public_key = - PublicKey::from_bytes(value.validator_node_public_key.as_bytes()).map_err(|err| format!("{:?}", err))?; - let signature = value - .signature - .ok_or_else(|| "signature not provided".to_string())? - .try_into()?; - - Ok(Self { - proposal_id: value.proposal_id, - validator_node_public_key, - signature, - }) - } -} - -//---------------------------------- ContractAmendment --------------------------------------------// - -impl From for proto::types::ContractAmendment { - fn from(value: ContractAmendment) -> Self { - Self { - proposal_id: value.proposal_id, - validator_committee: Some(value.validator_committee.into()), - validator_signatures: Some(value.validator_signatures.into()), - updated_constitution: Some(value.updated_constitution.into()), - activation_window: value.activation_window, - } - } -} - -impl TryFrom for ContractAmendment { - type Error = String; - - fn try_from(value: proto::types::ContractAmendment) -> Result { - let validator_committee = value - .validator_committee - .map(TryInto::try_into) - .ok_or("validator_committee not provided")??; - - let validator_signatures = value - .validator_signatures - .map(TryInto::try_into) - .ok_or("validator_signatures not provided")??; - - let updated_constitution = value - .updated_constitution - .ok_or_else(|| "updated_constiution not provided".to_string())? - .try_into()?; - - Ok(Self { - proposal_id: value.proposal_id, - validator_committee, - validator_signatures, - updated_constitution, - activation_window: value.activation_window, - }) - } -} - -//---------------------------------- SideChainConsensus --------------------------------------------// -impl From for proto::types::SideChainConsensus { - fn from(value: SideChainConsensus) -> Self { - #[allow(clippy::enum_glob_use)] - use proto::types::SideChainConsensus::*; - match value { - SideChainConsensus::Bft => Bft, - SideChainConsensus::ProofOfWork => ProofOfWork, - SideChainConsensus::MerkleRoot => MerkleRoot, - } - } -} - -impl TryFrom for SideChainConsensus { - type Error = String; - - fn try_from(value: proto::types::SideChainConsensus) -> Result { - #[allow(clippy::enum_glob_use)] - use proto::types::SideChainConsensus::*; - match value { - Unspecified => Err("Side chain consensus not specified or invalid".to_string()), - Bft => Ok(SideChainConsensus::Bft), - ProofOfWork => Ok(SideChainConsensus::ProofOfWork), - MerkleRoot => Ok(SideChainConsensus::MerkleRoot), - } - } -} - -//---------------------------------- CheckpointParameters --------------------------------------------// -impl From for proto::types::CheckpointParameters { - fn from(value: CheckpointParameters) -> Self { - Self { - minimum_quorum_required: value.minimum_quorum_required, - abandoned_interval: value.abandoned_interval, - quarantine_interval: value.quarantine_interval, - } - } -} - -impl TryFrom for CheckpointParameters { - type Error = String; - - fn try_from(value: proto::types::CheckpointParameters) -> Result { - Ok(Self { - minimum_quorum_required: value.minimum_quorum_required, - abandoned_interval: value.abandoned_interval, - quarantine_interval: value.quarantine_interval, - }) - } -} - -//---------------------------------- ConstitutionChangeRules --------------------------------------------// -impl From for proto::types::ConstitutionChangeRules { - fn from(value: ConstitutionChangeRules) -> Self { - Self { - change_flags: value.change_flags.bits().into(), - requirements_for_constitution_change: value.requirements_for_constitution_change.map(Into::into), - } - } -} - -impl TryFrom for ConstitutionChangeRules { - type Error = String; - - fn try_from(value: proto::types::ConstitutionChangeRules) -> Result { - Ok(Self { - change_flags: u8::try_from(value.change_flags) - .ok() - .and_then(ConstitutionChangeFlags::from_bits) - .ok_or("Invalid change_flags")?, - requirements_for_constitution_change: value - .requirements_for_constitution_change - .map(RequirementsForConstitutionChange::try_from) - .transpose()?, - }) - } -} - -//---------------------------------- RequirementsForConstitutionChange --------------------------------------------// -impl From for proto::types::RequirementsForConstitutionChange { - fn from(value: RequirementsForConstitutionChange) -> Self { - Self { - minimum_constitution_committee_signatures: value.minimum_constitution_committee_signatures, - constitution_committee: value.constitution_committee.map(Into::into), - backup_keys: value.backup_keys.map(Into::into), - } - } -} - -impl TryFrom for RequirementsForConstitutionChange { - type Error = String; - - fn try_from(value: proto::types::RequirementsForConstitutionChange) -> Result { - Ok(Self { - minimum_constitution_committee_signatures: value.minimum_constitution_committee_signatures, - constitution_committee: value - .constitution_committee - .map(CommitteeMembers::try_from) - .transpose()?, - backup_keys: value.backup_keys.map(CommitteeMembers::try_from).transpose()?, - }) - } -} - -//---------------------------------- CommitteeMembers --------------------------------------------// -impl From for proto::types::CommitteeMembers { - fn from(value: CommitteeMembers) -> Self { - Self { - members: value.members().iter().map(|pk| pk.to_vec()).collect(), - } - } -} - -impl TryFrom for CommitteeMembers { - type Error = String; - - fn try_from(value: proto::types::CommitteeMembers) -> Result { - if value.members.len() > CommitteeMembers::MAX_MEMBERS { - return Err(format!( - "Too many committee members: expected {} but got {}", - CommitteeMembers::MAX_MEMBERS, - value.members.len() - )); - } - - let members = value - .members - .iter() - .enumerate() - .map(|(i, c)| { - PublicKey::from_bytes(c) - .map_err(|err| format!("committee member #{} was not a valid public key: {}", i + 1, err)) - }) - .collect::, _>>()?; - - let members = CommitteeMembers::try_from(members).map_err(|e| e.to_string())?; - Ok(members) - } -} - -//---------------------------------- CommitteeSignatures --------------------------------------------// -impl From for proto::types::CommitteeSignatures { - fn from(value: CommitteeSignatures) -> Self { - Self { - signatures: value.signatures().iter().map(Into::into).collect(), - } - } -} - -impl TryFrom for CommitteeSignatures { - type Error = String; - - fn try_from(value: proto::types::CommitteeSignatures) -> Result { - if value.signatures.len() > CommitteeSignatures::MAX_SIGNATURES { - return Err(format!( - "Too many committee signatures: expected {} but got {}", - CommitteeSignatures::MAX_SIGNATURES, - value.signatures.len() - )); - } - - let signatures = value - .signatures - .into_iter() - .enumerate() - .map(|(i, s)| { - SignerSignature::try_from(s) - .map_err(|err| format!("committee signature #{} was not a valid signature: {}", i + 1, err)) - }) - .collect::, _>>()?; - - let signatures = CommitteeSignatures::try_from(signatures).map_err(|e| e.to_string())?; - Ok(signatures) - } -} - -// TODO: deprecated - -impl TryFrom for AssetOutputFeatures { - type Error = String; - - fn try_from(features: proto::types::AssetOutputFeatures) -> Result { - let public_key = PublicKey::from_bytes(features.public_key.as_bytes()).map_err(|err| format!("{:?}", err))?; - - Ok(Self { - public_key, - template_ids_implemented: features.template_ids_implemented, - template_parameters: features.template_parameters.into_iter().map(|s| s.into()).collect(), - }) - } -} - -impl From for proto::types::AssetOutputFeatures { - fn from(features: AssetOutputFeatures) -> Self { - Self { - public_key: features.public_key.as_bytes().to_vec(), - template_ids_implemented: features.template_ids_implemented, - template_parameters: features.template_parameters.into_iter().map(|tp| tp.into()).collect(), - } - } -} - -impl From for TemplateParameter { - fn from(source: proto::types::TemplateParameter) -> Self { - Self { - template_id: source.template_id, - template_data_version: source.template_data_version, - template_data: source.template_data, - } - } -} - -impl From for proto::types::TemplateParameter { - fn from(source: TemplateParameter) -> Self { - Self { - template_id: source.template_id, - template_data_version: source.template_data_version, - template_data: source.template_data, - } - } -} - -impl TryFrom for MintNonFungibleFeatures { - type Error = String; - - fn try_from(value: proto::types::MintNonFungibleFeatures) -> Result { - let asset_public_key = - PublicKey::from_bytes(value.asset_public_key.as_bytes()).map_err(|err| format!("{:?}", err))?; - - let asset_owner_commitment = value - .asset_owner_commitment - .map(|c| Commitment::from_bytes(&c.data)) - .ok_or_else(|| "asset_owner_commitment is missing".to_string())? - .map_err(|err| err.to_string())?; - Ok(Self { - asset_public_key, - asset_owner_commitment, - }) - } -} - -impl From for proto::types::MintNonFungibleFeatures { - fn from(value: MintNonFungibleFeatures) -> Self { - Self { - asset_public_key: value.asset_public_key.as_bytes().to_vec(), - asset_owner_commitment: Some(value.asset_owner_commitment.into()), - } - } -} - -impl TryFrom for SideChainCheckpointFeatures { - type Error = String; - - fn try_from(value: proto::types::SideChainCheckpointFeatures) -> Result { - if value.merkle_root.len() != FixedHash::byte_size() { - return Err(format!( - "Invalid side chain checkpoint merkle length {}", - value.merkle_root.len() - )); - } - let merkle_root = FixedHash::try_from(value.merkle_root).map_err(|e| e.to_string())?; - let committee = value - .committee - .into_iter() - .map(|c| PublicKey::from_bytes(&c).map_err(|err| format!("{:?}", err))) - .collect::>()?; - Ok(Self { merkle_root, committee }) - } -} - -impl From for proto::types::SideChainCheckpointFeatures { - fn from(value: SideChainCheckpointFeatures) -> Self { - Self { - merkle_root: value.merkle_root.as_bytes().to_vec(), - committee: value.committee.into_iter().map(|c| c.as_bytes().to_vec()).collect(), - } - } -} - -impl TryFrom for CommitteeDefinitionFeatures { - type Error = String; - - fn try_from(value: proto::types::CommitteeDefinitionFeatures) -> Result { - let committee = value - .committee - .into_iter() - .map(|c| PublicKey::from_bytes(&c).map_err(|err| format!("{:?}", err))) - .collect::>()?; - let effective_sidechain_height = value.effective_sidechain_height; - - Ok(Self { - committee, - effective_sidechain_height, - }) - } -} - -impl From for proto::types::CommitteeDefinitionFeatures { - fn from(value: CommitteeDefinitionFeatures) -> Self { - Self { - committee: value.committee.into_iter().map(|c| c.as_bytes().to_vec()).collect(), - effective_sidechain_height: value.effective_sidechain_height, - } - } -} - -//---------------------------------- ContractDefinition --------------------------------------------// - -impl TryFrom for ContractDefinition { - type Error = String; - - fn try_from(value: proto::types::ContractDefinition) -> Result { - let contract_name = bytes_into_fixed_string(value.contract_name); - - let contract_issuer = - PublicKey::from_bytes(value.contract_issuer.as_bytes()).map_err(|err| format!("{:?}", err))?; - - let contract_spec = value - .contract_spec - .map(ContractSpecification::try_from) - .ok_or_else(|| "contract_spec is missing".to_string())??; - - Ok(Self { - contract_name, - contract_issuer, - contract_spec, - }) - } -} - -impl From for proto::types::ContractDefinition { - fn from(value: ContractDefinition) -> Self { - let contract_name = value.contract_name.as_bytes().to_vec(); - let contract_issuer = value.contract_issuer.as_bytes().to_vec(); - - Self { - contract_name, - contract_issuer, - contract_spec: Some(value.contract_spec.into()), - } - } -} - -impl TryFrom for ContractSpecification { - type Error = String; - - fn try_from(value: proto::types::ContractSpecification) -> Result { - let runtime = bytes_into_fixed_string(value.runtime); - let public_functions = value - .public_functions - .into_iter() - .map(PublicFunction::try_from) - .collect::>()?; - - Ok(Self { - runtime, - public_functions, - }) - } -} - -impl From for proto::types::ContractSpecification { - fn from(value: ContractSpecification) -> Self { - let public_functions = value.public_functions.into_iter().map(|f| f.into()).collect(); - Self { - runtime: value.runtime.as_bytes().to_vec(), - public_functions, - } - } -} - -impl TryFrom for PublicFunction { - type Error = String; - - fn try_from(value: proto::types::PublicFunction) -> Result { - let function = value - .function - .map(FunctionRef::try_from) - .ok_or_else(|| "function is missing".to_string())??; - - Ok(Self { - name: bytes_into_fixed_string(value.name), - function, - }) - } -} - -impl From for proto::types::PublicFunction { - fn from(value: PublicFunction) -> Self { - Self { - name: value.name.as_bytes().to_vec(), - function: Some(value.function.into()), - } - } -} - -impl TryFrom for FunctionRef { - type Error = String; - - fn try_from(value: proto::types::FunctionRef) -> Result { - let template_id = FixedHash::try_from(value.template_id).map_err(|err| format!("{:?}", err))?; - let function_id = u16::try_from(value.function_id).map_err(|_| "Invalid function_id: overflowed u16")?; - - Ok(Self { - template_id, - function_id, - }) - } -} - -impl From for proto::types::FunctionRef { - fn from(value: FunctionRef) -> Self { - let template_id = value.template_id.as_bytes().to_vec(); - - Self { - template_id, - function_id: value.function_id.into(), - } - } -} diff --git a/base_layer/core/src/transactions/transaction_components/output_features.rs b/base_layer/core/src/transactions/transaction_components/output_features.rs index ec61627547..f8b9fb6980 100644 --- a/base_layer/core/src/transactions/transaction_components/output_features.rs +++ b/base_layer/core/src/transactions/transaction_components/output_features.rs @@ -102,11 +102,9 @@ impl OutputFeatures { pub fn for_template_registration(template_registration: CodeTemplateRegistration) -> OutputFeatures { OutputFeatures { output_type: OutputType::CodeTemplateRegistration, - sidechain_features: Some(Box::new( - SideChainFeatures::builder(Default::default()) - .with_template_registration(template_registration) - .finish(), - )), + sidechain_features: Some(Box::new(SideChainFeatures { + template_registration: Some(template_registration), + })), ..Default::default() } } diff --git a/base_layer/core/src/transactions/transaction_components/side_chain/mod.rs b/base_layer/core/src/transactions/transaction_components/side_chain/mod.rs index 4c4554c9b8..2c7e37fe7c 100644 --- a/base_layer/core/src/transactions/transaction_components/side_chain/mod.rs +++ b/base_layer/core/src/transactions/transaction_components/side_chain/mod.rs @@ -25,11 +25,3 @@ pub use sidechain_features::SideChainFeatures; mod template_registration; pub use template_registration::{BuildInfo, CodeTemplateRegistration, TemplateType}; - -// Length of FixedString -pub const FIXED_STR_LEN: usize = 32; -pub type FixedString = [u8; FIXED_STR_LEN]; - -pub fn bytes_into_fixed_string>(value: T) -> FixedString { - tari_common_types::array::copy_into_fixed_array_lossy::<_, FIXED_STR_LEN>(value.as_ref()) -} diff --git a/base_layer/core/src/transactions/transaction_components/side_chain/sidechain_features.rs b/base_layer/core/src/transactions/transaction_components/side_chain/sidechain_features.rs index d002e789e5..632f5fd4fe 100644 --- a/base_layer/core/src/transactions/transaction_components/side_chain/sidechain_features.rs +++ b/base_layer/core/src/transactions/transaction_components/side_chain/sidechain_features.rs @@ -29,13 +29,11 @@ use crate::{ transactions::transaction_components::CodeTemplateRegistration, }; -#[derive(Debug, Clone, Hash, PartialEq, Deserialize, Serialize, Eq)] +#[derive(Debug, Clone, Hash, PartialEq, Deserialize, Serialize, Eq, Default)] pub struct SideChainFeatures { pub template_registration: Option, } -impl SideChainFeatures {} - impl ConsensusEncoding for SideChainFeatures { fn consensus_encode(&self, writer: &mut W) -> Result<(), Error> { self.template_registration.consensus_encode(writer)?; @@ -57,13 +55,12 @@ impl ConsensusDecoding for SideChainFeatures { mod tests { use std::convert::TryInto; - use tari_common_types::types::{PublicKey, Signature}; use tari_utilities::hex::from_hex; use super::*; use crate::{ consensus::{check_consensus_encoding_correctness, MaxSizeString}, - transactions::transaction_components::{bytes_into_fixed_string, BuildInfo, SignerSignature, TemplateType}, + transactions::transaction_components::{BuildInfo, TemplateType}, }; #[allow(clippy::too_many_lines)]