Skip to content

Commit 4a1f774

Browse files
committed
test(e2e): rewards test
1 parent d1697e0 commit 4a1f774

File tree

2 files changed

+116
-2
lines changed

2 files changed

+116
-2
lines changed

packages/e2e/local-network/scripts/make-babbage.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -165,7 +165,7 @@ $SED -i "${ROOT}/genesis/shelley/genesis.json" \
165165
-e 's/"slotLength": 1/"slotLength": 0.1/' \
166166
-e 's/"activeSlotsCoeff": 5.0e-2/"activeSlotsCoeff": 0.1/' \
167167
-e 's/"securityParam": 2160/"securityParam": 10/' \
168-
-e 's/"epochLength": 432000/"epochLength": 100/' \
168+
-e 's/"epochLength": 432000/"epochLength": 500/' \
169169
-e "s/\"maxLovelaceSupply\": 0/\"maxLovelaceSupply\": ${MAX_SUPPLY}/" \
170170
-e 's/"minFeeA": 1/"minFeeA": 44/' \
171171
-e 's/"minFeeB": 0/"minFeeB": 155381/' \

packages/e2e/test/local-network/local-network.test.ts

Lines changed: 115 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
import * as envalid from 'envalid';
2+
import { Awaited } from '@cardano-sdk/util';
3+
import { Cardano } from '@cardano-sdk/core';
24
import { FaucetProvider } from '../../src/FaucetProvider';
3-
import { SingleAddressWallet } from '@cardano-sdk/wallet';
5+
import { ObservableWallet, SingleAddressWallet, StakeKeyStatus } from '@cardano-sdk/wallet';
46
import { faucetProviderFactory, getLogger, getWallet } from '../../src/factories';
57
import { filter, firstValueFrom, map } from 'rxjs';
68

