Skip to content

Commit

Permalink
Wallet pool review (#94)
Browse files Browse the repository at this point in the history
* fixing linter issues and add github action

* moves tests to own folder and adds tests for wallet manager.withWallet

* some documentation and adding a counter for locks

* normalize token vs address on sui
  • Loading branch information
mat1asm authored Aug 29, 2023
1 parent f907b9c commit 1b71597
Show file tree
Hide file tree
Showing 26 changed files with 248 additions and 91 deletions.
1 change: 1 addition & 0 deletions .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ module.exports = {
env: {
browser: true,
es2021: true,
node: true
},
extends: ["eslint:recommended", "plugin:@typescript-eslint/recommended"],
overrides: [],
Expand Down
11 changes: 0 additions & 11 deletions .github/workflow/test.yml

This file was deleted.

23 changes: 23 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
name: Run tests
on:
push:
branches: ["main"]
pull_request:
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout repo
uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
node-version: 18
cache: "npm"
cache-dependency-path: |
./package-lock.json
- name: npm ci
run: npm ci
- name: typecheck
run: npm run build
- name: test
run: npm test
2 changes: 1 addition & 1 deletion examples/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion examples/rebalancing.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@ const options: WalletManagerOptions = {
enabled: true,
serve: true,
port: 9091,
}
},
failOnInvalidChain: true
};

const allChainWallets: WalletManagerConfig = {
Expand Down
66 changes: 33 additions & 33 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@xlabs-xyz/wallet-monitor",
"version": "0.2.14",
"version": "0.2.15",
"description": "A set of utilities to monitor blockchain wallets and react to them",
"main": "lib/index.js",
"types": "lib/index.d.ts",
Expand Down
2 changes: 1 addition & 1 deletion src/balances/evm/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ export async function pullEvmTokenBalance(
isNative: false,
rawBalance: balance.toString(),
}
};
}

export async function pullEvmNativeBalance(
provider: ethers.providers.JsonRpcProvider,
Expand Down
2 changes: 1 addition & 1 deletion src/balances/sui.ts
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ function buildEd25519KeyPair(key: Buffer): Ed25519Keypair {
}

function buildSuiKeyPairFromPrivateKey(privateKey: string): Secp256k1Keypair | Ed25519Keypair {
let parsedKey = Buffer.from(privateKey, 'base64');
const parsedKey = Buffer.from(privateKey, 'base64');

let key, buildKeyPair;
if (parsedKey.length === PRIVATE_KEY_SIZE+1) {
Expand Down
10 changes: 5 additions & 5 deletions src/chain-wallet-manager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ export class ChainWalletManager {
console.warn(`A monitoring run is already in progress for ${this.options.chainName}. Will skip run`);
this.emitter.emit('skipped', { chainName: this.options.chainName, rawConfig: this.wallets });
return;
};
}

this.locked = true;

Expand All @@ -158,7 +158,7 @@ export class ChainWalletManager {

return acc;
}, {} as WalletBalancesByAddress);
};
}

