From ae41fb24568eb14172dcffa64a5b4719fa7800ea Mon Sep 17 00:00:00 2001 From: Gabriel Martinez Rodriguez Date: Wed, 4 Dec 2024 11:17:43 +0100 Subject: [PATCH 1/5] feat(txm): use address instead of id to find transaction inside txm --- .../Factories/CommitmentTransactionFactory.ts | 11 +++++------ .../Factories/RevealValueTransactionFactory.ts | 11 +++++------ packages/randomness-service/src/index.ts | 16 +++++++--------- packages/transaction-manager/lib/Transaction.ts | 11 +++++++---- .../lib/TransactionManager.ts | 14 +++++++++----- packages/transaction-manager/lib/db/types.ts | 1 + .../migrations/Migration20241205104400.js | 3 +++ 7 files changed, 37 insertions(+), 30 deletions(-) create mode 100644 packages/transaction-manager/migrations/Migration20241205104400.js diff --git a/packages/randomness-service/src/Factories/CommitmentTransactionFactory.ts b/packages/randomness-service/src/Factories/CommitmentTransactionFactory.ts index 34b02fec98..2508c9092b 100644 --- a/packages/randomness-service/src/Factories/CommitmentTransactionFactory.ts +++ b/packages/randomness-service/src/Factories/CommitmentTransactionFactory.ts @@ -1,20 +1,19 @@ -import { Transaction } from "@happychain/transaction-manager" +import type { Transaction, TransactionManager } from "@happychain/transaction-manager" import type { Address, Hex } from "viem" export class CommitmentTransactionFactory { - private readonly chainId: number + private readonly transactionManager: TransactionManager private readonly randomContractAddress: Address private readonly precommitDelay: bigint - constructor(chainId: number, randomContractAddress: Address, precommitDelay: bigint) { - this.chainId = chainId + constructor(transactionManager: TransactionManager, randomContractAddress: Address, precommitDelay: bigint) { + this.transactionManager = transactionManager this.randomContractAddress = randomContractAddress this.precommitDelay = precommitDelay } create(timestamp: bigint, commitment: Hex): Transaction { - return new Transaction({ - chainId: this.chainId, + return this.transactionManager.createTransaction({ address: this.randomContractAddress, functionName: "postCommitment", contractName: "Random", diff --git a/packages/randomness-service/src/Factories/RevealValueTransactionFactory.ts b/packages/randomness-service/src/Factories/RevealValueTransactionFactory.ts index fa3965a0d0..20f1541695 100644 --- a/packages/randomness-service/src/Factories/RevealValueTransactionFactory.ts +++ b/packages/randomness-service/src/Factories/RevealValueTransactionFactory.ts @@ -1,18 +1,17 @@ -import { Transaction } from "@happychain/transaction-manager" +import type { Transaction, TransactionManager } from "@happychain/transaction-manager" import type { Address } from "viem" export class RevealValueTransactionFactory { - private readonly chainId: number + private readonly transactionManager: TransactionManager private readonly randomContractAddress: Address - constructor(chainId: number, randomContractAddress: Address) { - this.chainId = chainId + constructor(transactionManager: TransactionManager, randomContractAddress: Address) { + this.transactionManager = transactionManager this.randomContractAddress = randomContractAddress } create(timestamp: bigint, revealedValue: bigint): Transaction { - return new Transaction({ - chainId: this.chainId, + return this.transactionManager.createTransaction({ address: this.randomContractAddress, functionName: "revealValue", contractName: "Random", diff --git a/packages/randomness-service/src/index.ts b/packages/randomness-service/src/index.ts index af0d950d02..497fc717f8 100644 --- a/packages/randomness-service/src/index.ts +++ b/packages/randomness-service/src/index.ts @@ -17,21 +17,19 @@ class RandomnessService { private readonly revealValueTransactionFactory: RevealValueTransactionFactory constructor() { this.commitmentManager = new CommitmentManager() - this.commitmentTransactionFactory = new CommitmentTransactionFactory( - anvil.id, - env.RANDOM_CONTRACT_ADDRESS, - env.PRECOMMIT_DELAY, - ) - this.revealValueTransactionFactory = new RevealValueTransactionFactory(anvil.id, env.RANDOM_CONTRACT_ADDRESS) this.txm = new TransactionManager({ account: privateKeyToAccount(env.PRIVATE_KEY), transport: webSocket(), chain: anvil, - id: "randomness-service", abis: abis, gasEstimator: new CustomGasEstimator(), }) - + this.commitmentTransactionFactory = new CommitmentTransactionFactory( + this.txm, + env.RANDOM_CONTRACT_ADDRESS, + env.PRECOMMIT_DELAY, + ) + this.revealValueTransactionFactory = new RevealValueTransactionFactory(this.txm, env.RANDOM_CONTRACT_ADDRESS) this.txm.start() this.txm.addTransactionOriginator(this.onCollectTransactions.bind(this)) } @@ -39,7 +37,7 @@ class RandomnessService { private async onCollectTransactions(block: LatestBlock): Promise { const transactions: Transaction[] = [] - // We try to commit the ramdomness POST_COMMIT_MARGIN to be safe that the transaction is included before the PRECOMMIT_DELAY + // We try to commit the randomness POST_COMMIT_MARGIN to be safe that the transaction is included before the PRECOMMIT_DELAY const commitmentTimestamp = block.timestamp + env.PRECOMMIT_DELAY + env.POST_COMMIT_MARGIN const commitment = this.commitmentManager.generateCommitment() diff --git a/packages/transaction-manager/lib/Transaction.ts b/packages/transaction-manager/lib/Transaction.ts index 3203bbc0e3..015a552d08 100644 --- a/packages/transaction-manager/lib/Transaction.ts +++ b/packages/transaction-manager/lib/Transaction.ts @@ -49,10 +49,6 @@ export interface Attempt { export const NotFinalizedStatuses = [TransactionStatus.Pending, TransactionStatus.Cancelling] export interface TransactionConstructorConfig { - /** - * The chain ID where the transaction will be sent - */ - chainId: number /** * The address of the contract that will be called */ @@ -84,6 +80,8 @@ export interface TransactionConstructorConfig { export class Transaction { readonly intentId: UUID + readonly from: Address + readonly chainId: number readonly address: Address @@ -113,6 +111,7 @@ export class Transaction { constructor({ intentId, + from, chainId, address, functionName, @@ -125,6 +124,8 @@ export class Transaction { updatedAt, metadata, }: TransactionConstructorConfig & { + from: Address + chainId: number intentId?: UUID status?: TransactionStatus attempts?: Attempt[] @@ -132,6 +133,7 @@ export class Transaction { updatedAt?: Date }) { this.intentId = intentId ?? createUUID() + this.from = from this.chainId = chainId this.address = address this.functionName = functionName @@ -187,6 +189,7 @@ export class Transaction { toDbRow(): Insertable { return { intentId: this.intentId, + from: this.from, chainId: this.chainId, address: this.address, functionName: this.functionName, diff --git a/packages/transaction-manager/lib/TransactionManager.ts b/packages/transaction-manager/lib/TransactionManager.ts index af5887e717..3259bb8c1c 100644 --- a/packages/transaction-manager/lib/TransactionManager.ts +++ b/packages/transaction-manager/lib/TransactionManager.ts @@ -12,7 +12,7 @@ import { DefaultGasLimitEstimator, type GasEstimator } from "./GasEstimator.js" import { GasPriceOracle } from "./GasPriceOracle.js" import { HookManager, type TxmHookHandler, type TxmHookType } from "./HookManager.js" import { NonceManager } from "./NonceManager.js" -import type { Transaction } from "./Transaction.js" +import { Transaction, type TransactionConstructorConfig } from "./Transaction.js" import { TransactionCollector } from "./TransactionCollector.js" import { TransactionRepository } from "./TransactionRepository.js" import { TransactionSubmitter } from "./TransactionSubmitter.js" @@ -26,8 +26,6 @@ export type TransactionManagerConfig = { account: Account /** The blockchain network configuration. See {@link Chain} from viem for more details. */ chain: Chain - /** A unique identifier for this TransactionManager instance. */ - id: string /** Optional EIP-1559 parameters. If not provided, defaults to the OP stack's stock parameters. */ eip1559?: EIP1559Parameters /** @@ -107,7 +105,6 @@ export class TransactionManager { public readonly transactionSubmitter: TransactionSubmitter public readonly hookManager: HookManager - public readonly id: string public readonly eip1559: EIP1559Parameters public readonly baseFeeMargin: bigint public readonly maxPriorityFeePerGas: bigint @@ -142,7 +139,6 @@ export class TransactionManager { this.transactionSubmitter = new TransactionSubmitter(this) this.hookManager = new HookManager() - this.id = _config.id this.eip1559 = _config.eip1559 || opStackDefaultEIP1559Parameters this.abiManager = new ABIManager(_config.abis) @@ -177,6 +173,14 @@ export class TransactionManager { return this.transactionRepository.getTransaction(txIntentId) } + public createTransaction(params: TransactionConstructorConfig): Transaction { + return new Transaction({ + ...params, + from: this.viemWallet.account.address, + chainId: this.viemWallet.chain.id, + }) + } + public async start(): Promise { // Start the gas price oracle to prevent other parts of the application from calling `suggestGasForNextBlock` before the gas price oracle has initialized the gas price after processing the first block const priceOraclePromise = this.gasPriceOracle.start() diff --git a/packages/transaction-manager/lib/db/types.ts b/packages/transaction-manager/lib/db/types.ts index e5b71b1589..5c485d2227 100644 --- a/packages/transaction-manager/lib/db/types.ts +++ b/packages/transaction-manager/lib/db/types.ts @@ -4,6 +4,7 @@ import type { TransactionStatus } from "../Transaction" export interface TransactionTable { intentId: UUID + from: Address chainId: number address: Address functionName: string diff --git a/packages/transaction-manager/migrations/Migration20241205104400.js b/packages/transaction-manager/migrations/Migration20241205104400.js new file mode 100644 index 0000000000..1a176c23ac --- /dev/null +++ b/packages/transaction-manager/migrations/Migration20241205104400.js @@ -0,0 +1,3 @@ +export async function up(db) { + await db.schema.alterTable("transaction").addColumn("from", "text", (col) => col.notNull()).execute() +} From 8f6ee1f7e3dbcc8d66921eb3171424ae7543eafb Mon Sep 17 00:00:00 2001 From: Gabriel Martinez Rodriguez Date: Wed, 4 Dec 2024 11:23:54 +0100 Subject: [PATCH 2/5] chore(txm): format --- .../migrations/Migration20241205104400.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/packages/transaction-manager/migrations/Migration20241205104400.js b/packages/transaction-manager/migrations/Migration20241205104400.js index 1a176c23ac..d40dadef5f 100644 --- a/packages/transaction-manager/migrations/Migration20241205104400.js +++ b/packages/transaction-manager/migrations/Migration20241205104400.js @@ -1,3 +1,6 @@ export async function up(db) { - await db.schema.alterTable("transaction").addColumn("from", "text", (col) => col.notNull()).execute() + await db.schema + .alterTable("transaction") + .addColumn("from", "text", (col) => col.notNull()) + .execute() } From 4dda50b5df450f61c2672fe50ea40a216f9ac39a Mon Sep 17 00:00:00 2001 From: Gabriel Martinez Rodriguez Date: Wed, 4 Dec 2024 11:39:26 +0100 Subject: [PATCH 3/5] feat(txm): get only transactions from db that contains the same from --- packages/transaction-manager/lib/TransactionRepository.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/transaction-manager/lib/TransactionRepository.ts b/packages/transaction-manager/lib/TransactionRepository.ts index 334dc5b0b7..121faef658 100644 --- a/packages/transaction-manager/lib/TransactionRepository.ts +++ b/packages/transaction-manager/lib/TransactionRepository.ts @@ -26,6 +26,7 @@ export class TransactionRepository { const transactionRows = await db .selectFrom("transaction") .where("status", "in", NotFinalizedStatuses) + .where("from", "=", this.transactionManager.viemWallet.account.address) .selectAll() .execute() From 2cd5e723cab8af804c33c2defb320b174bc8ab98 Mon Sep 17 00:00:00 2001 From: Gabriel Martinez Rodriguez Date: Wed, 4 Dec 2024 11:44:34 +0100 Subject: [PATCH 4/5] feat(txm): only purge transacion that are using same from --- packages/transaction-manager/lib/TransactionRepository.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/transaction-manager/lib/TransactionRepository.ts b/packages/transaction-manager/lib/TransactionRepository.ts index 121faef658..8f9e5bbc10 100644 --- a/packages/transaction-manager/lib/TransactionRepository.ts +++ b/packages/transaction-manager/lib/TransactionRepository.ts @@ -51,6 +51,7 @@ export class TransactionRepository { const persistedTransaction = await db .selectFrom("transaction") .where("intentId", "=", intentId) + .where("from", "=", this.transactionManager.viemWallet.account.address) .selectAll() .executeTakeFirst() @@ -132,6 +133,7 @@ export class TransactionRepository { .deleteFrom("transaction") .where("status", "not in", NotFinalizedStatuses) .where("updatedAt", "<", Date.now() - this.transactionManager.finalizedTransactionPurgeTime) + .where("from", "=", this.transactionManager.viemWallet.account.address) .execute() } } From 4f82a92c2a7ece3330a6f6e00c8df2c4ea23516b Mon Sep 17 00:00:00 2001 From: Gabriel Martinez Rodriguez Date: Wed, 4 Dec 2024 12:09:35 +0100 Subject: [PATCH 5/5] chore(txm): added comment --- packages/transaction-manager/lib/TransactionManager.ts | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/packages/transaction-manager/lib/TransactionManager.ts b/packages/transaction-manager/lib/TransactionManager.ts index 3259bb8c1c..c6faa22735 100644 --- a/packages/transaction-manager/lib/TransactionManager.ts +++ b/packages/transaction-manager/lib/TransactionManager.ts @@ -173,6 +173,11 @@ export class TransactionManager { return this.transactionRepository.getTransaction(txIntentId) } + /** + * Creates a new transaction. + * @param params - {@link TransactionConstructorConfig}. + * @returns A new transaction. + */ public createTransaction(params: TransactionConstructorConfig): Transaction { return new Transaction({ ...params,