@@ -29,6 +31,55 @@ export const env = envalid.cleanEnv(process.env, {
2931

3032
const logger = getLogger(env.LOGGER_MIN_SEVERITY);
3133

34+
const getWalletStateSnapshot = async (wallet: ObservableWallet) => {
35+
const [rewardAccount] = await firstValueFrom(wallet.delegation.rewardAccounts$);
36+
const balanceAvailable = await firstValueFrom(wallet.balance.utxo.available$);
37+
const balanceTotal = await firstValueFrom(wallet.balance.utxo.total$);
38+
const deposit = await firstValueFrom(wallet.balance.rewardAccounts.deposit$);
39+
const epoch = await firstValueFrom(wallet.currentEpoch$);
40+
const utxoTotal = await firstValueFrom(wallet.utxo.total$);
41+
const utxoAvailable = await firstValueFrom(wallet.utxo.available$);
42+
return {
43+
balance: { available: balanceAvailable, deposit, total: balanceTotal },
44+
epoch: epoch.epochNo,
45+
isStakeKeyRegistered: rewardAccount.keyStatus === StakeKeyStatus.Registered,
46+
rewardAccount,
47+
utxo: { available: utxoTotal, total: utxoAvailable }
48+
};
49+
};
50+
type WalletStateSnapshot = Awaited<ReturnType<typeof getWalletStateSnapshot>>;
51+
52+
const createDelegationCertificates = (
53+
{ epoch, isStakeKeyRegistered, rewardAccount: { address: rewardAccount } }: WalletStateSnapshot,
54+
poolId: Cardano.PoolId
55+
) => {
56+
const stakeKeyHash = Cardano.Ed25519KeyHash.fromRewardAccount(rewardAccount);
57+
return [
58+
...(isStakeKeyRegistered
59+
? []
60+
: ([
61+
{
62+
__typename: Cardano.CertificateType.StakeKeyRegistration,
63+
stakeKeyHash
64+
}
65+
] as Cardano.Certificate[])),
66+
{ __typename: Cardano.CertificateType.StakeDelegation, epoch, poolId, stakeKeyHash }
67+
] as Cardano.Certificate[];
68+
};
69+
70+
const generateTxs = async (wallet1: any, wallet2: any) => {
71+
const tAdaToSend = 5_000_000n;
72+
const [{ address: receivingAddress }] = await firstValueFrom(wallet2.wallet.addresses$);
73+
for (let i = 0; i < 100; i++) {
74+
const unsignedTxA = await wallet1.wallet.initializeTx({
75+
outputs: new Set([{ address: receivingAddress, value: { coins: tAdaToSend } }])
76+
});
77+
78+
const signedTxA = await wallet1.wallet.finalizeTx({ tx: unsignedTxA });
79+
await wallet1.wallet.submitTx(signedTxA);
80+
}
81+
};
82+
3283
describe('Local Network', () => {
3384
let faucetProvider: FaucetProvider;
3485

@@ -110,4 +161,67 @@ describe('Local Network', () => {
110161
wallet1.shutdown();
111162
wallet2.shutdown();
112163
});
164+
165+
it('will receive rewards for delegated tADA', async () => {
166+
// Arrange
167+
const amountFromFaucet = 100_000_000_000;
168+
169+
const wallet1 = await getWallet({ env, logger, name: 'Sending Wallet', polling: { interval: 50 } });
170+
const wallet2 = await getWallet({ env, logger, name: 'Receiving Wallet', polling: { interval: 50 } });
171+
172+
await firstValueFrom(wallet1.wallet.syncStatus.isSettled$.pipe(filter((isSettled) => isSettled)));
173+
await firstValueFrom(wallet2.wallet.syncStatus.isSettled$.pipe(filter((isSettled) => isSettled)));
174+
175+
const [{ address: sendingAddress }] = await firstValueFrom(wallet1.wallet.addresses$);
176+
177+
const waitForEpoch = async (numberOfEpochsToWait: number) => {
178+
const currentEpoch = await firstValueFrom(wallet1.wallet.currentEpoch$);
179+
return await firstValueFrom(
180+
wallet1.wallet.currentEpoch$.pipe(
181+
filter(({ epochNo }) => epochNo > currentEpoch.epochNo + numberOfEpochsToWait)
182+
)
183+
);
184+
};
185+
186+
logger.debug(`Address ${sendingAddress.toString()} will be funded with ${amountFromFaucet} tLovelace.`);
187+
await faucetProvider.request(sendingAddress.toString(), amountFromFaucet, 1);
188+
await firstValueFrom(wallet1.wallet.balance.utxo.total$.pipe(filter(({ coins }) => coins >= amountFromFaucet)));
189+
190+
const initialState = await getWalletStateSnapshot(wallet1.wallet);
191+
192+
const activePools = await wallet1.providers.stakePoolProvider.queryStakePools({
193+
filters: { status: [Cardano.StakePoolStatus.Active] },
194+
pagination: { limit: 2, startAt: 0 }
195+
});
196+
const poolId = activePools.pageResults[0].id;
197+
expect(poolId).toBeDefined();
198+
logger.debug(`Wallet funds will be staked to pool ${poolId}.`);
199+
const certificates = createDelegationCertificates(initialState, poolId);
200+
201+
// Act
202+
203+
// Create stake tx
204+
const unsignedTx = await wallet1.wallet.initializeTx({ certificates });
205+
const signedTx = await wallet1.wallet.finalizeTx({ tx: unsignedTx });
206+
await wallet1.wallet.submitTx(signedTx);
207+
208+
let currentEpoch = await firstValueFrom(wallet1.wallet.currentEpoch$);
209+
logger.debug(`current epoch - ${currentEpoch.epochNo}`);
210+
currentEpoch = await waitForEpoch(1);
211+
logger.debug(`waited for epoch - ${currentEpoch.epochNo} to start txs `);
212+
// workload for generating fees/rewards
213+
await generateTxs(wallet1, wallet2);
214+
215+
// Assert
216+
217+
currentEpoch = await waitForEpoch(2);
218+
logger.debug(`waited for epoch - ${currentEpoch.epochNo} to check rewards`);
219+
220+
// wait for rewards
221+
const reward = await firstValueFrom(wallet1.wallet.balance.rewardAccounts.rewards$.pipe(filter((r) => r > 0)));
222+
logger.debug(`amount of generated rewards - ${reward}`);
223+
224+
wallet1.wallet.shutdown();
225+
wallet2.wallet.shutdown();
226+
});
113227
});

0 commit comments

Comments
 (0)