From d75cc3c023902166fdfccd8573411ea03c3c5d04 Mon Sep 17 00:00:00 2001 From: Richard Moore Date: Sun, 27 Nov 2022 21:52:21 -0500 Subject: [PATCH] Moved to assert instead of throw helpers. --- src.ts/transaction/accesslist.ts | 17 +-- src.ts/transaction/transaction.ts | 237 ++++++++++++------------------ 2 files changed, 104 insertions(+), 150 deletions(-) diff --git a/src.ts/transaction/accesslist.ts b/src.ts/transaction/accesslist.ts index 4d68d389f..328dbc58e 100644 --- a/src.ts/transaction/accesslist.ts +++ b/src.ts/transaction/accesslist.ts @@ -1,5 +1,5 @@ import { getAddress } from "../address/index.js"; -import { dataLength } from "../utils/index.js"; +import { assertArgument, isHexString } from "../utils/index.js"; import type { AccessList, AccessListish } from "./index.js"; @@ -7,11 +7,8 @@ import type { AccessList, AccessListish } from "./index.js"; function accessSetify(addr: string, storageKeys: Array): { address: string,storageKeys: Array } { return { address: getAddress(addr), - storageKeys: (storageKeys || []).map((storageKey, index) => { - if (dataLength(storageKey) !== 32) { - //logger.throwArgumentError("invalid access list storageKey", `accessList[${ addr }> - throw new Error(""); - } + storageKeys: storageKeys.map((storageKey, index) => { + assertArgument(isHexString(storageKey, 32), "invalid slot", `storageKeys[${ index }]`, storageKey); return storageKey.toLowerCase(); }) }; @@ -21,16 +18,16 @@ export function accessListify(value: AccessListish): AccessList { if (Array.isArray(value)) { return (] | { address: string, storageKeys: Array}>>value).map((set, index) => { if (Array.isArray(set)) { - if (set.length > 2) { - //logger.throwArgumentError("access list expected to be [ address, storageKeys[> - throw new Error(""); - } + assertArgument(set.length === 2, "invalid slot set", `value[${ index }]`, set); return accessSetify(set[0], set[1]) } + assertArgument(set != null && typeof(set) === "object", "invalid address-slot set", "value", value); return accessSetify(set.address, set.storageKeys); }); } + assertArgument(value != null && typeof(value) === "object", "invalid access list", "value", value); + const result: Array<{ address: string, storageKeys: Array }> = Object.keys(value).map((addr) => { const storageKeys: Record = value[addr].reduce((accum, storageKey) => { accum[storageKey] = true; diff --git a/src.ts/transaction/transaction.ts b/src.ts/transaction/transaction.ts index 0bc0702ce..52e40cb38 100644 --- a/src.ts/transaction/transaction.ts +++ b/src.ts/transaction/transaction.ts @@ -1,15 +1,15 @@ import { getAddress } from "../address/index.js"; -import { keccak256, Signature } from "../crypto/index.js"; +import { keccak256, Signature, SigningKey } from "../crypto/index.js"; import { - concat, decodeRlp, encodeRlp, getBytes, getStore, getBigInt, getNumber, hexlify, - setStore, assertArgument, toArray, zeroPadValue + concat, decodeRlp, encodeRlp, getBytes, getBigInt, getNumber, hexlify, + assert, assertArgument, toArray, zeroPadValue } from "../utils/index.js"; import { accessListify } from "./accesslist.js"; import { recoverAddress } from "./address.js"; -import type { BigNumberish, BytesLike, Freezable, Frozen } from "../utils/index.js"; +import type { BigNumberish, BytesLike } from "../utils/index.js"; import type { SignatureLike } from "../crypto/index.js"; import type { AccessList, AccessListish } from "./index.js"; @@ -52,19 +52,11 @@ function handleAddress(value: string): null | string { return getAddress(value); } -function handleData(value: string, param: string): string { - try { - return hexlify(value); - } catch (error) { - assertArgument(false, "invalid data", param, value); - } -} - function handleAccessList(value: any, param: string): AccessList { try { return accessListify(value); - } catch (error) { - assertArgument(false, "invalid accessList", param, value); + } catch (error: any) { + assertArgument(false, error.message, param, value); } } @@ -104,7 +96,7 @@ function _parseLegacy(data: Uint8Array): TransactionLike { gasLimit: handleUint(fields[2], "gasLimit"), to: handleAddress(fields[3]), value: handleUint(fields[4], "value"), - data: handleData(fields[5], "dta"), + data: hexlify(fields[5]), chainId: BN_0 }; @@ -228,7 +220,7 @@ function _parseEip1559(data: Uint8Array): TransactionLike { gasLimit: handleUint(fields[4], "gasLimit"), to: handleAddress(fields[5]), value: handleUint(fields[6], "value"), - data: handleData(fields[7], "data"), + data: hexlify(fields[7]), accessList: handleAccessList(fields[8], "accessList"), }; @@ -278,7 +270,7 @@ function _parseEip2930(data: Uint8Array): TransactionLike { gasLimit: handleUint(fields[3], "gasLimit"), to: handleAddress(fields[4]), value: handleUint(fields[5], "value"), - data: handleData(fields[6], "data"), + data: hexlify(fields[6]), accessList: handleAccessList(fields[7], "accessList") }; @@ -321,24 +313,22 @@ export interface SignedTransaction extends Transaction { } -export class Transaction implements Freezable, TransactionLike { - #props: { - type: null | number, - to: null | string, - data: string, - nonce: number, - gasLimit: bigint, - gasPrice: null | bigint, - maxPriorityFeePerGas: null | bigint, - maxFeePerGas: null | bigint, - value: bigint, - chainId: bigint, - sig: null | Signature, - accessList: null | AccessList - }; +export class Transaction implements TransactionLike { + #type: null | number; + #to: null | string; + #data: string; + #nonce: number; + #gasLimit: bigint; + #gasPrice: null | bigint; + #maxPriorityFeePerGas: null | bigint; + #maxFeePerGas: null | bigint; + #value: bigint; + #chainId: bigint; + #sig: null | Signature; + #accessList: null | AccessList; // A type of null indicates the type will be populated automatically - get type(): null | number { return getStore(this.#props, "type"); } + get type(): null | number { return this.#type; } get typeName(): null | string { switch (this.type) { case 0: return "legacy"; @@ -351,100 +341,107 @@ export class Transaction implements Freezable, TransactionLike, TransactionLike, TransactionLike, TransactionLike, TransactionLike(this.inferTypes().pop()); } // Validates properties and lists possible types this transaction adheres to @@ -525,22 +516,15 @@ export class Transaction implements Freezable, TransactionLike= this.maxPriorityFeePerGas, "priorityFee cannot be more than maxFee", "BAD_DATA", { value: this }); } //if (this.type === 2 && hasGasPrice) { // throw new Error("eip-1559 transaction cannot have gasPrice"); //} - if ((this.type === 0 || this.type === 1) && hasFee) { - throw new Error("transaction type cannot have maxFeePerGas or maxPriorityFeePerGas"); - } - - if (this.type === 0 && hasAccessList) { - throw new Error("legacy transaction cannot have accessList"); - } + assert(!hasFee || (this.type !== 0 && this.type !== 1), "transaction type cannot have maxFeePerGas or maxPriorityFeePerGas", "BAD_DATA", { value: this }); + assert(this.type !== 0 || !hasAccessList, "legacy transaction cannot have accessList", "BAD_DATA", { value: this }) const types: Array = [ ]; @@ -583,26 +567,6 @@ export class Transaction implements Freezable, TransactionLike { - if (this.#props.sig) { - this.#props.sig = (this.#props.sig.clone().freeze()); - } - - if (this.#props.accessList) { - this.#props.accessList = Object.freeze(this.#props.accessList.map((set) => { - Object.freeze(set.storageKeys); - return Object.freeze(set); - })); - } - - Object.freeze(this.#props); - return this; - } - - isFrozen(): boolean { - return Object.isFrozen(this.#props); - } - toJSON(): any { const s = (v: null | bigint) => { if (v == null) { return null; } @@ -612,7 +576,7 @@ export class Transaction implements Freezable, TransactionLike, TransactionLike, TransactionLike