Skip to content

Commit b87899a

Browse files
authored
refactor(core-state): wallet repositories (#3501)
1 parent c558ddd commit b87899a

File tree

8 files changed

+84
-112
lines changed

8 files changed

+84
-112
lines changed

packages/core-state/src/dpos/dpos-previous-round.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,11 @@ import { Interfaces } from "@arkecosystem/crypto";
44
@Container.injectable()
55
export class DposPreviousRoundState implements Contracts.State.DposPreviousRoundState {
66
@Container.inject(Container.Identifiers.BlockState)
7-
@Container.tagged("state", "temp")
7+
@Container.tagged("state", "clone")
88
private readonly blockState!: Contracts.State.BlockState;
99

1010
@Container.inject(Container.Identifiers.DposState)
11-
@Container.tagged("state", "temp")
11+
@Container.tagged("state", "clone")
1212
private readonly dposState!: Contracts.State.DposState;
1313

1414
public async revert(blocks: Interfaces.IBlock[], roundInfo: Contracts.Shared.RoundInfo): Promise<void> {

packages/core-state/src/service-provider.ts

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import { BlockStore } from "./stores/blocks";
88
import { StateStore } from "./stores/state";
99
import { TransactionStore } from "./stores/transactions";
1010
import { TransactionValidator } from "./transaction-validator";
11-
import { TempWalletRepository, Wallet, WalletRepository } from "./wallets";
11+
import { Wallet, WalletRepository, WalletRepositoryClone, WalletRepositoryCopyOnWrite } from "./wallets";
1212
import {
1313
addressesIndexer,
1414
ipfsIndexer,
@@ -42,9 +42,15 @@ export class ServiceProvider extends Providers.ServiceProvider {
4242

4343
this.app
4444
.bind(Container.Identifiers.WalletRepository)
45-
.to(TempWalletRepository)
45+
.to(WalletRepositoryClone)
4646
.inRequestScope()
47-
.when(Container.Selectors.anyAncestorOrTargetTaggedFirst("state", "temp"));
47+
.when(Container.Selectors.anyAncestorOrTargetTaggedFirst("state", "clone"));
48+
49+
this.app
50+
.bind(Container.Identifiers.WalletRepository)
51+
.to(WalletRepositoryCopyOnWrite)
52+
.inRequestScope()
53+
.when(Container.Selectors.anyAncestorOrTargetTaggedFirst("state", "copy-on-write"));
4854

4955
this.app.bind(Container.Identifiers.DposState).to(DposState);
5056
this.app.bind(Container.Identifiers.BlockState).to(BlockState);

packages/core-state/src/transaction-validator.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import { strictEqual } from "assert";
66
@Container.injectable()
77
export class TransactionValidator implements Contracts.State.TransactionValidator {
88
@Container.inject(Container.Identifiers.TransactionHandlerRegistry)
9-
@Container.tagged("state", "temp")
9+
@Container.tagged("state", "clone")
1010
private readonly handlerRegistry!: Handlers.Registry;
1111

1212
public async validate(transaction: Interfaces.ITransaction): Promise<void> {
Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1-
export * from "./temp-wallet-repository";
21
export * from "./wallet-repository";
2+
export * from "./wallet-repository-clone";
3+
export * from "./wallet-repository-copy-on-write";
34
export * from "./wallet";

packages/core-state/src/wallets/temp-wallet-repository.ts

Lines changed: 0 additions & 93 deletions
This file was deleted.
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import { Container, Contracts } from "@arkecosystem/core-kernel";
2+
3+
import { WalletRepository } from "./wallet-repository";
4+
5+
@Container.injectable()
6+
export class WalletRepositoryClone extends WalletRepository {
7+
@Container.inject(Container.Identifiers.WalletRepository)
8+
@Container.tagged("state", "blockchain")
9+
private readonly blockchainWalletRepository!: Contracts.State.WalletRepository;
10+
11+
@Container.postConstruct()
12+
public initialize(): void {
13+
for (const index of this.blockchainWalletRepository.getIndexNames()) {
14+
this.indexes[index] = this.blockchainWalletRepository.getIndex(index).clone();
15+
}
16+
}
17+
18+
public reindex(wallet: Contracts.State.Wallet): void {
19+
super.reindex(wallet.clone());
20+
}
21+
}
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
import { Container, Contracts } from "@arkecosystem/core-kernel";
2+
3+
import { WalletRepository } from "./wallet-repository";
4+
5+
// ! This isn't copy-on-write, but copy-on-read and with many asterisks.
6+
// ! It only covers current pool use-cases.
7+
// ! It should be replaced with proper implementation eventually.
8+
9+
@Container.injectable()
10+
export class WalletRepositoryCopyOnWrite extends WalletRepository {
11+
@Container.inject(Container.Identifiers.WalletRepository)
12+
@Container.tagged("state", "blockchain")
13+
private readonly blockchainWalletRepository!: Contracts.State.WalletRepository;
14+
15+
public findByAddress(address: string): Contracts.State.Wallet {
16+
if (address && !this.hasByAddress(address)) {
17+
const walletClone = this.blockchainWalletRepository.findByAddress(address).clone();
18+
this.reindex(walletClone);
19+
}
20+
return this.findByIndex(Contracts.State.WalletIndexes.Addresses, address)!;
21+
}
22+
23+
public hasByIndex(index: string, key: string): boolean {
24+
if (super.hasByIndex(index, key)) {
25+
return true;
26+
}
27+
if (this.blockchainWalletRepository.hasByIndex(index, key) === false) {
28+
return false;
29+
}
30+
const walletClone = this.blockchainWalletRepository.findByIndex(index, key).clone();
31+
this.reindex(walletClone);
32+
return true;
33+
}
34+
35+
public allByUsername(): ReadonlyArray<Contracts.State.Wallet> {
36+
for (const wallet of this.blockchainWalletRepository.allByUsername()) {
37+
if (super.hasByAddress(wallet.address) === false) {
38+
this.reindex(wallet.clone());
39+
}
40+
}
41+
return super.allByUsername();
42+
}
43+
}

packages/core-transaction-pool/src/connection.ts

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import { Container, Contracts, Enums as AppEnums, Providers, Utils as AppUtils } from "@arkecosystem/core-kernel";
2-
import { Wallets } from "@arkecosystem/core-state";
32
import { Handlers } from "@arkecosystem/core-transactions";
43
import { Enums, Interfaces, Transactions, Utils } from "@arkecosystem/crypto";
54
import { strictEqual } from "assert";
@@ -533,10 +532,7 @@ export class Connection implements Contracts.TransactionPool.Connection {
533532
* @returns {Promise<Interfaces.ITransaction[]>}
534533
* @memberof Connection
535534
*/
536-
private async validateTransactions(
537-
transactions: Interfaces.ITransaction[],
538-
walletRepository?: Wallets.TempWalletRepository,
539-
): Promise<Interfaces.ITransaction[]> {
535+
private async validateTransactions(transactions: Interfaces.ITransaction[]): Promise<Interfaces.ITransaction[]> {
540536
const validTransactions: Interfaces.ITransaction[] = [];
541537
const forgedIds: string[] = await this.cleaner.removeForgedTransactions(transactions);
542538

@@ -546,13 +542,11 @@ export class Connection implements Contracts.TransactionPool.Connection {
546542
(t, forgedId) => t.id === forgedId,
547543
);
548544

549-
if (walletRepository === undefined) {
550-
walletRepository = this.app.getTagged<Wallets.TempWalletRepository>(
551-
Container.Identifiers.WalletRepository,
552-
"state",
553-
"temp",
554-
);
555-
}
545+
const walletRepository = this.app.getTagged<Contracts.State.WalletRepository>(
546+
Container.Identifiers.WalletRepository,
547+
"state",
548+
"clone",
549+
);
556550

557551
for (const transaction of unforgedTransactions) {
558552
try {

0 commit comments

Comments
 (0)