Skip to content

Commit

Permalink
Merge pull request #94 from usherlabs/feature/add-tx-overrides
Browse files Browse the repository at this point in the history
Improve initial gas fees incentives handling
  • Loading branch information
rsoury authored Nov 17, 2023
2 parents 124bfee + 0d7173d commit ede8b1d
Show file tree
Hide file tree
Showing 17 changed files with 184 additions and 44 deletions.
2 changes: 1 addition & 1 deletion packages/cli/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@logsn/cli",
"version": "0.0.4",
"version": "0.0.5",
"author": "Ryan Soury <[email protected]>",
"license": "GPL-3.0",
"description": "The Log Store Network CLI",
Expand Down
1 change: 0 additions & 1 deletion packages/cli/src/commands/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ export const rootProgram = new Command()
.version(appVersion)
.option('-h, --host <string>', 'Polygon/EVM Node RPC Endpoint')
.option('-w, --wallet <string>', 'Wallet private key')
.option('--gas-tip <number>', 'Initial gas tip to use for transactions')
.option(
'-c, --config <string>',
'Path to configuration file. Defaults to ~/.logstore-cli/default.json',
Expand Down
6 changes: 5 additions & 1 deletion packages/cli/src/commands/mint.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { getRootOptions } from '@/commands/options';
import { fastPriorityIfMainNet$ } from '@/utils/gasStation';
import {
getCredentialsFromOptions,
getLogStoreClientFromOptions,
Expand Down Expand Up @@ -60,7 +61,10 @@ export const mintCommand = new Command()

console.log(`Minting ${amountInToken} wei...`);
const result = await client.mint(
BigInt(new Decimal(amountInToken).toHex())
BigInt(new Decimal(amountInToken).toHex()),
{
maxPriorityFeePerGas: await firstValueFrom(fastPriorityIfMainNet$),
}
);

console.log(
Expand Down
10 changes: 8 additions & 2 deletions packages/cli/src/commands/query/query-stake.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { getRootOptions } from '@/commands/options';
import { fastPriorityIfMainNet$ } from '@/utils/gasStation';
import {
getCredentialsFromOptions,
getLogStoreClientFromOptions,
Expand Down Expand Up @@ -66,7 +67,10 @@ const stakeCommand = new Command()
Manager.QueryManager,
BigInt(hexValue),
signer,
!cmdOptions.assumeYes ? allowanceConfirm : undefined
!cmdOptions.assumeYes ? allowanceConfirm : undefined,
{
maxPriorityFeePerGas: await firstValueFrom(fastPriorityIfMainNet$),
}
);

if (allowanceTx) {
Expand All @@ -85,7 +89,9 @@ const stakeCommand = new Command()
const queryManagerContract = await getQueryManagerContract(signer);
console.info(`Staking ${amountToStakeInLSAN} LSAN...`);

const tx = await queryManagerContract.stake(hexValue);
const tx = await queryManagerContract.stake(hexValue, {
maxPriorityFeePerGas: await firstValueFrom(fastPriorityIfMainNet$),
});

const receipt = await firstValueFrom(
keepRetryingWithIncreasedGasPrice(signer, tx)
Expand Down
6 changes: 5 additions & 1 deletion packages/cli/src/commands/store/store-stake.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { fastPriorityIfMainNet$ } from '@/utils/gasStation';
import {
getCredentialsFromOptions,
getLogStoreClientFromOptions,
Expand Down Expand Up @@ -65,7 +66,10 @@ const stakeCommand = new Command()
Manager.StoreManager,
BigInt(hexValue),
signer,
!cmdOptions.assumeYes ? allowanceConfirm : undefined
!cmdOptions.assumeYes ? allowanceConfirm : undefined,
{
maxPriorityFeePerGas: await firstValueFrom(fastPriorityIfMainNet$),
}
);

if (allowanceTx) {
Expand Down
43 changes: 43 additions & 0 deletions packages/cli/src/utils/gasStation.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import { isDevNetwork$ } from '@/utils/observableUtils';
import { ethers } from 'ethers';
import { catchError, defer, map, of, share, switchMap, throwError } from 'rxjs';

type GasStationResponse = {
safeLow: {
maxPriorityFee: number;
maxFee: number;
};
standard: {
maxPriorityFee: number;
maxFee: number;
};
fast: {
maxPriorityFee: number;
maxFee: number;
};
estimatedBaseFee: number;
blockTime: number;
blockNumber: number;
};
const gasStationFees$ = defer(() =>
fetch('https://gasstation.polygon.technology/v2').then(
(response) => response.json() as Promise<GasStationResponse>
)
).pipe(
catchError((err) => {
console.log('error fetching gas station fees: ', err);
return throwError(() => err);
})
);
const mapGweiToBN = (gwei: number) =>
ethers.utils.parseUnits(gwei.toString(), 'gwei');

const fastPriorityFee$ = gasStationFees$.pipe(
map((gasStationResponse) => gasStationResponse.fast.maxPriorityFee),
map(mapGweiToBN),
share()
);

export const fastPriorityIfMainNet$ = isDevNetwork$.pipe(
switchMap((isDevNet) => (isDevNet ? of(undefined) : fastPriorityFee$))
);
11 changes: 11 additions & 0 deletions packages/cli/src/utils/observableUtils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { getRootOptions } from '@/commands/options';
import { getCredentialsFromOptions } from '@/utils/logstore-client';
import { defer, map } from 'rxjs';

export const rootOptions$ = defer(async () => getRootOptions());
export const credentials$ = defer(async () => getCredentialsFromOptions());

export const isDevNetwork$ = credentials$.pipe(
// enough to validate?
map(({ provider }) => provider.connection.url.includes('localhost'))
);
2 changes: 1 addition & 1 deletion packages/cli/src/utils/speedupTx.ts
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ export const keepRetryingWithIncreasedGasPrice = (
const newTransaction = await createTransactionWithIncreasedTip(
signer,
oldTransaction,
3 // 3x
1.2
);
console.log('');
console.log('Replacing transaction with increased gas price');
Expand Down
2 changes: 1 addition & 1 deletion packages/client/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@logsn/client",
"version": "0.0.6",
"version": "0.0.8",
"description": "The Log Store Network Client",
"author": "Ryan Soury <[email protected]>, Victor Shevtsov <[email protected]>",
"license": "Apache-2.0",
Expand Down
41 changes: 31 additions & 10 deletions packages/client/src/LogStoreClient.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import type { Overrides } from '@ethersproject/contracts';
import type {
MessageListener,
Stream,
Expand All @@ -19,7 +20,13 @@ import {
import { LogStoreClientEventEmitter, LogStoreClientEvents } from './events';
import { LogStoreClientConfig } from './LogStoreClientConfig';
import { LogStoreMessageStream } from './LogStoreMessageStream';
import { HttpApiQueryDict, Queries, QueryInput, QueryType } from './Queries';
import {
HttpApiQueryDict,
Queries,
QueryInput,
type QueryOptions,
QueryType,
} from './Queries';
import { LogStoreRegistry } from './registry/LogStoreRegistry';
import { QueryManager } from './registry/QueryManager';
import { TokenManager } from './registry/TokenManager';
Expand Down Expand Up @@ -109,8 +116,16 @@ export class LogStoreClient extends StreamrClient {
/**
* Stake funds so can query
*/
async queryStake(amount: bigint, options = { usd: false }) {
return this.logStoreQueryManager.queryStake(amount, { usd: options.usd });
async queryStake(
amount: bigint,
options = { usd: false },
overrides?: Overrides
) {
return this.logStoreQueryManager.queryStake(
amount,
{ usd: options.usd },
overrides
);
}

/**
Expand All @@ -128,9 +143,7 @@ export class LogStoreClient extends StreamrClient {
streamDefinition: StreamDefinition,
input: QueryInput,
onMessage?: MessageListener,
options?: {
verifyNetworkResponses?: boolean;
}
options?: QueryOptions
): Promise<LogStoreMessageStream> {
const streamPartId = await this.streamIdBuilder.toStreamPartID(
streamDefinition
Expand Down Expand Up @@ -183,9 +196,14 @@ export class LogStoreClient extends StreamrClient {
*/
async stakeOrCreateStore(
streamIdOrPath: string,
amount: bigint
amount: bigint,
overrides?: Overrides
): Promise<ContractTransaction> {
return this.logStoreRegistry.stakeOrCreateStore(streamIdOrPath, amount);
return this.logStoreRegistry.stakeOrCreateStore(
streamIdOrPath,
amount,
overrides
);
}

/**
Expand Down Expand Up @@ -223,8 +241,11 @@ export class LogStoreClient extends StreamrClient {
return this.logstoreTokenManager.getBalance();
}

async mint(weiAmountToMint: bigint): Promise<ContractTransaction> {
return this.logstoreTokenManager.mint(weiAmountToMint);
async mint(
weiAmountToMint: bigint,
overrides?: Overrides
): Promise<ContractTransaction> {
return this.logstoreTokenManager.mint(weiAmountToMint, overrides);
}

async getPrice(): Promise<bigint> {
Expand Down
13 changes: 10 additions & 3 deletions packages/client/src/Queries.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,10 @@ import { LogStoreClientConfigInjectionToken } from './Config';
import { HttpUtil } from './HttpUtil';
import { LogStoreMessageStream } from './LogStoreMessageStream';
import { NodeManager } from './registry/NodeManager';
import { validateWithNetworkResponses } from './utils/networkValidation/validateNetworkResponses';
import {
validateWithNetworkResponses,
type VerificationOptions,
} from './utils/networkValidation/validateNetworkResponses';
import { SystemMessageObservable } from './utils/SystemMessageObservable';
import { LogStoreClientSystemMessagesInjectionToken } from './utils/systemStreamUtils';
import { counterId } from './utils/utils';
Expand Down Expand Up @@ -132,7 +135,7 @@ function isQueryRange<T extends QueryRangeOptions>(options: any): options is T {
}

export type QueryOptions = {
verifyNetworkResponses?: boolean;
verifyNetworkResponses?: VerificationOptions | boolean;
};

@scoped(Lifecycle.ContainerScoped)
Expand Down Expand Up @@ -248,7 +251,7 @@ export class Queries implements IResends {
...query,
// we will get raw request to desserialize and decrypt
format: 'raw',
verifyNetworkResponses: options?.verifyNetworkResponses,
verifyNetworkResponses: !!options?.verifyNetworkResponses,
});
const messageStream = createSubscribePipeline({
streamPartId,
Expand Down Expand Up @@ -303,6 +306,10 @@ export class Queries implements IResends {
nodeManager: this.nodeManager,
logger: this.logger,
queryUrl: nodeUrl,
verificationOptions:
typeof options.verifyNetworkResponses === 'object'
? options.verifyNetworkResponses
: undefined,
});
}

Expand Down
13 changes: 7 additions & 6 deletions packages/client/src/registry/LogStoreRegistry.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { BigNumber } from '@ethersproject/bignumber';
import type { Overrides } from '@ethersproject/contracts';
import { Provider } from '@ethersproject/providers';
import type { LogStoreManager as LogStoreManagerContract } from '@logsn/contracts';
import { abi as LogStoreManagerAbi } from '@logsn/contracts/artifacts/src/StoreManager.sol/LogStoreManager.json';
Expand Down Expand Up @@ -173,7 +174,8 @@ export class LogStoreRegistry {

async stakeOrCreateStore(
streamIdOrPath: string,
amount: bigint
amount: bigint,
overrides?: Overrides
): Promise<ContractTransaction> {
const streamId = await this.streamIdBuilder.toStreamID(streamIdOrPath);
this.logger.debug('adding stream %s to LogStore', streamId);
Expand All @@ -185,11 +187,10 @@ export class LogStoreRegistry {
await this.authentication.getStreamRegistryChainSigner();
await prepareStakeForStoreManager(chainSigner, amount, false);
const ethersOverrides = getStreamRegistryOverrides(this.clientConfig);
return this.logStoreManagerContract!.stake(
streamId,
amount,
ethersOverrides
);
return this.logStoreManagerContract!.stake(streamId, amount, {
...ethersOverrides,
...overrides,
});
}

async getStreamBalance(streamIdOrPath: string): Promise<bigint> {
Expand Down
10 changes: 7 additions & 3 deletions packages/client/src/registry/QueryManager.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { BigNumberish } from '@ethersproject/bignumber';
import { ContractReceipt } from '@ethersproject/contracts';
import { ContractReceipt, type Overrides } from '@ethersproject/contracts';
import { Provider } from '@ethersproject/providers';
import { LogStoreQueryManager as QueryManagerContract } from '@logsn/contracts';
import { abi as QueryManagerAbi } from '@logsn/contracts/artifacts/src/QueryManager.sol/LogStoreQueryManager.json';
Expand Down Expand Up @@ -99,7 +99,8 @@ export class QueryManager {

async queryStake(
amount: BigNumberish,
options = { usd: false }
options = { usd: false },
overrides?: Overrides
): Promise<ContractReceipt> {
this.logger.debug(
`Staking ${amount} with options: ${JSON.stringify(options)}...`
Expand All @@ -118,7 +119,10 @@ export class QueryManager {

const ethersOverrides = getStreamRegistryOverrides(this.clientConfig);
return waitForTx(
this.queryManagerContract!.stake(stakeAmount, ethersOverrides)
this.queryManagerContract!.stake(stakeAmount, {
...ethersOverrides,
...overrides,
})
);
}
}
11 changes: 9 additions & 2 deletions packages/client/src/registry/TokenManager.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { BigNumberish } from '@ethersproject/bignumber';
import type { Overrides } from '@ethersproject/contracts';
import { Provider } from '@ethersproject/providers';
import { LSAN as LogStoreTokenManagerContract } from '@logsn/contracts';
import { abi as LogStoreTokenManagerAbi } from '@logsn/contracts/artifacts/src/alpha/Token.sol/LSAN.json';
Expand Down Expand Up @@ -100,10 +101,16 @@ export class TokenManager {
}, this.logstoreTokenManagerContractsReadonly);
}

public async mint(amount: BigNumberish): Promise<ContractTransaction> {
public async mint(
amount: BigNumberish,
overrides?: Overrides
): Promise<ContractTransaction> {
this.logger.debug('mint amount: ' + amount);
await this.connectToContract();
return this.logStoreTokenManagerContract!.mint({ value: amount });
return this.logStoreTokenManagerContract!.mint({
value: amount,
...overrides,
});
}

/**
Expand Down
Loading

0 comments on commit ede8b1d

Please sign in to comment.