fuel-core 0.15.3

Fuel client.
Documentation
use std::collections::HashMap;

use fuel_core_interfaces::{
    common::{
        fuel_tx::Script,
        tai64::Tai64,
    },
    model::{
        FuelApplicationHeader,
        FuelConsensusHeader,
        PartialFuelBlockHeader,
    },
};

use super::*;

const fn txn_id(i: u8) -> Bytes32 {
    Bytes32::new([i; 32])
}

fn receipt(i: Option<u8>) -> Receipt {
    match i {
        Some(i) => {
            let sender = Address::new([i; 32]);
            let recipient = Address::new([i; 32]);
            let amount = 0;
            let nonce = Bytes32::new([i; 32]);
            let data = Vec::new();
            let message_id =
                Output::message_id(&sender, &recipient, &nonce, amount, &data);
            Receipt::MessageOut {
                message_id,
                len: 0,
                digest: Bytes32::new([0; 32]),
                sender,
                recipient,
                amount,
                nonce,
                data,
            }
        }
        None => Receipt::Call {
            id: ContractId::new([0; 32]),
            to: ContractId::new([0; 32]),
            amount: 0,
            asset_id: AssetId::new([0; 32]),
            gas: 0,
            param1: 0,
            param2: 0,
            pc: 0,
            is: 0,
        },
    }
}

fn message_out() -> Output {
    Output::Message {
        recipient: Default::default(),
        amount: Default::default(),
    }
}

fn other_out() -> Output {
    Output::Coin {
        to: Default::default(),
        amount: Default::default(),
        asset_id: Default::default(),
    }
}

#[tokio::test]
async fn can_build_message_proof() {
    use mockall::predicate::*;
    let expected_receipt = receipt(Some(11));
    let message_id = *expected_receipt.message_id().unwrap();
    let receipts: [Receipt; 4] = [
        receipt(Some(10)),
        receipt(None),
        receipt(Some(3)),
        expected_receipt,
    ];
    static TXNS: [Bytes32; 4] = [txn_id(20), txn_id(24), txn_id(1), txn_id(33)];
    let transaction_id = TXNS[3];
    let other_receipts: [Receipt; 3] =
        [receipt(Some(4)), receipt(Some(5)), receipt(Some(6))];

    let message_ids: Vec<MessageId> = other_receipts
        .iter()
        .chain(receipts.iter())
        .filter_map(|r| Some(*r.message_id()?))
        .collect();

    let mut out = HashMap::new();
    out.insert(
        transaction_id,
        vec![message_out(), other_out(), message_out(), message_out()],
    );
    out.insert(TXNS[0], vec![message_out(), other_out()]);
    out.insert(TXNS[1], vec![message_out(), other_out()]);
    out.insert(TXNS[2], vec![message_out(), other_out()]);

    let mut data = MockMessageProofData::new();
    let mut count = 0;

    data.expect_receipts().returning(move |txn_id| {
        if *txn_id == transaction_id {
            Ok(receipts.to_vec())
        } else {
            let r = other_receipts[count..=count].to_vec();
            count += 1;
            Ok(r)
        }
    });
    data.expect_transaction_status()
        .with(eq(transaction_id))
        .returning(|_| {
            Ok(Some(TransactionStatus::Success {
                block_id: Default::default(),
                time: Tai64::UNIX_EPOCH,
                result: None,
            }))
        });
    data.expect_transactions_on_block()
        .once()
        .with(eq(Bytes32::default()))
        .returning(|_| Ok(TXNS.to_vec()));

    data.expect_transaction().returning(move |txn_id| {
        Ok(TXNS.iter().find(|t| *t == txn_id).map(|_| {
            let mut txn = Script::default();
            txn.outputs_mut().extend(out.get(txn_id).unwrap());
            txn.into()
        }))
    });

    data.expect_signature()
        .once()
        .with(eq(Bytes32::default()))
        .returning(|_| Ok(Some(fuel_crypto::Signature::default())));

    let header = PartialFuelBlockHeader {
        application: FuelApplicationHeader {
            da_height: 0u64.into(),
            generated: Default::default(),
        },
        consensus: FuelConsensusHeader {
            prev_root: Bytes32::zeroed(),
            height: 1u64.into(),
            time: Tai64::UNIX_EPOCH,
            generated: Default::default(),
        },
        metadata: None,
    };
    data.expect_block()
        .once()
        .with(eq(Bytes32::default()))
        .returning({
            let header = header.clone();
            let message_ids = message_ids.clone();
            move |_| {
                let header = header.clone().generate(&[vec![]], &message_ids);
                let transactions = TXNS.to_vec();
                Ok(Some(FuelBlockDb {
                    header,
                    transactions,
                }))
            }
        });

    let p = message_proof(&data, transaction_id, message_id)
        .await
        .unwrap()
        .unwrap();
    assert_eq!(p.message_id(), message_id);
    assert_eq!(p.signature, fuel_crypto::Signature::default());
    let header = header.generate(&[vec![]], &message_ids);
    assert_eq!(p.header.output_messages_root, header.output_messages_root);
}