Skip to content

Commit

Permalink
feat: constitution publishing (#4150)
Browse files Browse the repository at this point in the history
Description
---
Update the committee proposals into constitution publishing.

Motivation and Context
---
Meet the new requirements for proposing a committee. Update old code to match new specifications. Refactor the existing functionality instead of introducing net new functionality.

It may have been a better choice to specify a json file as a constitution but I wanted to keep similar functionality to how it was being done. By the end of the PR this was obviously a less ideal choice. We accept 4 arguments to create the constitution at the moment. Where as there are more arguments that can be utilized.

How Has This Been Tested?
---

- With CI passing. 
- With a new integration test.
- Manually using the following command:
`cargo run --bin tari_console_wallet -- -b . --command "publish-constitution-definition --json-file ../../integration_tests/fixtures/constitution_definition.json"`
  • Loading branch information
brianp committed Jun 7, 2022
1 parent 56442ad commit ba83b8f
Show file tree
Hide file tree
Showing 20 changed files with 285 additions and 122 deletions.
14 changes: 7 additions & 7 deletions applications/tari_app_grpc/proto/wallet.proto
Expand Up @@ -72,7 +72,7 @@ service Wallet {
rpc CreateInitialAssetCheckpoint(CreateInitialAssetCheckpointRequest) returns (CreateInitialAssetCheckpointResponse);
// TODO: Needs a better name pls
rpc CreateFollowOnAssetCheckpoint(CreateFollowOnAssetCheckpointRequest) returns (CreateFollowOnAssetCheckpointResponse);
rpc CreateCommitteeDefinition(CreateCommitteeDefinitionRequest) returns (CreateCommitteeDefinitionResponse);
rpc CreateConstitutionDefinition(CreateConstitutionDefinitionRequest) returns (CreateConstitutionDefinitionResponse);

rpc GetOwnedAssets(Empty) returns (GetOwnedAssetsResponse);

Expand Down Expand Up @@ -288,14 +288,14 @@ message CreateFollowOnAssetCheckpointResponse {

}

message CreateCommitteeDefinitionRequest {
bytes asset_public_key = 1;
repeated bytes committee = 2;
uint64 effective_sidechain_height = 3;
bool is_initial = 4;
message CreateConstitutionDefinitionRequest {
bytes contract_id = 1;
CommitteeMembers validator_committee = 2;
uint64 acceptance_period_expiry = 3;
uint64 minimum_quorum_required = 4;
}

message CreateCommitteeDefinitionResponse {
message CreateConstitutionDefinitionResponse {

}

Expand Down
40 changes: 40 additions & 0 deletions applications/tari_app_grpc/src/conversions/sidechain_features.rs
Expand Up @@ -72,6 +72,46 @@ impl TryFrom<grpc::SideChainFeatures> for SideChainFeatures {
}
}

impl TryFrom<grpc::CreateConstitutionDefinitionRequest> for SideChainFeatures {
type Error = String;

fn try_from(request: grpc::CreateConstitutionDefinitionRequest) -> Result<Self, Self::Error> {
let acceptance_period_expiry = request.acceptance_period_expiry;
let minimum_quorum_required = request.minimum_quorum_required;
let validator_committee = request
.validator_committee
.map(CommitteeMembers::try_from)
.transpose()?
.unwrap();

Ok(Self {
contract_id: request.contract_id.try_into().map_err(|_| "Invalid contract_id")?,
definition: None,
constitution: Some(ContractConstitution {
validator_committee: validator_committee.clone(),
acceptance_requirements: ContractAcceptanceRequirements {
minimum_quorum_required: minimum_quorum_required as u32,
acceptance_period_expiry,
},
consensus: SideChainConsensus::MerkleRoot,
checkpoint_params: CheckpointParameters {
minimum_quorum_required: 5,
abandoned_interval: 100,
},
constitution_change_rules: ConstitutionChangeRules {
change_flags: ConstitutionChangeFlags::all(),
requirements_for_constitution_change: Some(RequirementsForConstitutionChange {
minimum_constitution_committee_signatures: 5,
constitution_committee: Some(validator_committee),
}),
},
initial_reward: 100.into(),
}),
acceptance: None,
})
}
}

//---------------------------------- ContractDefinition --------------------------------------------//

impl TryFrom<grpc::ContractDefinition> for ContractDefinition {
Expand Down
Expand Up @@ -134,30 +134,31 @@ impl WalletClient {
Ok(result.into_inner())
}

pub async fn create_committee_definition(
pub async fn create_constitution_definition(
&mut self,
asset_public_key: &str,
committee: &[String],
effective_sidechain_height: u64,
is_initial: bool,
) -> Result<grpc::CreateCommitteeDefinitionResponse, CollectiblesError> {
committee: Vec<String>,
acceptance_period_expiry: u64,
minimum_quorum_required: u64,
) -> Result<grpc::CreateConstitutionDefinitionResponse, CollectiblesError> {
let inner = self.get_inner_mut()?;
let committee = committee
.iter()
.map(|s| Vec::from_hex(s))
.collect::<Result<Vec<_>, _>>()?;

let request = grpc::CreateCommitteeDefinitionRequest {
asset_public_key: Vec::from_hex(asset_public_key)?,
committee,
effective_sidechain_height,
is_initial,
let committee = tari_app_grpc::tari_rpc::CommitteeMembers {
members: committee.into_iter().map(|s| s.into_bytes()).collect(),
};

let request = grpc::CreateConstitutionDefinitionRequest {
contract_id: Vec::from_hex(asset_public_key)?,
validator_committee: Some(committee),
acceptance_period_expiry,
minimum_quorum_required,
};

let result = inner
.create_committee_definition(request)
.create_constitution_definition(request)
.await
.map_err(|source| CollectiblesError::ClientRequest {
request: "create_committee_definition".to_string(),
request: "create_constitution_definition".to_string(),
source,
})?;
debug!(target: LOG_TARGET, "result {:?}", result);
Expand Down
Expand Up @@ -307,18 +307,24 @@ pub(crate) async fn inner_assets_create_initial_checkpoint(
}

#[tauri::command]
pub(crate) async fn assets_create_committee_definition(
asset_public_key: String,
pub(crate) async fn assets_create_constitution_definition(
contract_id: String,
committee: Vec<String>,
is_initial: bool,
acceptance_period_expiry: u64,
minimum_quorum_required: u64,
state: tauri::State<'_, ConcurrentAppState>,
) -> Result<Vec<String>, Status> {
let mut client = state.create_wallet_client().await;
client.connect().await?;

// TODO: effective sidechain height...
client
.create_committee_definition(&asset_public_key, &committee, 0, is_initial)
.create_constitution_definition(
&contract_id,
committee.clone(),
acceptance_period_expiry,
minimum_quorum_required,
)
.await?;

Ok(committee)
Expand Down
2 changes: 1 addition & 1 deletion applications/tari_collectibles/src-tauri/src/main.rs
Expand Up @@ -84,7 +84,7 @@ fn main() -> Result<(), Box<dyn Error>> {
commands::assets::assets_list_owned,
commands::assets::assets_list_registered_assets,
commands::assets::assets_create_initial_checkpoint,
commands::assets::assets_create_committee_definition,
commands::assets::assets_create_constitution_definition,
commands::assets::assets_get_committee_definition,
commands::assets::assets_get_registration,
commands::asset_wallets::asset_wallets_create,
Expand Down
Expand Up @@ -90,7 +90,7 @@ const AssetCommitteeManager = () => {

const submit = (committee) => {
binding
.command_asset_create_committee_definition(
.command_asset_create_constitution_definition(
assetPublicKey,
committee,
false
Expand Down
2 changes: 1 addition & 1 deletion applications/tari_collectibles/web-app/src/Create.js
Expand Up @@ -175,7 +175,7 @@ class Create extends React.Component {
console.log("register asset...");
await binding.command_asset_create_initial_checkpoint(assetPublicKey);
console.log("define committee...");
await binding.command_asset_create_committee_definition(
await binding.command_asset_create_constitution_definition(
assetPublicKey,
this.state.tip003Data.committee,
true
Expand Down
6 changes: 3 additions & 3 deletions applications/tari_collectibles/web-app/src/binding.js
Expand Up @@ -57,12 +57,12 @@ async function command_asset_create_initial_checkpoint(assetPublicKey) {
});
}

async function command_asset_create_committee_definition(
async function command_asset_create_constitution_definition(
assetPublicKey,
committee,
isInitial
) {
return await invoke("assets_create_committee_definition", {
return await invoke("assets_create_constitution_definition", {
assetPublicKey,
committee,
isInitial,
Expand Down Expand Up @@ -165,7 +165,7 @@ const commands = {
command_assets_list_owned,
command_assets_list_registered_assets,
command_asset_create_initial_checkpoint,
command_asset_create_committee_definition,
command_asset_create_constitution_definition,
command_asset_get_committee_definition,
command_next_asset_public_key,
command_asset_wallets_create,
Expand Down
37 changes: 29 additions & 8 deletions applications/tari_console_wallet/src/automation/commands.rs
Expand Up @@ -21,6 +21,7 @@
// USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

use std::{
convert::TryFrom,
fs::File,
io::{BufReader, BufWriter, LineWriter, Write},
path::PathBuf,
Expand All @@ -42,12 +43,12 @@ use tari_comms::{
use tari_comms_dht::{envelope::NodeDestination, DhtDiscoveryRequester};
use tari_core::transactions::{
tari_amount::{uT, MicroTari, Tari},
transaction_components::{ContractDefinition, TransactionOutput, UnblindedOutput},
transaction_components::{ContractDefinition, SideChainFeatures, TransactionOutput, UnblindedOutput},
};
use tari_crypto::ristretto::pedersen::PedersenCommitmentFactory;
use tari_utilities::{hex::Hex, ByteArray, Hashable};
use tari_wallet::{
assets::{ContractDefinitionFileFormat, ContractSpecificationFileFormat},
assets::{ConstitutionDefinitionFileFormat, ContractDefinitionFileFormat, ContractSpecificationFileFormat},
error::WalletError,
output_manager_service::handle::OutputManagerHandle,
transaction_service::handle::{TransactionEvent, TransactionServiceHandle},
Expand All @@ -68,7 +69,7 @@ use crate::{
ContractDefinitionCommand,
ContractDefinitionSubcommand,
InitContractDefinitionArgs,
PublishContractDefinitionArgs,
PublishDefinitionArgs,
},
utils::db::{CUSTOM_BASE_NODE_ADDRESS_KEY, CUSTOM_BASE_NODE_PUBLIC_KEY_KEY},
};
Expand Down Expand Up @@ -98,7 +99,7 @@ pub enum WalletCommand {
RegisterAsset,
MintTokens,
CreateInitialCheckpoint,
CreateCommitteeDefinition,
PublishConstitutionDefinition,
RevalidateWalletDb,
PublishContractDefinition,
}
Expand Down Expand Up @@ -715,7 +716,30 @@ pub async fn command_runner(
debug!(target: LOG_TARGET, "claiming tari HTLC tx_id {}", tx_id);
tx_ids.push(tx_id);
},
PublishConstitutionDefinition(args) => {
let file = File::open(&args.file_path).map_err(|e| CommandError::JsonFile(e.to_string()))?;
let file_reader = BufReader::new(file);

// parse the JSON file
let constitution_definition: ConstitutionDefinitionFileFormat =
serde_json::from_reader(file_reader).map_err(|e| CommandError::JsonFile(e.to_string()))?;
let side_chain_features = SideChainFeatures::try_from(constitution_definition.clone()).unwrap();

let mut asset_manager = wallet.asset_manager.clone();
let (tx_id, transaction) = asset_manager
.create_constitution_definition(&side_chain_features)
.await?;

let message = format!(
"Committee definition with {} members for {:?}",
constitution_definition.validator_committee.len(),
constitution_definition.contract_id
);

transaction_service
.submit_transaction(tx_id, transaction, 0.into(), message)
.await?;
},
RevalidateWalletDb => {
output_service
.revalidate_all_outputs()
Expand Down Expand Up @@ -821,10 +845,7 @@ fn init_contract_definition_spec(args: InitContractDefinitionArgs) -> Result<(),
Ok(())
}

async fn publish_contract_definition(
wallet: &WalletSqlite,
args: PublishContractDefinitionArgs,
) -> Result<(), CommandError> {
async fn publish_contract_definition(wallet: &WalletSqlite, args: PublishDefinitionArgs) -> Result<(), CommandError> {
// open the JSON file with the contract definition values
let file = File::open(&args.file_path).map_err(|e| CommandError::JsonFile(e.to_string()))?;
let file_reader = BufReader::new(file);
Expand Down
5 changes: 3 additions & 2 deletions applications/tari_console_wallet/src/cli.rs
Expand Up @@ -108,6 +108,7 @@ pub enum CliCommands {
InitShaAtomicSwap(SendTariArgs),
FinaliseShaAtomicSwap(FinaliseShaAtomicSwapArgs),
ClaimShaAtomicSwapRefund(ClaimShaAtomicSwapRefundArgs),
PublishConstitutionDefinition(PublishDefinitionArgs),
RevalidateWalletDb,
ContractDefinition(ContractDefinitionCommand),
}
Expand Down Expand Up @@ -210,7 +211,7 @@ pub enum ContractDefinitionSubcommand {
/// commands.
Init(InitContractDefinitionArgs),
/// Creates and publishes a contract definition UTXO from the JSON spec file.
Publish(PublishContractDefinitionArgs),
Publish(PublishDefinitionArgs),
}

#[derive(Debug, Args, Clone)]
Expand All @@ -229,6 +230,6 @@ pub struct InitContractDefinitionArgs {
}

#[derive(Debug, Args, Clone)]
pub struct PublishContractDefinitionArgs {
pub struct PublishDefinitionArgs {
pub file_path: PathBuf,
}

0 comments on commit ba83b8f

Please sign in to comment.