Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

e2e for duplicated keys check and invalid keys #155

Merged
merged 4 commits into from
Dec 19, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -275,6 +275,8 @@ $ yarn test:e2e
$ yarn test:cov
```

To run e2e tests, ensure the RPC_URL environment variable is set to the Goerli provider's endpoint, and generate private keys, which should be subsequently set in the WALLET_PRIVATE_KEY variable.

## Release flow

To create a new release:
Expand Down
3 changes: 3 additions & 0 deletions src/contracts/deposit/deposit.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -243,6 +243,7 @@ export class DepositService {
* The last N blocks are not stored, in order to avoid storing reorganized blocks
*/
public async updateEventsCache(): Promise<void> {
this.logger.log('try to update?');
F4ever marked this conversation as resolved.
Show resolved Hide resolved
const fetchTimeStart = performance.now();

const [currentBlock, initialCache] = await Promise.all([
Expand Down Expand Up @@ -270,6 +271,8 @@ export class DepositService {
chunkToBlock,
);

console.log('chunk?', chunkEventGroup);
F4ever marked this conversation as resolved.
Show resolved Hide resolved

updatedCachedEvents.headers.endBlock = chunkEventGroup.endBlock;
updatedCachedEvents.data = updatedCachedEvents.data.concat(
chunkEventGroup.events,
Expand Down
1 change: 1 addition & 0 deletions src/guardian/guardian.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,7 @@ export class GuardianService implements OnModuleInit {

await this.depositService.handleNewBlock(blockNumber);

// TODO: e2e test 'node operator deposit frontrun' shows that it is possible to find event and not save in cache
const blockData = await this.blockGuardService.getCurrentBlockData({
blockHash,
blockNumber,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -237,7 +237,14 @@ export class StakingModuleGuardService {
intersectionsWithLidoWC: VerifiedDepositEvent[],
blockData: BlockData,
) {
const depositedPubkeys = intersectionsWithLidoWC.map(
// should not check invalid
// TODO: fix in prev PR
const validIntersections = intersectionsWithLidoWC.filter(
({ valid }) => valid,
);
if (!validIntersections.length) return [];

const depositedPubkeys = validIntersections.map(
(deposit) => deposit.pubkey,
);

Expand Down
18 changes: 9 additions & 9 deletions src/guardian/staking-module-guard/staking-module-guard.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -669,9 +669,9 @@ describe('StakingModuleGuardService', () => {
const pubkeyWithUsedKey2 = '0x3478';
const lidoWC = '0x12';
const intersectionsWithLidoWC = [
{ pubkey: pubkeyWithUsedKey1, wc: lidoWC } as any,
{ pubkey: pubkeyWithoutUsedKey, wc: lidoWC } as any,
{ pubkey: pubkeyWithUsedKey2, wc: lidoWC } as any,
{ pubkey: pubkeyWithUsedKey1, wc: lidoWC, valid: true } as any,
{ pubkey: pubkeyWithoutUsedKey, wc: lidoWC, valid: true } as any,
{ pubkey: pubkeyWithUsedKey2, wc: lidoWC, valid: true } as any,
];
// function that return list from kapi that match keys in parameter
const mockSendMessageFromGuardian = jest
Expand Down Expand Up @@ -767,9 +767,9 @@ describe('StakingModuleGuardService', () => {
const pubkey3 = '0x3478';
const lidoWC = '0x12';
const intersectionsWithLidoWC = [
{ pubkey: pubkey1, wc: lidoWC } as any,
{ pubkey: pubkey2, wc: lidoWC } as any,
{ pubkey: pubkey3, wc: lidoWC } as any,
{ pubkey: pubkey1, wc: lidoWC, valid: true } as any,
{ pubkey: pubkey2, wc: lidoWC, valid: true } as any,
{ pubkey: pubkey3, wc: lidoWC, valid: true } as any,
];
// function that return list from kapi that match keys in parameter
const mockSendMessageFromGuardian = jest
Expand Down Expand Up @@ -829,9 +829,9 @@ describe('StakingModuleGuardService', () => {
const pubkey3 = '0x3478';
const lidoWC = '0x12';
const intersectionsWithLidoWC = [
{ pubkey: pubkey1, wc: lidoWC } as any,
{ pubkey: pubkey2, wc: lidoWC } as any,
{ pubkey: pubkey3, wc: lidoWC } as any,
{ pubkey: pubkey1, wc: lidoWC, valid: true } as any,
{ pubkey: pubkey2, wc: lidoWC, valid: true } as any,
{ pubkey: pubkey3, wc: lidoWC, valid: true } as any,
];
// function that return list from kapi that match keys in parameter
const mockSendMessageFromGuardian = jest
Expand Down
2 changes: 1 addition & 1 deletion src/keys-api/keys-api.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ export class KeysApiService {

/**
*
* @param The /v1/keys/find KAPI endpoint returns a key along with its duplicates
* @param The /v1/keys/find API endpoint returns keys along with their duplicates
* @returns
*/
public async findKeysEntires(pubkeys: string[]) {
Expand Down
111 changes: 58 additions & 53 deletions test/helpers/mockKeysApi.ts
Original file line number Diff line number Diff line change
@@ -1,66 +1,52 @@
import ethers from 'ethers';
import { toHexString } from '@chainsafe/ssz';

import { KeysApiService } from '../../src/keys-api/keys-api.service';
import { NOP_REGISTRY, pk } from './../constants';
import { NOP_REGISTRY } from './../constants';
import { RegistryOperator } from 'keys-api/interfaces/RegistryOperator';
import { SRModule } from 'keys-api/interfaces';
import { ELBlockSnapshot } from 'keys-api/interfaces/ELBlockSnapshot';
import { RegistryKey } from 'keys-api/interfaces/RegistryKey';

export const mockKeysApi = (
sig: Uint8Array[],
block: ethers.providers.Block,
keysApiService: KeysApiService,
used = false,
) => {
const mockedModule = {
nonce: 6046,
type: 'grouped-onchain-v1',
id: 1,
stakingModuleAddress: NOP_REGISTRY,
moduleFee: 10,
treasuryFee: 10,
targetShare: 10,
status: 1,
name: 'NodeOperatorRegistry',
lastDepositAt: block.timestamp,
lastDepositBlock: block.number,
};
export const mockedModule = (block: ethers.providers.Block) => ({
nonce: 6046,
type: 'grouped-onchain-v1',
id: 1,
stakingModuleAddress: NOP_REGISTRY,
moduleFee: 10,
treasuryFee: 10,
targetShare: 10,
status: 1,
name: 'NodeOperatorRegistry',
lastDepositAt: block.timestamp,
lastDepositBlock: block.number,
});

const mockedMeta = {
blockNumber: block.number,
blockHash: block.hash,
timestamp: block.timestamp,
};
export const mockedMeta = (block: ethers.providers.Block) => ({
blockNumber: block.number,
blockHash: block.hash,
timestamp: block.timestamp,
});

const mockedKeys = sig.map((x) => ({
key: toHexString(pk),
depositSignature: toHexString(x),
operatorIndex: 0,
used,
export const mockedOperators: RegistryOperator[] = [
{
name: 'Dev team',
rewardAddress: '0x6D725DAe055287f913661ee0b79dE6B21F12A459',
stakingLimit: 12,
stoppedValidators: 0,
totalSigningKeys: 12,
usedSigningKeys: 10,
index: 0,
active: true,
moduleAddress: NOP_REGISTRY,
}));

const mockedOperators: RegistryOperator[] = [
{
name: 'Dev team',
rewardAddress: '0x6D725DAe055287f913661ee0b79dE6B21F12A459',
stakingLimit: 11,
stoppedValidators: 0,
totalSigningKeys: 11,
usedSigningKeys: 10,
index: 0,
active: true,
moduleAddress: NOP_REGISTRY,
},
];

jest.spyOn(keysApiService, 'getUnusedKeys').mockImplementation(async () => ({
data: mockedKeys,
meta: {
elBlockSnapshot: mockedMeta,
},
}));
},
];

export const mockedKeysApiOperators = (
keysApiService: KeysApiService,
mockedOperators: RegistryOperator[],
mockedModule: SRModule,
mockedMeta: ELBlockSnapshot,
) => {
jest
.spyOn(keysApiService, 'getOperatorListWithModule')
.mockImplementation(async () => ({
Expand All @@ -69,7 +55,26 @@ export const mockKeysApi = (
elBlockSnapshot: mockedMeta,
},
}));
};

export const mockedKeysApiUnusedKeys = (
keysApiService: KeysApiService,
mockedKeys: RegistryKey[],
mockedMeta: ELBlockSnapshot,
) => {
jest.spyOn(keysApiService, 'getUnusedKeys').mockImplementation(async () => ({
data: mockedKeys,
meta: {
elBlockSnapshot: mockedMeta,
},
}));
};

export const mockedKeysWithDuplicates = (
keysApiService: KeysApiService,
mockedKeys: RegistryKey[],
mockedMeta: ELBlockSnapshot,
) => {
jest
.spyOn(keysApiService, 'findKeysEntires')
.mockImplementation(async () => ({
Expand Down
Loading
Loading