public on(event: string, listener: (...args: any[]) => void) {
this.emitter.on(event, listener);
Expand Down Expand Up @@ -190,15 +190,15 @@ export class ChainWalletManager {
}

public async acquireLock(opts?: WalletExecuteOptions) {
return this.walletToolbox.acquire(opts?.address, opts?.leaseTimeout)
return this.walletToolbox.acquire(opts?.address, opts?.waitToAcquireTimeout)
}

public async releaseLock(address: string) {
return this.walletToolbox.release(address)
}

// Returns a boolean indicating if a rebalance was executed
public async executeRebalanceIfNeeded(): Promise<Boolean> {
public async executeRebalanceIfNeeded(): Promise<boolean> {
if (this.rebalanceLocked) {
this.logger.warn(`A rebalance is already in progress for ${this.options.chainName}. Will skip rebalance`);
return false;
Expand Down Expand Up @@ -236,7 +236,7 @@ export class ChainWalletManager {
}

receipts.push(receipt);
};
}

await this.refreshBalances();

Expand Down
2 changes: 1 addition & 1 deletion src/grpc/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ export class ClientWalletManager implements IClientWalletManager {
const chainManager = this.managers[chainName];
if (!chainManager) throw new Error(`No wallets configured for chain: ${chainName}`);

const { address: acquiredAddress } = await this.walletManagerGRPCClient.acquireLock({chainName, address: opts?.address, leaseTimeout: opts?.leaseTimeout})
const { address: acquiredAddress } = await this.walletManagerGRPCClient.acquireLock({chainName, address: opts?.address, leaseTimeout: opts?.leaseTimeout, acquireTimeout: opts?.waitToAcquireTimeout })

// FIXME
// Dirty solution. We are doing as little work as possible to get the same expected WalletInterface after
Expand Down
2 changes: 1 addition & 1 deletion src/grpc/proto/wallet-manager-grpc-service.proto
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ service WalletManagerGRPCService {
message AcquireLockRequest {
string chain_name = 1;
optional string address = 2;
// FIXME: We are missing waitToAcquireTimeout.
optional uint64 lease_timeout = 3;
optional uint64 acquire_timeout = 4;
}
message AcquireLockResponse {
string address = 1;
Expand Down
5 changes: 4 additions & 1 deletion src/grpc/service-impl.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,10 @@ export class WalletManagerGRPCService implements WalletManagerGRPCServiceImpleme
constructor(private underlyingWalletManager: IServiceWalletManager) {}

async acquireLock(request: AcquireLockRequest, context: CallContext): Promise<DeepPartial<AcquireLockResponse>> {
const acquiredWallet = await this.underlyingWalletManager.acquireLock(request.chainName as ChainName, {address: request.address, leaseTimeout: request.leaseTimeout})
const acquiredWallet = await this.underlyingWalletManager.acquireLock(
request.chainName as ChainName,
{ address: request.address, leaseTimeout: request.leaseTimeout, waitToAcquireTimeout: request.acquireTimeout }
);

return {address: acquiredWallet.address};
}
Expand Down
2 changes: 1 addition & 1 deletion src/grpc/service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ const walletManager = new WalletManager(fileConfig.config, fileConfig.options)

const walletManagerGRPCService = new WalletManagerGRPCService(walletManager);

const server = createServer();
const server = createServer(); // TODO: add observability for the GRPC server
server.add(WalletManagerGRPCServiceDefinition, walletManagerGRPCService);
server.listen(fileConfig.grpc.listenAddress + ':' + fileConfig.grpc.listenPort);

Expand Down
6 changes: 3 additions & 3 deletions src/i-wallet-manager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,6 @@ interface IWMBareLocks {
releaseLock(chainName: ChainName, address: string): Promise<void>
}

export interface ILibraryWalletManager extends IWMContextManagedLocks {}
export interface IClientWalletManager extends IWMContextManagedLocks {}
export interface IServiceWalletManager extends IWMBareLocks {}
export type ILibraryWalletManager = IWMContextManagedLocks
export type IClientWalletManager = IWMContextManagedLocks
export type IServiceWalletManager = IWMBareLocks
20 changes: 20 additions & 0 deletions src/prometheus-exporter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,15 @@ function createRebalanceTransactionsCounter (registry: Registry, name: string) {
});
}

function createCounter(registry: Registry, name: string, help: string, labels: string[]) {
return new Counter({
name,
help,
labelNames: labels,
registers: [registry],
});
}

export function createBalancesGauge(registry: Registry, gaugeName: string) {
return new Gauge({
name: gaugeName,
Expand Down Expand Up @@ -87,6 +96,8 @@ export class PrometheusExporter {
private rebalanceExpenditureCounter: Counter;
private rebalanceInstructionsCounter: Counter;
private rebalanceTransactionsCounter: Counter;
private locksAcquiredCounter: Counter;


private prometheusPort: number;
private prometheusPath: string;
Expand All @@ -102,6 +113,7 @@ export class PrometheusExporter {
this.rebalanceExpenditureCounter = createRebalanceExpenditureCounter(this.registry, 'wallet_monitor_rebalance_expenditure');
this.rebalanceInstructionsCounter = createRebalanceInstructionsCounter(this.registry, 'wallet_monitor_rebalance_instruction');
this.rebalanceTransactionsCounter = createRebalanceTransactionsCounter(this.registry, 'wallet_monitor_rebalance_transaction');
this.locksAcquiredCounter = createCounter(this.registry, "locks_acquired_total", "Total number of acquired locks", ['chain_name', 'status']);
}

public getRegistry() {
Expand Down Expand Up @@ -135,6 +147,14 @@ export class PrometheusExporter {
this.rebalanceExpenditureCounter.labels(chainName, strategy).inc(totalExpenditure);
}

public increaseAcquiredLocks(chainName: string) {
this.locksAcquiredCounter.labels(chainName, "success").inc();
}

public increaseAcquireLockFailure(chainName: string) {
this.locksAcquiredCounter.labels(chainName, "failed").inc();
}

public async startMetricsServer(): Promise<void> {
this.app = await startMetricsServer(this.prometheusPort, this.prometheusPath, async () => {
const metrics = await this.metrics()
Expand Down
Loading

0 comments on commit 1b71597

Please sign in to comment.