From ef0f9dcb18a66db25c815ab69cfeb1366fbf2a25 Mon Sep 17 00:00:00 2001 From: hopeyen Date: Mon, 8 Jan 2024 14:28:04 -0600 Subject: [PATCH] feat: transaction unallocate subcommand + docs --- docs/onchain_guide.md | 42 +++++++++++--- subfile-exchange/src/config.rs | 10 +--- subfile-exchange/src/main.rs | 26 +++++---- .../src/transaction_manager/staking.rs | 56 +++++++++++++++++++ 4 files changed, 107 insertions(+), 27 deletions(-) diff --git a/docs/onchain_guide.md b/docs/onchain_guide.md index 086b610..0cf2d91 100644 --- a/docs/onchain_guide.md +++ b/docs/onchain_guide.md @@ -39,11 +39,16 @@ To open allocation towards a deployment, provide the deployment IPFS hash, the t #### Unallocate ->To be implemented + ### Examples -**Allocating Funds:** +- Replace placeholders like `"your mnemonic"`, `"http://localhost:8545"`, `"0x123..."`, `"QmHash"`, etc., with actual values. +- Ensure that the mnemonic and provider URL are kept secure and private. + +**Allocating** + +Grab the IPFS hash of the deployment you want to allocate to and decide the allocation amount. Note that you can only open 1 allocation per deployment per epoch. ```shell ✗ cargo run -p subfile-exchange wallet \ @@ -55,15 +60,13 @@ To open allocation towards a deployment, provide the deployment IPFS hash, the t --epoch 100 ``` -- Replace placeholders like `"your mnemonic"`, `"http://localhost:8545"`, `"0x123..."`, `"QmHash"`, etc., with actual values. -- Ensure that the mnemonic and provider URL are kept secure and private. - With RUST_LOG turned on, you can expect the following logs upon success ``` 2024-01-08T18:17:34.123941Z INFO subfile_exchange::transaction_manager: Initialize transaction manager at subfile-exchange/src/transaction_manager/mod.rs:32 - 2024-01-08T18:17:34.650044Z INFO subfile_exchange::transaction_manager::staking: allocate params, dep_bytes: [241, 64, 71, 78, 218, 63, 159, 91, 130, 173, 178, 168, 30, 254, 183, 20, 225, 131, 35, 230, 52, 85, 74, 196, 40, 255, 173, 61, 144, 126, 223, 33], tokens: Some(Allocate(AllocateArgs { tokens: 256, deployment_ipfs: "QmeaPp764FjQjPB66M9ijmQKmLhwBpHQhA7dEbH2FA1j3v", epoch: 101 })), allocation_id: 0x75e11e0f2319913c28d0b1916b4b1d9a1ac3977b, metadata: [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], proof: Bytes(0xac1b36d68ea95ebe9f9793850cf083a031d40806121dc2dac525423c50611d18053f195627f6bffe036b9325b4dfd273959457b5d3f1c1b53095c096182756bb1b) + 2024-01-08T18:17:34.650044Z INFO subfile_exchange::transaction_manager::staking: allocate params, dep_bytes: [241, 64, 71, 78, 218, 63, 159, 91, 130, 173, 178, 168, 30, 254, 183, 20, 225, 131, 35, 230, 52, 85, 74, 196, 40, 255, 173, 61, 144, 126, 223, 33], tokens: Some(Allocate(AllocateArgs { tokens: 256, deployment_ipfs: "QmeaPp764FjQjPB66M9ijmQKmLhwBpHQhA7dEbH2FA1j3v", + epoch: 101 })), allocation_id: 0x75e11e0f2319913c28d0b1916b4b1d9a1ac3977b, metadata: [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], proof: Bytes(0xac1b36d68ea95ebe9f9793850cf083a031d40806121dc2dac525423c50611d18053f195627f6bffe036b9325b4dfd273959457b5d3f1c1b53095c096182756bb1b) at subfile-exchange/src/transaction_manager/staking.rs:67 2024-01-08T18:17:34.765769Z DEBUG subfile_exchange::transaction_manager::staking: estimate gas, estimated_gas: 379109 @@ -71,4 +74,29 @@ With RUST_LOG turned on, you can expect the following logs upon success 2024-01-08T18:17:42.224872Z INFO subfile_exchange: Allocation transaction finished, allocation_id: 0x75e11e0f2319913c28d0b1916b4b1d9a1ac3977b, tx_receipt: Some(TransactionReceipt { transaction_hash: 0x835b790326abf1555545920265e54d5bfbaba150aef31820529736e6727c7a0a, ... }) at subfile-exchange/src/main.rs:75 -``` \ No newline at end of file +``` + +**Closing allocation** + +Grab the ID of allocation you want to close, and populate the unallocate subcommand +``` +✗ cargo run -p subfile-exchange wallet \ + --mnemonic "mnemonic" \ + --provider "provider_url" \ + unallocate --allocation-id 0xe37b9ee6d657ab5700e8a964a8fcc8b39cdefd73 +``` + +You can expect logs as follows +``` + 2024-01-08T20:17:58.886745Z INFO subfile_exchange::transaction_manager: Initialize transaction manager + at subfile-exchange/src/transaction_manager/mod.rs:32 + + 2024-01-08T20:17:59.355035Z INFO subfile_exchange::transaction_manager::staking: unallocate params, allocation_id: 0xe37b9ee6d657ab5700e8a964a8fcc8b39cdefd73 + at subfile-exchange/src/transaction_manager/staking.rs:142 + + 2024-01-08T20:17:59.436442Z DEBUG subfile_exchange::transaction_manager::staking: estimate gas, estimated_gas: 390965 + at subfile-exchange/src/transaction_manager/staking.rs:154 + + 2024-01-08T20:18:06.929268Z INFO subfile_exchange: Transaction result, result: Ok((0xe37b9ee6d657ab5700e8a964a8fcc8b39cdefd73, Some(TransactionReceipt { transaction_hash: 0xd5c7c4d3dbd4aa8f845f87f8225aef91e927fe7cd5a1cd02085b0d30a59f4743, transaction_index: 1, block_hash: Some(0xcb46a88b2a37648a38165ca3740248b9a2a41e01f3b56f65f59b33f5cbf00fd0), block_number: Some(5738566), from: 0xe9a1cabd57700b17945fd81feefba82340d9568f, to: Some(0x865365c425f3a593ffe698d9c4e6707d14d51e08), cumulative_gas_used: 345329, gas_used: Some(345329), contract_address: None, logs: [Log { address: 0x865365c425f3a593ffe698d9c4e6707d14d51e08, topics: [...], data: Bytes(...), block_hash: Some(0xcb46a88b2a37648a38165ca3740248b9a2a41e01f3b56f65f59b33f5cbf00fd0), block_number: Some(5738566), transaction_hash: Some(0xd5c7c4d3dbd4aa8f845f87f8225aef91e927fe7cd5a1cd02085b0d30a59f4743), transaction_index: Some(1), log_index: Some(0), transaction_log_index: None, log_type: None, removed: Some(false) }], status: Some(1), root: None, logs_bloom: ..., transaction_type: Some(2), effective_gas_price: Some(100000000), other: OtherFields { inner: {"gasUsedForL1": String("0x28a70"), "l1BlockNumber": String("0x4d09a3")} } }))) + at subfile-exchange/src/main.rs:88 +``` diff --git a/subfile-exchange/src/config.rs b/subfile-exchange/src/config.rs index de0d425..ef455c7 100644 --- a/subfile-exchange/src/config.rs +++ b/subfile-exchange/src/config.rs @@ -313,7 +313,8 @@ pub struct AllocateArgs { long, value_name = "tokens", env = "TOKENS", - help = "Token amount to allocate" + help = "Token amount to allocate (in units of GRT)", + value_parser = U256::from_dec_str, )] pub tokens: U256, #[clap( @@ -335,13 +336,6 @@ pub struct AllocateArgs { #[derive(Clone, Debug, Args, Serialize, Deserialize, Default)] #[group(required = false, multiple = true)] pub struct UnallocateArgs { - #[clap( - long, - value_name = "deployment_ipfs", - env = "DEPLOYMENT_IPFS", - help = "Deployment IPFS hash to unallocate" - )] - pub deployment_ipfs: String, #[clap( long, value_name = "allocation_id", diff --git a/subfile-exchange/src/main.rs b/subfile-exchange/src/main.rs index ef66f3b..06d4508 100644 --- a/subfile-exchange/src/main.rs +++ b/subfile-exchange/src/main.rs @@ -64,27 +64,29 @@ async fn main() { .await .expect("Cannot initate transaction manager"); - match transaction_manager.args.action.clone() { + let result = match transaction_manager.args.action.clone() { Some(OnchainAction::Allocate(allocate_args)) => { - let (allocation_id, tx_receipt) = transaction_manager + transaction_manager .allocate( &allocate_args.deployment_ipfs, allocate_args.tokens, allocate_args.epoch, ) .await - .unwrap(); - tracing::info!( - allocation_id = tracing::field::debug(&allocation_id), - tx_receipt = tracing::field::debug(&tx_receipt), - "Allocation transaction finished" - ); } - Some(OnchainAction::Unallocate(_unallocate_args)) => { - todo!() + Some(OnchainAction::Unallocate(unallocate_args)) => { + transaction_manager + .unallocate(&unallocate_args.allocation_id) + .await } - None => {} - } + None => { + panic!("No onchain command provided (later add general status return)") + } + }; + tracing::info!( + result = tracing::field::debug(&result), + "Transaction result" + ); } } } diff --git a/subfile-exchange/src/transaction_manager/staking.rs b/subfile-exchange/src/transaction_manager/staking.rs index 7dcb879..01cfab5 100644 --- a/subfile-exchange/src/transaction_manager/staking.rs +++ b/subfile-exchange/src/transaction_manager/staking.rs @@ -131,6 +131,62 @@ impl TransactionManager { Ok(value) } + + /// call staking contract unallocate function + pub async fn unallocate( + &self, + allocation_id: &str, + ) -> Result<(H160, Option), Error> { + let zero_poi: [u8; 32] = [0; 32]; + let allocation_id = + H160::from_str(allocation_id).map_err(|e| Error::InvalidConfig(e.to_string()))?; + tracing::info!( + allocation_id = tracing::field::debug(&allocation_id), + "unallocate params", + ); + + let populated_tx = self + .staking_contract + .close_allocation(allocation_id, zero_poi); + let estimated_gas = populated_tx + .estimate_gas() + .await + .map_err(|e| Error::ContractError(e.to_string()))?; + tracing::debug!( + estimated_gas = tracing::field::debug(&estimated_gas), + "estimate gas" + ); + + // Attempt to send the populated tx with estimated gas, can later add a slippage + let tx_result = populated_tx + .gas(estimated_gas) + .send() + .await + .map_err(|e| { + let encoded_error = &e.to_string()[2..]; + let error_message_hex = &encoded_error[8 + 64..]; + let bytes = hex::decode(error_message_hex).unwrap(); + let message = String::from_utf8(bytes).unwrap(); + tracing::error!(message); + + Error::ContractError(e.to_string()) + })? + .await + .map_err(|e| { + let encoded_error = &e.to_string()[2..]; + let error_message_hex = &encoded_error[8 + 64..]; + let bytes = hex::decode(error_message_hex).unwrap(); + let message = String::from_utf8(bytes).unwrap(); + tracing::error!(message); + + Error::ContractError(e.to_string()) + })?; + tracing::debug!( + value = tracing::field::debug(&tx_result), + "allocate call result" + ); + Ok((allocation_id, tx_result)) + } } /// create packed keccak hash for allocation id as proof