Skip to content

Commit b2676a0

Browse files
bug: cannot fetch mint transactions (#1203)
closes #1199 Mint transactions can now be fetched through the `Provider`. Implemented what made sense for `Mint`, left the rest as `unimplemented!`. Without some hefty redesign don't see what other option is there but to violate the LSP (L for Liskov). Decided to wrap `Mint`, so that users may extract the id, outputs, etc, without having to know about the various traits from fuel. ### Checklist - [x] I have linked to any relevant issues. - [ ] I have updated the documentation. - [x] I have added tests that prove my fix is effective or that my feature works. - [x] I have added necessary labels. - [x] I have done my best to ensure that my PR adheres to [the Fuel Labs Code Review Standards](https://github.com/FuelLabs/rfcs/blob/master/text/code-standards/external-contributors.md). - [x] I have requested a review from the relevant team or maintainers.
1 parent 5793398 commit b2676a0

File tree

7 files changed

+100
-156
lines changed

7 files changed

+100
-156
lines changed

packages/fuels-code-gen/src/program_bindings/utils.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,9 @@ use itertools::Itertools;
66
use proc_macro2::{Ident, TokenStream};
77
use quote::quote;
88

9-
use super::resolved_type::GenericType;
109
use crate::{
1110
error::Result,
12-
program_bindings::resolved_type::{ResolvedType, TypeResolver},
11+
program_bindings::resolved_type::{GenericType, ResolvedType, TypeResolver},
1312
utils::{self, safe_ident, TypePath},
1413
};
1514

packages/fuels-core/src/codec/logs.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,8 @@ use std::{
77

88
use fuel_tx::{ContractId, Receipt};
99

10-
use super::ABIDecoder;
1110
use crate::{
12-
codec::DecoderConfig,
11+
codec::{ABIDecoder, DecoderConfig},
1312
traits::{Parameterize, Tokenizable},
1413
types::{
1514
errors::{error, Error, Result},

packages/fuels-core/src/types/transaction_builders.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,19 +15,20 @@ use fuel_tx::{
1515
use fuel_types::{bytes::padded_len_usize, canonical::Serialize, Bytes32, ChainId, Salt};
1616
use zeroize::{Zeroize, ZeroizeOnDrop};
1717

18-
use super::{chain_info::ChainInfo, node_info::NodeInfo};
1918
use crate::{
2019
constants::{
2120
BASE_ASSET_ID, DEFAULT_CREATE_WITNESS_LIMIT, DEFAULT_SCRIPT_WITNESS_LIMIT, WORD_SIZE,
2221
},
2322
offsets,
2423
types::{
2524
bech32::Bech32Address,
25+
chain_info::ChainInfo,
2626
coin::Coin,
2727
coin_type::CoinType,
2828
errors::{error, Result},
2929
input::Input,
3030
message::Message,
31+
node_info::NodeInfo,
3132
transaction::{
3233
CreateTransaction, EstimablePredicates, ScriptTransaction, Transaction, TxPolicies,
3334
},

packages/fuels-core/src/types/wrappers/coin_type.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,9 @@
33
use fuel_core_client::client::types::CoinType as ClientCoinType;
44
use fuel_types::AssetId;
55

6-
use super::coin_type_id::CoinTypeId;
76
use crate::{
87
constants::BASE_ASSET_ID,
9-
types::{bech32::Bech32Address, coin::Coin, message::Message},
8+
types::{bech32::Bech32Address, coin::Coin, coin_type_id::CoinTypeId, message::Message},
109
};
1110

1211
#[derive(Debug, Clone, PartialEq, Eq, Hash)]

packages/fuels-core/src/types/wrappers/transaction.rs

Lines changed: 55 additions & 148 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@ use std::{collections::HashMap, fmt::Debug};
22

33
use fuel_tx::{
44
field::{
5-
GasPrice, Inputs, Maturity, Outputs, Script as ScriptField, ScriptData, ScriptGasLimit,
6-
Witnesses,
5+
GasPrice, Inputs, Maturity, MintAmount, MintAssetId, Outputs, Script as ScriptField,
6+
ScriptData, ScriptGasLimit, Witnesses,
77
},
88
input::{
99
coin::{CoinPredicate, CoinSigned},
@@ -12,7 +12,7 @@ use fuel_tx::{
1212
},
1313
},
1414
Buildable, Bytes32, Cacheable, Chargeable, ConsensusParameters, Create, FormatValidityChecks,
15-
Input, Output, Salt as FuelSalt, Script, StorageSlot, Transaction as FuelTransaction,
15+
Input, Mint, Output, Salt as FuelSalt, Script, StorageSlot, Transaction as FuelTransaction,
1616
TransactionFee, UniqueIdentifier, Witness,
1717
};
1818
use fuel_types::{AssetId, ChainId};
@@ -24,8 +24,56 @@ use crate::{
2424
types::{bech32::Bech32Address, errors::error, Result},
2525
};
2626

27-
#[derive(Default, Debug, Copy, Clone)]
27+
#[derive(Default, Debug, Clone, PartialEq, Eq)]
28+
pub struct MintTransaction {
29+
tx: Box<Mint>,
30+
}
31+
32+
impl From<MintTransaction> for FuelTransaction {
33+
fn from(mint: MintTransaction) -> Self {
34+
(*mint.tx).into()
35+
}
36+
}
37+
38+
impl From<MintTransaction> for Mint {
39+
fn from(tx: MintTransaction) -> Self {
40+
*tx.tx
41+
}
42+
}
43+
44+
impl From<Mint> for MintTransaction {
45+
fn from(tx: Mint) -> Self {
46+
Self { tx: Box::new(tx) }
47+
}
48+
}
49+
50+
impl MintTransaction {
51+
pub fn check_without_signatures(
52+
&self,
53+
block_height: u32,
54+
consensus_parameters: &ConsensusParameters,
55+
) -> Result<()> {
56+
Ok(self
57+
.tx
58+
.check_without_signatures(block_height.into(), consensus_parameters)?)
59+
}
60+
#[must_use]
61+
pub fn id(&self, chain_id: ChainId) -> Bytes32 {
62+
self.tx.id(&chain_id)
63+
}
2864

65+
#[must_use]
66+
pub fn mint_asset_id(&self) -> &AssetId {
67+
self.tx.mint_asset_id()
68+
}
69+
70+
#[must_use]
71+
pub fn mint_amount(&self) -> u64 {
72+
*self.tx.mint_amount()
73+
}
74+
}
75+
76+
#[derive(Default, Debug, Copy, Clone)]
2977
//ANCHOR: tx_policies_struct
3078
pub struct TxPolicies {
3179
gas_price: Option<u64>,
@@ -101,12 +149,13 @@ impl TxPolicies {
101149

102150
use fuel_tx::field::{BytecodeLength, BytecodeWitnessIndex, Salt, StorageSlots};
103151

104-
use super::coin_type_id::CoinTypeId;
152+
use crate::types::coin_type_id::CoinTypeId;
105153

106154
#[derive(Debug, Clone)]
107155
pub enum TransactionType {
108156
Script(ScriptTransaction),
109157
Create(CreateTransaction),
158+
Mint(MintTransaction),
110159
}
111160

112161
pub trait EstimablePredicates {
@@ -171,149 +220,7 @@ impl From<TransactionType> for FuelTransaction {
171220
match value {
172221
TransactionType::Script(tx) => tx.into(),
173222
TransactionType::Create(tx) => tx.into(),
174-
}
175-
}
176-
}
177-
178-
impl EstimablePredicates for TransactionType {
179-
fn estimate_predicates(&mut self, consensus_parameters: &ConsensusParameters) -> Result<()> {
180-
match self {
181-
TransactionType::Script(tx) => tx.estimate_predicates(consensus_parameters),
182-
TransactionType::Create(tx) => tx.estimate_predicates(consensus_parameters),
183-
}
184-
}
185-
}
186-
187-
impl GasValidation for TransactionType {
188-
fn validate_gas(&self, min_gas_price: u64, gas_used: u64) -> Result<()> {
189-
match self {
190-
TransactionType::Script(tx) => tx.validate_gas(min_gas_price, gas_used),
191-
TransactionType::Create(tx) => tx.validate_gas(min_gas_price, gas_used),
192-
}
193-
}
194-
}
195-
196-
impl Transaction for TransactionType {
197-
fn fee_checked_from_tx(
198-
&self,
199-
consensus_parameters: &ConsensusParameters,
200-
) -> Option<TransactionFee> {
201-
match self {
202-
TransactionType::Script(tx) => tx.fee_checked_from_tx(consensus_parameters),
203-
TransactionType::Create(tx) => tx.fee_checked_from_tx(consensus_parameters),
204-
}
205-
}
206-
207-
fn max_gas(&self, consensus_parameters: &ConsensusParameters) -> u64 {
208-
match self {
209-
TransactionType::Script(tx) => tx.max_gas(consensus_parameters),
210-
TransactionType::Create(tx) => tx.max_gas(consensus_parameters),
211-
}
212-
}
213-
214-
fn check_without_signatures(
215-
&self,
216-
block_height: u32,
217-
consensus_parameters: &ConsensusParameters,
218-
) -> Result<()> {
219-
match self {
220-
TransactionType::Script(tx) => {
221-
tx.check_without_signatures(block_height, consensus_parameters)
222-
}
223-
TransactionType::Create(tx) => {
224-
tx.check_without_signatures(block_height, consensus_parameters)
225-
}
226-
}
227-
}
228-
229-
fn id(&self, chain_id: ChainId) -> Bytes32 {
230-
match self {
231-
TransactionType::Script(tx) => tx.id(chain_id),
232-
TransactionType::Create(tx) => tx.id(chain_id),
233-
}
234-
}
235-
236-
fn maturity(&self) -> u32 {
237-
match self {
238-
TransactionType::Script(tx) => tx.maturity(),
239-
TransactionType::Create(tx) => tx.maturity(),
240-
}
241-
}
242-
243-
fn with_maturity(self, maturity: u32) -> Self {
244-
match self {
245-
TransactionType::Script(tx) => TransactionType::Script(tx.with_maturity(maturity)),
246-
TransactionType::Create(tx) => TransactionType::Create(tx.with_maturity(maturity)),
247-
}
248-
}
249-
250-
fn gas_price(&self) -> u64 {
251-
match self {
252-
TransactionType::Script(tx) => tx.gas_price(),
253-
TransactionType::Create(tx) => tx.gas_price(),
254-
}
255-
}
256-
257-
fn with_gas_price(self, gas_price: u64) -> Self {
258-
match self {
259-
TransactionType::Script(tx) => TransactionType::Script(tx.with_gas_price(gas_price)),
260-
TransactionType::Create(tx) => TransactionType::Create(tx.with_gas_price(gas_price)),
261-
}
262-
}
263-
264-
fn metered_bytes_size(&self) -> usize {
265-
match self {
266-
TransactionType::Script(tx) => tx.metered_bytes_size(),
267-
TransactionType::Create(tx) => tx.metered_bytes_size(),
268-
}
269-
}
270-
271-
fn inputs(&self) -> &Vec<Input> {
272-
match self {
273-
TransactionType::Script(tx) => tx.inputs(),
274-
TransactionType::Create(tx) => tx.inputs(),
275-
}
276-
}
277-
278-
fn outputs(&self) -> &Vec<Output> {
279-
match self {
280-
TransactionType::Script(tx) => tx.outputs(),
281-
TransactionType::Create(tx) => tx.outputs(),
282-
}
283-
}
284-
285-
fn witnesses(&self) -> &Vec<Witness> {
286-
match self {
287-
TransactionType::Script(tx) => tx.witnesses(),
288-
TransactionType::Create(tx) => tx.witnesses(),
289-
}
290-
}
291-
292-
fn is_using_predicates(&self) -> bool {
293-
match self {
294-
TransactionType::Script(tx) => tx.is_using_predicates(),
295-
TransactionType::Create(tx) => tx.is_using_predicates(),
296-
}
297-
}
298-
299-
fn precompute(&mut self, chain_id: &ChainId) -> Result<()> {
300-
match self {
301-
TransactionType::Script(tx) => tx.precompute(chain_id),
302-
TransactionType::Create(tx) => tx.precompute(chain_id),
303-
}
304-
}
305-
306-
fn append_witness(&mut self, witness: Witness) -> usize {
307-
match self {
308-
TransactionType::Script(tx) => tx.append_witness(witness),
309-
TransactionType::Create(tx) => tx.append_witness(witness),
310-
}
311-
}
312-
313-
fn used_coins(&self) -> HashMap<(Bech32Address, AssetId), Vec<CoinTypeId>> {
314-
match self {
315-
TransactionType::Script(tx) => tx.used_coins(),
316-
TransactionType::Create(tx) => tx.used_coins(),
223+
TransactionType::Mint(tx) => tx.into(),
317224
}
318225
}
319226
}

packages/fuels-core/src/types/wrappers/transaction_response.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ impl From<ClientTransactionResponse> for TransactionResponse {
4747
let transaction = match client_response.transaction {
4848
Transaction::Script(tx) => TransactionType::Script(ScriptTransaction::from(tx)),
4949
Transaction::Create(tx) => TransactionType::Create(CreateTransaction::from(tx)),
50-
Transaction::Mint(_) => unimplemented!(),
50+
Transaction::Mint(tx) => TransactionType::Mint(tx.into()),
5151
};
5252

5353
Self {

packages/fuels/tests/providers.rs

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -934,6 +934,45 @@ async fn test_cache_invalidation_on_await() -> Result<()> {
934934
Ok(())
935935
}
936936

937+
#[tokio::test]
938+
async fn can_fetch_mint_transactions() -> Result<()> {
939+
setup_program_test!(
940+
Wallets("wallet"),
941+
Abigen(Contract(
942+
name = "TestContract",
943+
project = "packages/fuels/tests/contracts/contract_test"
944+
)),
945+
Deploy(
946+
name = "contract_instance",
947+
contract = "TestContract",
948+
wallet = "wallet"
949+
),
950+
);
951+
952+
let provider = wallet.try_provider()?;
953+
954+
let transactions = provider
955+
.get_transactions(PaginationRequest {
956+
cursor: None,
957+
results: 100,
958+
direction: PageDirection::Forward,
959+
})
960+
.await?
961+
.results;
962+
963+
// TODO: remove once (fuels-rs#1093)[https://github.com/FuelLabs/fuels-rs/issues/1093] is in
964+
// until then the type is explicitly mentioned to check that we're reexporting it through fuels
965+
let _: ::fuels::types::transaction::MintTransaction = transactions
966+
.into_iter()
967+
.find_map(|tx| match tx.transaction {
968+
TransactionType::Mint(tx) => Some(tx),
969+
_ => None,
970+
})
971+
.expect("Should have had at least one mint transaction");
972+
973+
Ok(())
974+
}
975+
937976
#[tokio::test]
938977
async fn test_build_with_provider() -> Result<()> {
939978
let wallet = launch_provider_and_get_wallet().await?;

0 commit comments

Comments
 (0)