Skip to content

Commit

Permalink
feat(state): implements sizeOfIndex on WalletRepository (#479)
Browse files Browse the repository at this point in the history
* Add sizeOfIndex

* Add initial implementation

* Wallet repository clone

* Implement on wallet repo clone

* Add missing attribute

* FIx validator resignation
  • Loading branch information
sebastijankuzner authored Mar 13, 2024
1 parent 79eafc0 commit 221d08a
Show file tree
Hide file tree
Showing 6 changed files with 37 additions and 6 deletions.
1 change: 1 addition & 0 deletions packages/contracts/source/contracts/state/wallets.ts
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@ export interface WalletRepository {
getIndex(name: string): WalletIndex;
setOnIndex(index: string, key: string, wallet: Wallet): void;
forgetOnIndex(index: string, key: string): void;
sizeOfIndex(index: string): number;

setDirtyWallet(wallet: Wallet): void;
getDirtyWallets(): IterableIterator<Wallet>;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,11 +37,10 @@ export class ValidatorResignationTransactionHandler extends Handlers.Transaction
throw new Exceptions.WalletAlreadyResignedError();
}

// TODO: use validator count relative to proposed block height
const requiredValidatorsCount: number = this.configuration.getMilestone().activeValidators;
const currentValidatorsCount: number = walletRepository
.allValidators()
.filter((w) => w.hasAttribute("validatorResigned") === false).length;
const currentValidatorsCount: number =
walletRepository.sizeOfIndex(Contracts.State.WalletIndexes.Validators) -
walletRepository.sizeOfIndex(Contracts.State.WalletIndexes.Resignations);

if (currentValidatorsCount - 1 < requiredValidatorsCount) {
throw new Exceptions.NotEnoughValidatorsError();
Expand Down
1 change: 1 addition & 0 deletions packages/state/source/service-provider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ export class ServiceProvider extends Providers.ServiceProvider {
walletAttributeRepository.set("validatorForgedTotal", Contracts.State.AttributeType.BigNumber);
walletAttributeRepository.set("validatorProducedBlocks", Contracts.State.AttributeType.Number);
walletAttributeRepository.set("validatorApproval", Contracts.State.AttributeType.Number);
walletAttributeRepository.set("validatorResigned", Contracts.State.AttributeType.Boolean);

this.app
.bind(Identifiers.State.Wallet.Factory)
Expand Down
5 changes: 5 additions & 0 deletions packages/state/source/wallets/wallet-repository-by-sender.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,8 +70,13 @@ export class WalletRepositoryBySender extends WalletRepository {
return this.#blockchainWalletRepository.hasByIndex(index, key);
}

// TODO: set, forget & sizeOfIndex methods are not implemented fully
public setOnIndex(index: string, key: string, wallet: Contracts.State.Wallet): void {}

public sizeOfIndex(index: string): number {
return this.#blockchainWalletRepository.sizeOfIndex(index);
}

#cloneWallet(address: string): Contracts.State.Wallet {
return this.#blockchainWalletRepository.findByAddress(address).clone(this);
}
Expand Down
25 changes: 23 additions & 2 deletions packages/state/source/wallets/wallet-repository-clone.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ export class WalletRepositoryClone extends WalletRepository implements Contracts
#originalWalletRepository!: WalletRepository;

readonly #forgetIndexes: Record<string, Set<string>> = {};
readonly #indexOffset: Record<string, number> = {};
readonly #dirtyWallets = new Set<Contracts.State.Wallet>();

@postConstruct()
Expand All @@ -16,6 +17,7 @@ export class WalletRepositoryClone extends WalletRepository implements Contracts

for (const name of this.indexSet.all()) {
this.#forgetIndexes[name] = new Set();
this.#indexOffset[name] = 0;
}
}

Expand Down Expand Up @@ -83,17 +85,36 @@ export class WalletRepositoryClone extends WalletRepository implements Contracts
}

public setOnIndex(index: string, key: string, wallet: Contracts.State.Wallet): void {
// New key registration
if (!this.#originalWalletRepository.hasByIndex(index, key) && !this.getIndex(index).has(key)) {
this.#indexOffset[index]++;
}

// Remove from forget indexes
if (this.#getForgetSet(index).has(key)) {
this.#getForgetSet(index).delete(key);
this.#indexOffset[index]++;
}

this.getIndex(index).set(key, wallet);
this.#getForgetSet(index).delete(key);
}

public forgetOnIndex(index: string, key: string): void {
if (this.getIndex(index).has(key) || this.#originalWalletRepository.getIndex(index).has(key)) {
if (
!this.#getForgetSet(index).has(key) &&
(this.getIndex(index).has(key) || this.#originalWalletRepository.getIndex(index).has(key))
) {
this.getIndex(index).forget(key);
this.#getForgetSet(index).add(key);

this.#indexOffset[index]--;
}
}

public sizeOfIndex(index: string): number {
return this.#originalWalletRepository.sizeOfIndex(index) + this.#indexOffset[index];
}

public getDirtyWallets(): IterableIterator<Contracts.State.Wallet> {
return this.#dirtyWallets.values();
}
Expand Down
4 changes: 4 additions & 0 deletions packages/state/source/wallets/wallet-repository.ts
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,10 @@ export class WalletRepository implements Contracts.State.WalletRepository {
this.getIndex(index).forget(key);
}

public sizeOfIndex(index: string): number {
return this.getIndex(index).size();
}

public setDirtyWallet(wallet: Contracts.State.Wallet): void {}

public getDirtyWallets(): IterableIterator<Contracts.State.Wallet> {
Expand Down

0 comments on commit 221d08a

Please sign in to comment.