Skip to content

Commit

Permalink
Add TxParameters to transfer functionality (#271)
Browse files Browse the repository at this point in the history
  • Loading branch information
digorithm authored May 10, 2022
1 parent f538ef3 commit b855779
Show file tree
Hide file tree
Showing 9 changed files with 87 additions and 30 deletions.
6 changes: 4 additions & 2 deletions packages/fuels-contract/src/contract.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
use crate::abi_decoder::ABIDecoder;
use crate::abi_encoder::ABIEncoder;
use crate::parameters::{CallParameters, TxParameters};
use crate::script::Script;
use anyhow::Result;
use fuel_asm::Opcode;
Expand All @@ -15,7 +14,10 @@ use fuel_vm::script_with_data_offset;
use fuels_core::errors::Error;
use fuels_core::ReturnLocation;
use fuels_core::{
constants::DEFAULT_COIN_AMOUNT, constants::WORD_SIZE, Detokenize, Selector, Token,
constants::DEFAULT_COIN_AMOUNT,
constants::WORD_SIZE,
parameters::{CallParameters, TxParameters},
Detokenize, Selector, Token,
};
use fuels_core::{constants::NATIVE_ASSET_ID, ParamType};
use fuels_signers::provider::Provider;
Expand Down
1 change: 0 additions & 1 deletion packages/fuels-contract/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
pub mod contract;
pub mod errors;
pub mod parameters;
pub mod script;

pub mod abi_encoder {
Expand Down
2 changes: 1 addition & 1 deletion packages/fuels-core/src/constants.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use fuel_types::AssetId;
pub const DEFAULT_GAS_LIMIT: u64 = 1_000_000;
pub const DEFAULT_GAS_PRICE: u64 = 0;
pub const DEFAULT_BYTE_PRICE: u64 = 0;
pub const DEFAULT_MATURITY: u32 = 0;
pub const DEFAULT_MATURITY: u64 = 0;

pub const WORD_SIZE: usize = core::mem::size_of::<Word>();

Expand Down
1 change: 1 addition & 0 deletions packages/fuels-core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ pub mod code_gen;
pub mod constants;
pub mod errors;
pub mod json_abi;
pub mod parameters;
pub mod rustfmt;
pub mod source;
pub mod types;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
use fuel_tx::AssetId;
use fuels_core::constants::{
use crate::constants::{
DEFAULT_BYTE_PRICE, DEFAULT_GAS_LIMIT, DEFAULT_GAS_PRICE, DEFAULT_MATURITY, NATIVE_ASSET_ID,
};
use fuel_tx::AssetId;

#[derive(Debug)]
pub struct TxParameters {
pub gas_price: u64,
pub gas_limit: u64,
pub byte_price: u64,
pub maturity: u32,
pub maturity: u64,
}

#[derive(Debug)]
Expand Down Expand Up @@ -52,7 +52,7 @@ impl TxParameters {
gas_price: Option<u64>,
gas_limit: Option<u64>,
byte_price: Option<u64>,
maturity: Option<u32>,
maturity: Option<u64>,
) -> Self {
Self {
gas_price: gas_price.unwrap_or(DEFAULT_GAS_PRICE),
Expand Down
60 changes: 48 additions & 12 deletions packages/fuels-signers/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ pub trait Signer: std::fmt::Debug + Send + Sync {
mod tests {
use fuel_crypto::{Message, SecretKey};
use fuel_tx::{AssetId, Bytes32, Input, Output, UtxoId};
use fuels_core::parameters::TxParameters;
use fuels_test_helpers::{setup_address_and_coins, setup_test_client};
use rand::{rngs::StdRng, RngCore, SeedableRng};
use std::str::FromStr;
Expand Down Expand Up @@ -130,12 +131,12 @@ mod tests {
#[tokio::test]
async fn send_transaction() {
// Setup two sets of coins, one for each wallet, each containing 1 coin with 1 amount.
let (pk_1, mut coins_1) = setup_address_and_coins(1, 1);
let (pk_2, coins_2) = setup_address_and_coins(1, 1);
let (pk_1, mut coins_1) = setup_address_and_coins(1, 1000000);
let (pk_2, coins_2) = setup_address_and_coins(1, 1000000);

coins_1.extend(coins_2);

// Setup a provider and node with both set of coins
// Setup a provider and node with both set of coins.
let (client, _) = setup_test_client(coins_1).await;
let provider = Provider::new(client);

Expand All @@ -145,26 +146,56 @@ mod tests {
let wallet_1_initial_coins = wallet_1.get_coins().await.unwrap();
let wallet_2_initial_coins = wallet_2.get_coins().await.unwrap();

// Check initial wallet state
// Check initial wallet state.
assert_eq!(wallet_1_initial_coins.len(), 1);
assert_eq!(wallet_2_initial_coins.len(), 1);

// Transfer 1 from wallet 1 to wallet 2
let _receipts = wallet_1
.transfer(&wallet_2.address(), 1, Default::default())
// Configure transaction parameters.
let gas_price = 1;
let gas_limit = 500_000;
let byte_price = 1;
let maturity = 0;

let tx_params = TxParameters {
gas_price,
gas_limit,
byte_price,
maturity,
};

// Transfer 1 from wallet 1 to wallet 2.
let (tx_id, _receipts) = wallet_1
.transfer(&wallet_2.address(), 1, Default::default(), tx_params)
.await
.unwrap();

// Currently ignoring the effect on wallet 1, as coins aren't being marked as spent for now
// Assert that the transaction was properly configured.
let res = wallet_1
.provider
.get_transaction_by_id(&tx_id)
.await
.unwrap();

assert_eq!(res.transaction.byte_price(), byte_price);
assert_eq!(res.transaction.gas_limit(), gas_limit);
assert_eq!(res.transaction.gas_price(), gas_price);
assert_eq!(res.transaction.maturity(), maturity);

// Currently ignoring the effect on wallet 1, as coins aren't being marked as spent for now.
let _wallet_1_final_coins = wallet_1.get_coins().await.unwrap();
let wallet_2_final_coins = wallet_2.get_coins().await.unwrap();

// Check that wallet two now has two coins
// Check that wallet two now has two coins.
assert_eq!(wallet_2_final_coins.len(), 2);

// Transferring more than balance should fail
// Transferring more than balance should fail.
let result = wallet_1
.transfer(&wallet_2.address(), 2, Default::default())
.transfer(
&wallet_2.address(),
2000000,
Default::default(),
TxParameters::default(),
)
.await;

assert!(result.is_err());
Expand Down Expand Up @@ -194,7 +225,12 @@ mod tests {

// Transfer 2 from wallet 1 to wallet 2.
let _receipts = wallet_1
.transfer(&wallet_2.address(), 2, Default::default())
.transfer(
&wallet_2.address(),
2,
Default::default(),
TxParameters::default(),
)
.await
.unwrap();

Expand Down
22 changes: 17 additions & 5 deletions packages/fuels-signers/src/provider.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#[cfg(feature = "fuel-core")]
use fuel_core::service::{Config, FuelService};
use fuel_gql_client::client::schema::coin::Coin;
use fuel_gql_client::client::types::TransactionResponse;
use fuel_gql_client::client::{FuelClient, PageDirection, PaginationRequest};
use fuel_tx::Receipt;
use fuel_tx::{Address, AssetId, Input, Output, Transaction};
Expand All @@ -10,6 +11,7 @@ use std::net::SocketAddr;

use fuel_vm::prelude::Opcode;
use fuels_core::errors::Error;
use fuels_core::parameters::TxParameters;
use thiserror::Error;

/// An error involving a signature.
Expand Down Expand Up @@ -105,15 +107,20 @@ impl Provider {
}

/// Craft a transaction used to transfer funds between two addresses.
pub fn build_transfer_tx(&self, inputs: &[Input], outputs: &[Output]) -> Transaction {
pub fn build_transfer_tx(
&self,
inputs: &[Input],
outputs: &[Output],
params: TxParameters,
) -> Transaction {
// This script contains a single Opcode that returns immediately (RET)
// since all this transaction does is move Inputs and Outputs around.
let script = Opcode::RET(REG_ONE).to_bytes().to_vec();
Transaction::Script {
gas_price: 0,
gas_limit: 1_000_000,
byte_price: 0,
maturity: 0,
gas_price: params.gas_price,
gas_limit: params.gas_limit,
byte_price: params.byte_price,
maturity: params.maturity,
receipts_root: Default::default(),
script,
script_data: vec![],
Expand All @@ -124,6 +131,11 @@ impl Provider {
}
}

/// Get transaction by id.
pub async fn get_transaction_by_id(&self, tx_id: &str) -> io::Result<TransactionResponse> {
Ok(self.client.transaction(tx_id).await.unwrap().unwrap())
}

// @todo
// - Get transaction(s)
// - Get block(s)
Expand Down
15 changes: 11 additions & 4 deletions packages/fuels-signers/src/wallet.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ use fuel_crypto::{Message, PublicKey, SecretKey, Signature};
use fuel_gql_client::client::schema::coin::Coin;
use fuel_tx::{Address, AssetId, Input, Output, Receipt, Transaction, UtxoId, Witness};
use fuels_core::errors::Error;
use fuels_core::parameters::TxParameters;
use std::{fmt, io};
use thiserror::Error;

Expand Down Expand Up @@ -106,6 +107,7 @@ impl Wallet {

/// Transfer funds from this wallet to another `Address`.
/// Fails if amount for asset ID is larger than address's spendable coins.
/// Returns the transaction ID that was sent and the list of receipts.
///
/// # Examples
/// ```
Expand All @@ -129,7 +131,7 @@ impl Wallet {
///
/// // Transfer 1 from wallet 1 to wallet 2
/// let _receipts = wallet_1
/// .transfer(&wallet_2.address(), 1, Default::default())
/// .transfer(&wallet_2.address(), 1, Default::default(), TxParameters::default())
/// .await
/// .unwrap();
///
Expand All @@ -145,7 +147,8 @@ impl Wallet {
to: &Address,
amount: u64,
asset_id: AssetId,
) -> Result<Vec<Receipt>, WalletError> {
tx_parameters: TxParameters,
) -> Result<(String, Vec<Receipt>), WalletError> {
let inputs = self
.get_asset_inputs_for_amount(asset_id, amount, 0)
.await?;
Expand All @@ -157,10 +160,14 @@ impl Wallet {
];

// Build transaction and sign it
let mut tx = self.provider.build_transfer_tx(&inputs, &outputs);
let mut tx = self
.provider
.build_transfer_tx(&inputs, &outputs, tx_parameters);
let _sig = self.sign_transaction(&mut tx).await.unwrap();

Ok(self.provider.send_transaction(&tx).await?)
let receipts = self.provider.send_transaction(&tx).await?;

Ok((tx.id().to_string(), receipts))
}

/// Returns a proper vector of `Input::Coin`s for the given asset ID, amount, and witness index.
Expand Down
2 changes: 1 addition & 1 deletion packages/fuels/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,9 +45,9 @@ pub mod prelude {
//! ```
pub use super::contract::contract::Contract;
pub use super::contract::parameters::*;
pub use super::core::constants::*;
pub use super::core::errors::Error;
pub use super::core::parameters::*;
pub use super::core::{Token, Tokenizable};
pub use super::signers::provider::*;
pub use super::signers::{LocalWallet, Signer};
Expand Down

0 comments on commit b855779

Please sign in to comment.