Skip to content

Commit 1c14d9b

Browse files
authored
Set Request ID on Acceptance Tests (#659)
- Set requestId for acceptance tests (see logs from test runs to check how it looks). - Fix acceptance tests. - Make tests run parallel and retry 3 times before failing. - Fix eth_getLogs bug, when passing only toBlock as parameter. When only toBlock is passed, fromBlock is being defaulted to 'latest', which results in toBlock < fromBlock. This returns empty array. Now if only toBlock is passed, fromBlock defaults to toBlock, are returns logs only for this block. - Fix eth_getLogs bug, when passing wrong blockHash. Signed-off-by: georgi-l95 <[email protected]>
1 parent 0827c2b commit 1c14d9b

File tree

14 files changed

+461
-372
lines changed

14 files changed

+461
-372
lines changed

.github/workflows/acceptance-workflow.yml

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -38,12 +38,8 @@ jobs:
3838
run: npx lerna run build
3939

4040
- name: Run acceptance tests
41-
continue-on-error: true
42-
timeout-minutes: 15
43-
run: npm run acceptancetest:${{ inputs.testfilter }}
44-
45-
- name: Re-run acceptance tests (without nick-fields/retry@v2)
46-
if: ${{ failure() }}
47-
timeout-minutes: 15
48-
run: npm run acceptancetest:${{ inputs.testfilter }}
49-
41+
uses: nick-fields/retry@v2
42+
with:
43+
max_attempts: 3
44+
timeout_minutes: 15
45+
command: npm run acceptancetest:${{ inputs.testfilter }}

.github/workflows/acceptance.yml

Lines changed: 9 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,10 @@ name: Acceptance Tests
22

33
on:
44
pull_request:
5-
branches: [ main, release/** ]
5+
branches: [main, release/**]
66
push:
7-
branches: [ main, release/** ]
8-
tags: [ v* ]
7+
branches: [main, release/**]
8+
tags: [v*]
99

1010
jobs:
1111
api:
@@ -17,35 +17,29 @@ jobs:
1717
erc20:
1818
name: ERC20
1919
uses: ./.github/workflows/acceptance-workflow.yml
20-
needs: api
2120
with:
2221
testfilter: erc20
2322

2423
ratelimiter:
2524
name: Rate Limiter
2625
uses: ./.github/workflows/acceptance-workflow.yml
27-
needs: [ api, erc20 ]
2826
with:
2927
testfilter: ratelimiter
3028

3129
tokencreate:
32-
name: Token Create
30+
name: Token Create
3331
uses: ./.github/workflows/acceptance-workflow.yml
34-
needs: [ api, erc20, ratelimiter ]
35-
with:
32+
with:
3633
testfilter: tokencreate
3734

3835
tokenmanagement:
39-
name: Token Management
36+
name: Token Management
4037
uses: ./.github/workflows/acceptance-workflow.yml
41-
needs: [ api, erc20, ratelimiter ]
42-
with:
38+
with:
4339
testfilter: tokenmanagement
4440

4541
htsprecompilev1:
46-
name: Precompile
42+
name: Precompile
4743
uses: ./.github/workflows/acceptance-workflow.yml
48-
needs: [ api, erc20, ratelimiter ]
49-
with:
44+
with:
5045
testfilter: htsprecompilev1
51-

packages/relay/src/lib/eth.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1266,6 +1266,8 @@ export class EthImpl implements Eth {
12661266
`gte:${block.timestamp.from}`,
12671267
`lte:${block.timestamp.to}`
12681268
];
1269+
}else {
1270+
return [];
12691271
}
12701272
}
12711273
catch(e: any) {
@@ -1288,7 +1290,10 @@ export class EthImpl implements Eth {
12881290
} else {
12891291
params.timestamp = [];
12901292

1291-
const fromBlockResponse = await this.getHistoricalBlockResponse(fromBlock || "latest", true, requestId);
1293+
// Use the `toBlock` if it is the only passed tag, if not utilize the `fromBlock` or default to "latest"
1294+
const blockTag = toBlock && !fromBlock ? toBlock : fromBlock || "latest";
1295+
1296+
const fromBlockResponse = await this.getHistoricalBlockResponse(blockTag, true, requestId);
12921297
if (fromBlockResponse != null) {
12931298
params.timestamp.push(`gte:${fromBlockResponse.timestamp.from}`);
12941299
fromBlockNum = parseInt(fromBlockResponse.number);

packages/server/tests/acceptance/erc20.spec.ts

Lines changed: 28 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,8 @@ describe('@erc20 Acceptance Tests', async function () {
4040
let initialHolder;
4141
let recipient;
4242
let anotherAccount;
43+
let requestId;
44+
4345
const contracts:[any] = [];
4446

4547
const name = Utils.randomString(10);
@@ -51,13 +53,15 @@ describe('@erc20 Acceptance Tests', async function () {
5153

5254
const testTitles = [
5355
{testName: ERC20, expectedBytecode: ERC20MockJson.deployedBytecode},
54-
{testName: HTS, expectedBytecode: EthImpl.emptyHex}
56+
{testName: HTS}
5557
];
5658

5759
this.beforeAll(async () => {
58-
accounts[0] = await servicesNode.createAliasAccount(30, relay.provider);
59-
accounts[1] = await servicesNode.createAliasAccount(15, relay.provider);
60-
accounts[2] = await servicesNode.createAliasAccount(15, relay.provider);
60+
requestId = Utils.generateRequestId();
61+
62+
accounts[0] = await servicesNode.createAliasAccount(30, relay.provider, requestId);
63+
accounts[1] = await servicesNode.createAliasAccount(15, relay.provider, requestId);
64+
accounts[2] = await servicesNode.createAliasAccount(15, relay.provider, requestId);
6165

6266
initialHolder = accounts[0].address;
6367
recipient = accounts[1].address;
@@ -70,6 +74,10 @@ describe('@erc20 Acceptance Tests', async function () {
7074
contracts.push(await createHTS(name, symbol, accounts[0], 10000, ERC20MockJson.abi, [accounts[1], accounts[2]]));
7175
});
7276

77+
this.beforeEach(async () => {
78+
requestId = Utils.generateRequestId();
79+
});
80+
7381
for (const i in testTitles) {
7482
describe(testTitles[i].testName, async function () {
7583
let contract;
@@ -91,8 +99,13 @@ describe('@erc20 Acceptance Tests', async function () {
9199
});
92100

93101
it('Relay can execute "eth_getCode" for ERC20 contract with evmAddress', async function () {
94-
const res = await relay.call('eth_getCode', [contract.address]);
95-
expect(res).to.eq(testTitles[i].expectedBytecode);
102+
const res = await relay.call('eth_getCode', [contract.address], requestId);
103+
const expectedBytecode = `${EthImpl.redirectBytecodePrefix}${contract.address.slice(2)}${EthImpl.redirectBytecodePostfix}`
104+
if (testTitles[i].testName !== HTS) {
105+
expect(res).to.eq(testTitles[i].expectedBytecode);
106+
} else {
107+
expect(res).to.eq(expectedBytecode);
108+
}
96109
});
97110

98111
describe('should behave like erc20', function() {
@@ -179,17 +192,12 @@ describe('@erc20 Acceptance Tests', async function () {
179192
receipt = await tx.wait();
180193
});
181194

182-
// FIXME there is an issue with the Approval event for HTS tokens in Services.
183-
// Re-enable this test when it is resolved
184-
// Last tested with services image: 0.30.0-alpha.2
185-
if (testTitles[i].testName !== HTS) {
186-
it('emits an approval event', async function () {
187-
const allowance = await contract.allowance(tokenOwner, spender);
188-
await expect(tx)
189-
.to.emit(contract, 'Approval')
190-
.withArgs(tokenOwnerWallet.address, spenderWallet.address, allowance);
191-
});
192-
}
195+
it('emits an approval event', async function () {
196+
const allowance = await contract.allowance(tokenOwner, spender);
197+
await expect(tx)
198+
.to.emit(contract, 'Approval')
199+
.withArgs(tokenOwnerWallet.address, spenderWallet.address, allowance);
200+
});
193201

194202
describe('when the token owner has enough balance', function () {
195203
let amount, tx;
@@ -302,11 +310,6 @@ describe('@erc20 Acceptance Tests', async function () {
302310
expect(allowance.toString()).to.be.equal((initialSupply.toNumber() - 1).toString());
303311
});
304312
}
305-
306-
it('does not emit an approval event', async function () {
307-
await expect(await contract.connect(spenderWallet).transferFrom(tokenOwner, to, 1))
308-
.to.not.emit(contract, 'Approval');
309-
});
310313
});
311314
});
312315

@@ -354,12 +357,12 @@ describe('@erc20 Acceptance Tests', async function () {
354357

355358
// Associate and approve token for all accounts
356359
for (const account of associatedAccounts) {
357-
await servicesNode.associateHTSToken(account.accountId, htsResult.receipt.tokenId, account.privateKey, htsResult.client);
358-
await servicesNode.approveHTSToken(account.accountId, htsResult.receipt.tokenId, htsResult.client);
360+
await servicesNode.associateHTSToken(account.accountId, htsResult.receipt.tokenId, account.privateKey, htsResult.client, requestId);
361+
await servicesNode.approveHTSToken(account.accountId, htsResult.receipt.tokenId, htsResult.client, requestId);
359362
}
360363

361364
// Setup initial balance of token owner account
362-
await servicesNode.transferHTSToken(accounts[0].accountId, htsResult.receipt.tokenId, initialSupply, htsResult.client);
365+
await servicesNode.transferHTSToken(accounts[0].accountId, htsResult.receipt.tokenId, initialSupply, htsResult.client, requestId);
363366
const evmAddress = Utils.idToEvmAddress(htsResult.receipt.tokenId.toString());
364367
return new ethers.Contract(evmAddress, abi, accounts[0].wallet);
365368
};

packages/server/tests/acceptance/htsPrecompile/tokenCreate.spec.ts

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ import { ethers } from 'ethers';
2929
import ERC20MockJson from '../../contracts/ERC20Mock.json';
3030
import ERC721MockJson from '../../contracts/ERC721Mock.json';
3131
import TokenCreateJson from '../../contracts/TokenCreateContract.json';
32+
import { Utils } from '../../helpers/utils';
3233

3334
/**
3435
* Tests for:
@@ -74,17 +75,20 @@ describe('@tokencreate HTS Precompile Token Create Acceptance Tests', async func
7475
let mainContractReceiverWalletFirst;
7576
let mainContractReceiverWalletSecond;
7677
let HTSTokenWithCustomFeesContractAddress;
78+
let requestId;
7779

7880
before(async () => {
79-
accounts[0] = await servicesNode.createAliasAccount(200, relay.provider);
80-
accounts[1] = await servicesNode.createAliasAccount(30, relay.provider);
81-
accounts[2] = await servicesNode.createAliasAccount(30, relay.provider);
81+
requestId = Utils.generateRequestId();
82+
83+
accounts[0] = await servicesNode.createAliasAccount(200, relay.provider, requestId);
84+
accounts[1] = await servicesNode.createAliasAccount(30, relay.provider, requestId);
85+
accounts[2] = await servicesNode.createAliasAccount(30, relay.provider, requestId);
8286

8387
// allow mirror node a 2 full record stream write windows (2 sec) and a buffer to persist setup details
8488
await new Promise(r => setTimeout(r, 5000));
85-
await mirrorNode.get(`/accounts/${accounts[0].accountId}`);
86-
await mirrorNode.get(`/accounts/${accounts[1].accountId}`);
87-
await mirrorNode.get(`/accounts/${accounts[2].accountId}`);
89+
await mirrorNode.get(`/accounts/${accounts[0].accountId}`, requestId);
90+
await mirrorNode.get(`/accounts/${accounts[1].accountId}`, requestId);
91+
await mirrorNode.get(`/accounts/${accounts[2].accountId}`, requestId);
8892

8993
mainContractAddress = await deploymainContract();
9094
HTSTokenContractAddress = await createHTSToken();
@@ -100,6 +104,10 @@ describe('@tokencreate HTS Precompile Token Create Acceptance Tests', async func
100104
mainContractReceiverWalletSecond = mainContract.connect(accounts[2].wallet);
101105
});
102106

107+
this.beforeEach(async () => {
108+
requestId = Utils.generateRequestId();
109+
});
110+
103111
async function deploymainContract() {
104112
const mainFactory = new ethers.ContractFactory(TokenCreateJson.abi, TokenCreateJson.bytecode, accounts[0].wallet);
105113
const mainContract = await mainFactory.deploy({gasLimit: 15000000});

packages/server/tests/acceptance/htsPrecompile/tokenManagement.spec.ts

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ import Assertions from '../../helpers/assertions';
2929
import { ethers } from 'ethers';
3030
import ERC20MockJson from '../../contracts/ERC20Mock.json';
3131
import TokenManagementJson from '../../contracts/TokenManagementContract.json';
32+
import { Utils } from '../../helpers/utils';
3233

3334
/**
3435
* Tests for:
@@ -61,15 +62,18 @@ describe('@tokenmanagement HTS Precompile Token Management Acceptance Tests', as
6162
let mainContract;
6263
let mainContractOwner;
6364
let mainContractReceiverWalletFirst;
65+
let requestId;
6466

6567
this.beforeAll(async () => {
66-
accounts[0] = await servicesNode.createAliasAccount(200, relay.provider);
67-
accounts[1] = await servicesNode.createAliasAccount(30, relay.provider);
68+
requestId = Utils.generateRequestId();
69+
70+
accounts[0] = await servicesNode.createAliasAccount(200, relay.provider, requestId);
71+
accounts[1] = await servicesNode.createAliasAccount(30, relay.provider, requestId);
6872

6973
// allow mirror node a 2 full record stream write windows (2 sec) and a buffer to persist setup details
7074
await new Promise(r => setTimeout(r, 5000));
71-
await mirrorNode.get(`/accounts/${accounts[0].accountId}`);
72-
await mirrorNode.get(`/accounts/${accounts[1].accountId}`);
75+
await mirrorNode.get(`/accounts/${accounts[0].accountId}`, requestId);
76+
await mirrorNode.get(`/accounts/${accounts[1].accountId}`, requestId);
7377

7478
mainContractAddress = await deploymainContract();
7579
HTSTokenContractAddress = await createHTSToken();
@@ -94,6 +98,10 @@ describe('@tokenmanagement HTS Precompile Token Management Acceptance Tests', as
9498
expect((await tx4.wait()).events.filter(e => e.event === 'ResponseCode')[0].args.responseCode).to.equal(TX_SUCCESS_CODE);
9599
});
96100

101+
this.beforeEach(async () => {
102+
requestId = Utils.generateRequestId();
103+
});
104+
97105
async function deploymainContract() {
98106
const mainFactory = new ethers.ContractFactory(TokenManagementJson.abi, TokenManagementJson.bytecode, accounts[0].wallet);
99107
const mainContract = await mainFactory.deploy({gasLimit: 15000000});
@@ -513,7 +521,7 @@ describe('@tokenmanagement HTS Precompile Token Management Acceptance Tests', as
513521
//Expiry Info auto renew account returns account id from type - 0x000000000000000000000000000000000000048C
514522
//We expect account to be evm address, but because we can't compute one address for the other, we have to make a mirror node query to get expiry info auto renew evm address
515523
async function mirrorNodeAddressReq(address){
516-
const accountEvmAddress = await mirrorNode.get(`/accounts/${address}?transactiontype=cryptotransfer`);
524+
const accountEvmAddress = await mirrorNode.get(`/accounts/${address}?transactiontype=cryptotransfer`, requestId);
517525
return accountEvmAddress.evm_address;
518526
}
519527

packages/server/tests/acceptance/htsPrecompile_v1.spec.ts

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ chai.use(solidity);
2727
import { AliasAccount } from '../clients/servicesClient';
2828
import { ethers } from 'ethers';
2929
import BaseHTSJson from '../contracts/contracts_v1/BaseHTS.json';
30+
import { Utils } from '../helpers/utils';
3031

3132

3233
describe('@htsprecompilev1 HTS Precompile V1 Acceptance Tests', async function () {
@@ -44,11 +45,14 @@ describe('@htsprecompilev1 HTS Precompile V1 Acceptance Tests', async function (
4445
let baseHTSContractReceiverWalletFirst;
4546
let baseHTSContractReceiverWalletSecond;
4647
let HTSTokenWithCustomFeesContractAddress;
48+
let requestId;
4749

4850
this.beforeAll(async () => {
49-
accounts[0] = await servicesNode.createAliasAccount(60, relay.provider);
50-
accounts[1] = await servicesNode.createAliasAccount(15, relay.provider);
51-
accounts[2] = await servicesNode.createAliasAccount(15, relay.provider);
51+
requestId = Utils.generateRequestId();
52+
53+
accounts[0] = await servicesNode.createAliasAccount(70, relay.provider, requestId);
54+
accounts[1] = await servicesNode.createAliasAccount(25, relay.provider, requestId);
55+
accounts[2] = await servicesNode.createAliasAccount(25, relay.provider, requestId);
5256

5357
// alow mirror node a 2 full record stream write windows (2 sec) and a buffer to persist setup details
5458
await new Promise(r => setTimeout(r, 5000));
@@ -61,6 +65,10 @@ describe('@htsprecompilev1 HTS Precompile V1 Acceptance Tests', async function (
6165
baseHTSContractReceiverWalletSecond = baseHTSContract.connect(accounts[2].wallet);
6266
});
6367

68+
this.beforeEach(async () => {
69+
requestId = Utils.generateRequestId();
70+
});
71+
6472
async function deployBaseHTSContract() {
6573
const baseHTSFactory = new ethers.ContractFactory(BaseHTSJson.abi, BaseHTSJson.bytecode, accounts[0].wallet);
6674
const baseHTS = await baseHTSFactory.deploy({gasLimit: 10_000_000});

0 commit comments

Comments
 (0)