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

dev to main #235

Merged
merged 58 commits into from
Jan 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
58 commits
Select commit Hold shift + click to select a range
dbfee63
fix: add missing `middleware` package
AlexanderLukin Nov 25, 2023
ed05fa8
fix: log
Amuhar Dec 11, 2023
1860c8d
Merge pull request #223 from lidofinance/fix-logs-end-time
Amuhar Dec 12, 2023
d5247d5
feat: add finalizedUsedSigningKeys
eddort Dec 18, 2023
2471e3f
feat: new indexing logic
eddort Dec 19, 2023
92ecf44
fix: revert operatorsWereChanged logic
eddort Dec 19, 2023
183cbbd
fix: tests
eddort Dec 19, 2023
cca8041
feat: add data to endpoints
eddort Dec 20, 2023
244967d
fix: fixtures and entity types
eddort Dec 20, 2023
3fa909b
fix: operators fetch spec
eddort Dec 20, 2023
138e9c3
fix: reorg detection
eddort Dec 20, 2023
39a92e9
feat: add migration
eddort Dec 20, 2023
7b018f3
feat: moduleAddresses filter
eddort Dec 20, 2023
edf5c22
refactor: split update function into two
eddort Dec 20, 2023
c7bb4e3
refactor: move interfaces to a separate file
eddort Dec 20, 2023
7e52c4c
test: processing of all indexing cases
eddort Dec 20, 2023
2796b6f
refactor: rename updater
eddort Dec 20, 2023
1533454
fix: different hash but same number case
eddort Dec 20, 2023
ba06c2c
test: reorg spec
eddort Dec 20, 2023
a8a1bc0
test: reorg cases
eddort Dec 20, 2023
403a91a
fix: block range in isReorgDetected method
eddort Dec 20, 2023
9cef0d3
refactor: connect updater to keys-update service
eddort Dec 20, 2023
e9c83f7
fix: e2e tests
eddort Dec 20, 2023
60efe63
fix: reorg spec
eddort Dec 20, 2023
8f8bb45
fix: sql e2e spec
eddort Dec 20, 2023
ac084c5
test: debug e2e
eddort Dec 21, 2023
91ef826
fix: chronix tests
eddort Dec 21, 2023
05d2553
fix: e2e connects tests
eddort Dec 21, 2023
0c649a1
Merge pull request #228 from lidofinance/fix/e2e-tests
eddort Dec 21, 2023
9906c1e
Merge pull request #227 from lidofinance/feat/new-updater-refactoring
eddort Dec 21, 2023
66ccb66
fix: 425 error while fetching modules
eddort Dec 21, 2023
9599800
fix: 425 http error
eddort Dec 21, 2023
125a332
Merge pull request #226 from lidofinance/feat/gcd-endpoint
eddort Dec 21, 2023
e9d2249
fix: reorg detection
eddort Dec 21, 2023
d72df82
refactor: better logs
eddort Dec 21, 2023
754d6a4
test: reorg handling in registry module
eddort Dec 23, 2023
998c17a
test: key registry
eddort Dec 24, 2023
0d01ef6
test: fix fixtures
eddort Dec 24, 2023
d36ebca
fix: e2e test
eddort Dec 24, 2023
39a42a1
fix: httpExceptionTooEarlyResp
eddort Dec 24, 2023
c60467e
fix: update log message
eddort Dec 24, 2023
aa921b2
fix: remove old e2e tests
eddort Dec 24, 2023
506cdcd
refactor: reorg test
eddort Dec 24, 2023
079d15c
refactor: add comments to reorg check method
eddort Dec 24, 2023
453ac72
fix: reorg spec arg
eddort Dec 24, 2023
1dc39ec
fix: wrong migration
eddort Dec 25, 2023
06f8422
Merge pull request #225 from lidofinance/feat/indexing-reorg
eddort Dec 25, 2023
8b9aef1
fix: metrics id
Amuhar Jan 9, 2024
e4b8831
fix: metrics id
Amuhar Jan 9, 2024
cda57f4
Merge pull request #231 from lidofinance/fix-metrics
Amuhar Jan 9, 2024
9e54b81
fix: move reset above for loop
Amuhar Jan 9, 2024
db258d8
Merge pull request #232 from lidofinance/fix-metrics-reset
Amuhar Jan 9, 2024
d4fdb59
chore: bump version
infloop Jan 10, 2024
6da5dd1
Merge pull request #219 from lidofinance/fix/add-missing-middleware-p…
Amuhar Jan 12, 2024
bc82967
fix: srmodules types
eddort Jan 17, 2024
84e02ae
Merge pull request #236 from lidofinance/fix/srmodule-types
infloop Jan 17, 2024
0f318e1
test: covering reorg edge cases
eddort Jan 17, 2024
92538d3
Merge pull request #237 from lidofinance/fix/reorg-edge-cases
infloop Jan 17, 2024
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
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "lido-keys-api",
"version": "0.10.1",
"version": "0.10.2",
"description": "Lido Node Operators keys service",
"author": "Lido team",
"private": true,
Expand Down Expand Up @@ -51,6 +51,7 @@
"@lido-nestjs/execution": "^1.11.0",
"@lido-nestjs/fetch": "^1.4.0",
"@lido-nestjs/logger": "^1.3.2",
"@lido-nestjs/middleware": "^1.2.0",
"@lido-nestjs/validators-registry": "^1.3.0",
"@mikro-orm/cli": "^5.5.3",
"@mikro-orm/core": "^5.5.3",
Expand Down
8 changes: 4 additions & 4 deletions src/app/simple-dvt-deploy.e2e-chain.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import { RegistryKeyStorageService } from '../common/registry';
import { ElMetaStorageService } from '../storage/el-meta.storage';
import { SRModuleStorageService } from '../storage/sr-module.storage';
import { KeysUpdateService } from '../jobs/keys-update';
import { ExecutionProvider, ExecutionProviderService } from '../common/execution-provider';
import { ExecutionProvider } from '../common/execution-provider';
import { ConfigService } from '../common/config';
import { PrometheusService } from '../common/prometheus';
import { StakingRouterService } from '../staking-router-modules/staking-router.service';
Expand Down Expand Up @@ -64,8 +64,6 @@ describe('Simple DVT deploy', () => {
});

