Skip to content

Commit

Permalink
Turn on UTXO validation in tests (#193)
Browse files Browse the repository at this point in the history
* Turn on UTXO validation in tests

* use genesis config instead of manual db setup

Co-authored-by: Brandon Kite <[email protected]>
  • Loading branch information
digorithm and Voxelot authored Mar 29, 2022
1 parent e835574 commit da97652
Show file tree
Hide file tree
Showing 3 changed files with 51 additions and 13 deletions.
12 changes: 11 additions & 1 deletion fuels-contract/src/contract.rs
Original file line number Diff line number Diff line change
Expand Up @@ -371,8 +371,18 @@ impl Contract {
// For now we use the NATIVE_ASSET_ID constant
Output::change(wallet.address(), 0, AssetId::from(NATIVE_ASSET_ID)),
];

// The first witness is the bytecode we're deploying.
// So, the signature will be appended at position 1 of
// the witness list.
let coin_witness_index = 1;

let inputs = wallet
.get_asset_inputs_for_amount(AssetId::default(), DEFAULT_COIN_AMOUNT)
.get_asset_inputs_for_amount(
AssetId::default(),
DEFAULT_COIN_AMOUNT,
coin_witness_index,
)
.await?;

let tx = Transaction::create(
Expand Down
39 changes: 29 additions & 10 deletions fuels-signers/src/util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,14 @@
pub mod test_helpers {
use crate::provider::Provider;
use crate::LocalWallet;
use fuel_core::service::{Config, FuelService};
use fuel_core::{
database::Database,
chain_config::{ChainConfig, CoinConfig, StateConfig},
model::coin::{Coin, CoinStatus},
service::{Config, DbType, FuelService},
};
use fuel_crypto::Hasher;
use fuel_gql_client::client::FuelClient;
use fuel_tx::{Address, Bytes32, Bytes64, UtxoId};
use fuel_vm::prelude::Storage;
use fuels_core::constants::DEFAULT_INITIAL_BALANCE;
use rand::{Fill, Rng};
use secp256k1::{PublicKey, Secp256k1, SecretKey};
Expand Down Expand Up @@ -70,14 +69,34 @@ pub mod test_helpers {
// Setup a test provider with the given coins. We return the SocketAddr so the launched node
// client can be connected to more easily (even though it is often ignored).
pub async fn setup_test_provider(coins: Vec<(UtxoId, Coin)>) -> (Provider, SocketAddr) {
let mut db = Database::default();
for (utxo_id, coin) in coins {
Storage::<UtxoId, Coin>::insert(&mut db, &utxo_id, &coin).unwrap();
}
let coin_configs = coins
.into_iter()
.map(|(utxo_id, coin)| CoinConfig {
tx_id: Some(*utxo_id.tx_id()),
output_index: Some(utxo_id.output_index() as u64),
block_created: Some(coin.block_created),
maturity: Some(coin.maturity),
owner: coin.owner,
amount: coin.amount,
asset_id: coin.asset_id,
})
.collect();

// Setup node config with genesis coins and utxo_validation enabled
let config = Config {
chain_conf: ChainConfig {
initial_state: Some(StateConfig {
coins: Some(coin_configs),
..StateConfig::default()
}),
..ChainConfig::local_testnet()
},
database_type: DbType::InMemory,
utxo_validation: true,
..Config::local_node()
};

let srv = FuelService::from_database(db, Config::local_node())
.await
.unwrap();
let srv = FuelService::new_node(config).await.unwrap();
let client = FuelClient::from(srv.bound_address);

(Provider::new(client), srv.bound_address)
Expand Down
13 changes: 11 additions & 2 deletions fuels-signers/src/wallet.rs
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,9 @@ impl Wallet {
amount: u64,
asset_id: AssetId,
) -> Result<Vec<Receipt>, WalletError> {
let inputs = self.get_asset_inputs_for_amount(asset_id, amount).await?;
let inputs = self
.get_asset_inputs_for_amount(asset_id, amount, 0)
.await?;
let outputs: Vec<Output> = vec![
Output::coin(*to, amount, asset_id),
// Note that the change will be computed by the node.
Expand All @@ -170,10 +172,17 @@ impl Wallet {
Ok(self.provider.send_transaction(&tx).await?)
}

/// Returns a proper vector of `Input::Coin`s for the given asset ID, amount, and witness index.
/// The `witness_index` is the position of the witness
/// (signature) in the transaction's list of witnesses.
/// Meaning that, in the validation process, the node will
/// use the witness at this index to validate the coins returned
/// by this method.
pub async fn get_asset_inputs_for_amount(
&self,
asset_id: AssetId,
amount: u64,
witness_index: u8,
) -> Result<Vec<Input>, WalletError> {
let spendable = self.get_spendable_coins(&asset_id, amount).await?;
let mut inputs = vec![];
Expand All @@ -183,7 +192,7 @@ impl Wallet {
coin.owner.into(),
coin.amount.0,
asset_id,
0,
witness_index,
0,
vec![],
vec![],
Expand Down

0 comments on commit da97652

Please sign in to comment.