#![cfg(feature = "alloc")]
use stellar_xdr::{
Asset, ContractId, Error, FeeBumpTransaction, FeeBumpTransactionEnvelope,
FeeBumpTransactionExt, FeeBumpTransactionInnerTx, Hash, HostFunction, InvokeContractArgs,
InvokeHostFunctionOp, Memo, MuxedAccount, Operation, OperationBody, PaymentOp, Preconditions,
ScAddress, ScSymbol, ScVal, SequenceNumber, SorobanAuthorizationEntry,
SorobanAuthorizedFunction, SorobanAuthorizedInvocation, SorobanCredentials, Transaction,
TransactionEnvelope, TransactionExt, TransactionV0, TransactionV0Envelope, TransactionV0Ext,
TransactionV1Envelope, Uint256,
};
#[test]
fn txv0() -> Result<(), Error> {
let auth1 = create_soroban_auth_entry(1);
let auth2 = create_soroban_auth_entry(2);
let auth3 = create_soroban_auth_entry(3);
let invoke_op_some = create_invoke_host_op(&[auth1.clone(), auth2.clone()]);
let invoke_op_more = create_invoke_host_op(std::slice::from_ref(&auth3));
let invoke_op_none = create_invoke_host_op(&[]);
let other_op = create_payment_op();
let mut tx = TransactionEnvelope::TxV0(TransactionV0Envelope {
tx: TransactionV0 {
source_account_ed25519: Uint256([0; 32]),
fee: 100,
seq_num: SequenceNumber(1),
time_bounds: None,
memo: Memo::None,
operations: [invoke_op_some, invoke_op_none, other_op, invoke_op_more]
.to_vec()
.try_into()?,
ext: TransactionV0Ext::V0,
},
signatures: [].to_vec().try_into()?,
});
let tx_auths: Vec<_> = tx.auths().collect();
assert_eq!(tx_auths, [&auth1, &auth2, &auth3]);
#[allow(unused_mut)]
let mut tx_auths: Vec<_> = tx.auths_mut().collect();
assert_eq!(tx_auths, [&auth1, &auth2, &auth3]);
Ok(())
}
#[test]
fn txv1() -> Result<(), Error> {
let auth1 = create_soroban_auth_entry(1);
let auth2 = create_soroban_auth_entry(2);
let auth3 = create_soroban_auth_entry(3);
let invoke_op_some = create_invoke_host_op(&[auth1.clone(), auth2.clone()]);
let invoke_op_more = create_invoke_host_op(std::slice::from_ref(&auth3));
let invoke_op_none = create_invoke_host_op(&[]);
let other_op = create_payment_op();
let mut tx = TransactionEnvelope::Tx(TransactionV1Envelope {
tx: Transaction {
source_account: MuxedAccount::Ed25519(Uint256([0; 32])),
fee: 100,
seq_num: SequenceNumber(1),
cond: Preconditions::None,
memo: Memo::None,
operations: [invoke_op_some, invoke_op_none, other_op, invoke_op_more]
.to_vec()
.try_into()?,
ext: TransactionExt::V0,
},
signatures: [].to_vec().try_into()?,
});
let tx_auths: Vec<_> = tx.auths().collect();
assert_eq!(tx_auths, [&auth1, &auth2, &auth3]);
#[allow(unused_mut)]
let mut tx_auths: Vec<_> = tx.auths_mut().collect();
assert_eq!(tx_auths, [&auth1, &auth2, &auth3]);
Ok(())
}
#[test]
fn txfeebump() -> Result<(), Error> {
let auth1 = create_soroban_auth_entry(1);
let auth2 = create_soroban_auth_entry(2);
let auth3 = create_soroban_auth_entry(3);
let invoke_op_some = create_invoke_host_op(&[auth1.clone(), auth2.clone()]);
let invoke_op_more = create_invoke_host_op(std::slice::from_ref(&auth3));
let invoke_op_none = create_invoke_host_op(&[]);
let other_op = create_payment_op();
let mut tx = TransactionEnvelope::TxFeeBump(FeeBumpTransactionEnvelope {
tx: FeeBumpTransaction {
fee_source: MuxedAccount::Ed25519(Uint256([0; 32])),
fee: 200,
inner_tx: FeeBumpTransactionInnerTx::Tx(TransactionV1Envelope {
tx: Transaction {
source_account: MuxedAccount::Ed25519(Uint256([0; 32])),
fee: 100,
seq_num: SequenceNumber(1),
cond: Preconditions::None,
memo: Memo::None,
operations: [invoke_op_some, invoke_op_none, other_op, invoke_op_more]
.to_vec()
.try_into()?,
ext: TransactionExt::V0,
},
signatures: [].to_vec().try_into()?,
}),
ext: FeeBumpTransactionExt::V0,
},
signatures: [].to_vec().try_into()?,
});
let tx_auths: Vec<_> = tx.auths().collect();
assert_eq!(tx_auths, [&auth1, &auth2, &auth3]);
#[allow(unused_mut)]
let mut tx_auths: Vec<_> = tx.auths_mut().collect();
assert_eq!(tx_auths, [&auth1, &auth2, &auth3]);
Ok(())
}
fn create_soroban_auth_entry(id: u64) -> SorobanAuthorizationEntry {
SorobanAuthorizationEntry {
credentials: SorobanCredentials::SourceAccount,
root_invocation: SorobanAuthorizedInvocation {
function: SorobanAuthorizedFunction::ContractFn(InvokeContractArgs {
contract_address: ScAddress::Contract(ContractId(Hash([0; 32]))),
function_name: ScSymbol("test".try_into().unwrap()),
args: [ScVal::U64(id)].to_vec().try_into().unwrap(),
}),
sub_invocations: [].to_vec().try_into().unwrap(),
},
}
}
fn create_invoke_host_op(auth_entries: &[SorobanAuthorizationEntry]) -> Operation {
Operation {
source_account: None,
body: OperationBody::InvokeHostFunction(InvokeHostFunctionOp {
host_function: HostFunction::InvokeContract(InvokeContractArgs {
contract_address: ScAddress::Contract(ContractId(Hash([0; 32]))),
function_name: ScSymbol("test".try_into().unwrap()),
args: [].to_vec().try_into().unwrap(),
}),
auth: auth_entries.try_into().unwrap(),
}),
}
}
fn create_payment_op() -> Operation {
Operation {
source_account: None,
body: OperationBody::Payment(PaymentOp {
asset: Asset::Native,
destination: MuxedAccount::Ed25519(Uint256([0; 32])),
amount: 1,
}),
}
}