moduleRef = await Test.createTestingModule({ imports: [AppModule] })
.overrideProvider(ExecutionProviderService)
.useValue(session.provider)
.overrideProvider(SimpleFallbackJsonRpcBatchProvider)
.useValue(session.provider)
.overrideProvider(ExecutionProvider)
Expand All @@ -89,7 +87,9 @@ describe('Simple DVT deploy', () => {
.overrideProvider(ConfigService)
.useValue({
get(path) {
const conf = { LIDO_LOCATOR_ADDRESS: '0xC1d0b3DE6792Bf6b4b37EccdcC24e45978Cfd2Eb' };
const conf = {
LIDO_LOCATOR_ADDRESS: '0xC1d0b3DE6792Bf6b4b37EccdcC24e45978Cfd2Eb',
};
return conf[path];
},
})
Expand Down
9 changes: 9 additions & 0 deletions src/common/execution-provider/execution-provider.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,4 +46,13 @@ export class ExecutionProviderService {
const block = await this.provider.getBlock(blockHashOrBlockTag);
return { number: block.number, hash: block.hash, timestamp: block.timestamp };
}

/**
*
* Returns full block info
*/
public async getFullBlock(blockHashOrBlockTag: number | string) {
const block = await this.provider.getBlock(blockHashOrBlockTag);
return block;
}
}
1 change: 1 addition & 0 deletions src/common/registry/fetch/interfaces/operator.interface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,5 @@ export interface RegistryOperator {
totalSigningKeys: number;
usedSigningKeys: number;
moduleAddress: string;
finalizedUsedSigningKeys: number;
}
25 changes: 24 additions & 1 deletion src/common/registry/fetch/operator.fetch.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,20 +59,37 @@ export class RegistryOperatorFetchService {
return false;
}

/** return blockTag for finalized block, it need for testing purposes */
public getFinalizedBlockTag() {
return 'finalized';
}

/** fetches number of operators */
public async count(moduleAddress: string, overrides: CallOverrides = {}): Promise<number> {
const bigNumber = await this.getContract(moduleAddress).getNodeOperatorsCount(overrides as any);
return bigNumber.toNumber();
}

/** fetches finalized operator */
public async getFinalizedNodeOperator(moduleAddress: string, operatorIndex: number) {
const fullInfo = true;
const contract = this.getContract(moduleAddress);
const finalizedOperator = await contract.getNodeOperator(operatorIndex, fullInfo, {
blockTag: this.getFinalizedBlockTag(),
});
return finalizedOperator;
}

/** fetches one operator */
public async fetchOne(
moduleAddress: string,
operatorIndex: number,
overrides: CallOverrides = {},
): Promise<RegistryOperator> {
const fullInfo = true;
const operator = await this.getContract(moduleAddress).getNodeOperator(operatorIndex, fullInfo, overrides as any);
const contract = this.getContract(moduleAddress);

const operator = await contract.getNodeOperator(operatorIndex, fullInfo, overrides as any);

const {
name,
Expand All @@ -84,6 +101,11 @@ export class RegistryOperatorFetchService {
totalDepositedValidators,
} = operator;

const { totalDepositedValidators: finalizedUsedSigningKeys } = await this.getFinalizedNodeOperator(
moduleAddress,
operatorIndex,
);

return {
index: operatorIndex,
active,
Expand All @@ -94,6 +116,7 @@ export class RegistryOperatorFetchService {
totalSigningKeys: totalAddedValidators.toNumber(),
usedSigningKeys: totalDepositedValidators.toNumber(),
moduleAddress,
finalizedUsedSigningKeys: finalizedUsedSigningKeys.toNumber(),
};
}

Expand Down
7 changes: 3 additions & 4 deletions src/common/registry/main/abstract-registry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -108,9 +108,10 @@ export abstract class AbstractRegistryService {
const prevOperator = previousOperators[currentIndex] ?? null;
const isSameOperator = compareOperators(prevOperator, currOperator);

const finalizedUsedSigningKeys = prevOperator ? prevOperator.finalizedUsedSigningKeys : null;
// skip updating keys from 0 to `usedSigningKeys` of previous collected data
// since the contract guarantees that these keys cannot be changed
const unchangedKeysMaxIndex = isSameOperator ? prevOperator.usedSigningKeys : 0;
const unchangedKeysMaxIndex = isSameOperator && finalizedUsedSigningKeys ? finalizedUsedSigningKeys : 0;
// get the right border up to which the keys should be updated
// it's different for different scenarios
const toIndex = this.getToIndex(currOperator);
Expand All @@ -121,7 +122,7 @@ export abstract class AbstractRegistryService {

const operatorIndex = currOperator.index;
const overrides = { blockTag: { blockHash } };
// TODO: use feature flag

const result = await this.keyBatchFetch.fetch(moduleAddress, operatorIndex, fromIndex, toIndex, overrides);

const operatorKeys = result.filter((key) => key);
Expand All @@ -138,8 +139,6 @@ export abstract class AbstractRegistryService {

this.logger.log('Keys saved', { operatorIndex });
}

console.timeEnd('FETCH_OPERATORS');
}

/** storage */
Expand Down
4 changes: 4 additions & 0 deletions src/common/registry/storage/operator.entity.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ export class RegistryOperator {
this.totalSigningKeys = operator.totalSigningKeys;
this.usedSigningKeys = operator.usedSigningKeys;
this.moduleAddress = operator.moduleAddress;
this.finalizedUsedSigningKeys = operator.finalizedUsedSigningKeys;
}

@PrimaryKey()
Expand Down Expand Up @@ -46,4 +47,7 @@ export class RegistryOperator {
@PrimaryKey()
@Property({ length: ADDRESS_LEN })
moduleAddress!: string;

@Property()
finalizedUsedSigningKeys!: number;
}
28 changes: 27 additions & 1 deletion src/common/registry/test/fetch/key.fetch.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,33 @@ describe('Keys', () => {
const result = await fetchService.fetch(address, expected.operatorIndex);

expect(result).toEqual([expected]);
expect(mockCall).toBeCalledTimes(2);
expect(mockCall).toBeCalledTimes(3);
});

test('fetch all operator keys with reorg', async () => {
const expected = { operatorIndex: 1, index: 0, moduleAddress: address, ...key };

mockCall
.mockImplementationOnce(async () => {
const iface = new Interface(Registry__factory.abi);
return iface.encodeFunctionResult(
'getNodeOperator',
operatorFields({
...operator,
moduleAddress: address,
totalSigningKeys: 1,
usedSigningKeys: 2,
finalizedUsedSigningKeys: 1,
}),
);
})
.mockImplementation(async () => {
const iface = new Interface(Registry__factory.abi);
return iface.encodeFunctionResult('getSigningKey', keyFields);
});
const result = await fetchService.fetch(address, expected.operatorIndex);
expect(result).toEqual([expected]);
expect(mockCall).toBeCalledTimes(3);
});

test('fetch. fromIndex > toIndex', async () => {
Expand Down
9 changes: 4 additions & 5 deletions src/common/registry/test/fetch/operator.fetch.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ describe('Operators', () => {
const result = await fetchService.fetchOne(address, expected.index);

expect(result).toEqual(expected);
expect(mockCall).toBeCalledTimes(1);
expect(mockCall).toBeCalledTimes(2);
});

test('fetch', async () => {
Expand All @@ -62,7 +62,7 @@ describe('Operators', () => {
const result = await fetchService.fetch(address, expectedFirst.index, expectedSecond.index + 1);

expect(result).toEqual([expectedFirst, expectedSecond]);
expect(mockCall).toBeCalledTimes(2);
expect(mockCall).toBeCalledTimes(4);
});

test('fetch all', async () => {
Expand All @@ -73,16 +73,15 @@ describe('Operators', () => {
const iface = new Interface(Registry__factory.abi);
return iface.encodeFunctionResult('getNodeOperatorsCount', [1]);
})
.mockImplementationOnce(async () => {
.mockImplementation(async () => {
const iface = new Interface(Registry__factory.abi);
operator['moduleAddress'] = address;
// operatorFields(operator);
return iface.encodeFunctionResult('getNodeOperator', operatorFields(operator));
});
const result = await fetchService.fetch(address);

expect(result).toEqual([expected]);
expect(mockCall).toBeCalledTimes(2);
expect(mockCall).toBeCalledTimes(3);
});

test('fetch. fromIndex > toIndex', async () => {
Expand Down
Loading
Loading