Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 34 additions & 18 deletions e2e/cloudwalk-contracts/integration/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 e2e/cloudwalk-contracts/integration/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
"@openzeppelin/hardhat-upgrades": "3.3.0",
"@trivago/prettier-plugin-sort-imports": "4.3.0",
"axios": "1.15.2",
"ethers": "6.13.1",
"ethers": "6.15.0",
"hardhat": "2.22.16",
"prettier": "3.2.5",
"undici": "6.25.0",
Expand Down
136 changes: 134 additions & 2 deletions e2e/cloudwalk-contracts/integration/test/helpers/account.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,15 @@
import { Addressable, BigNumberish, Signer, Wallet } from "ethers";
import {
Addressable,
BigNumberish,
Signer,
SigningKey,
Wallet,
concat,
encodeRlp,
getAddress,
keccak256,
toBeArray,
} from "ethers";

import { CHAIN_ID_DEC, ETHERJS } from "./rpc";

Expand Down Expand Up @@ -60,7 +71,7 @@ export class Account implements Addressable {
value: amount,
chainId: CHAIN_ID_DEC,
maxFeePerGas: 2000000000, // 2 gwei
maxPriorityFeePerGas: 2000000000, // 2 gwei
maxPriorityFeePerGas: 2000000000,
gasLimit,
nonce,
});
Expand All @@ -83,6 +94,106 @@ export class Account implements Addressable {
accessList: [],
});
}

async signFullFieldsLegacy(
counterParty: string,
amount: BigNumberish,
nonce: number = 0,
gasLimit: BigNumberish = 1_000_000,
): Promise<string> {
return await this.signer().signTransaction({
to: counterParty,
value: amount,
chainId: CHAIN_ID_DEC,
gasPrice: 2000000000,
gasLimit,
nonce,
type: 0,
data: "0xdeadbeef",
});
}

async signFullFieldsEIP2930(
counterParty: string,
amount: BigNumberish,
nonce: number = 0,
gasLimit: BigNumberish = 1_000_000,
): Promise<string> {
return await this.signer().signTransaction({
to: counterParty,
value: amount,
chainId: CHAIN_ID_DEC,
gasPrice: 2000000000,
gasLimit,
nonce,
type: 1,
data: "0xdeadbeef",
accessList: ACCESS_LIST,
});
}

async signFullFieldsEIP1559(
counterParty: string,
amount: BigNumberish,
nonce: number = 0,
gasLimit: BigNumberish = 1_000_000,
): Promise<string> {
return await this.signer().signTransaction({
to: counterParty,
value: amount,
chainId: CHAIN_ID_DEC,
maxFeePerGas: 2000000000,
maxPriorityFeePerGas: 2000000000,
gasLimit,
nonce,
type: 2,
data: "0xdeadbeef",
accessList: ACCESS_LIST,
});
}

async signFullFieldsEIP4844(
counterParty: string,
amount: BigNumberish,
nonce: number = 0,
gasLimit: BigNumberish = 1_000_000,
): Promise<string> {
return await this.signer().signTransaction({
to: counterParty,
value: amount,
chainId: CHAIN_ID_DEC,
maxFeePerGas: 2000000000,
maxPriorityFeePerGas: 2000000000,
gasLimit,
nonce,
type: 3,
data: "0xdeadbeef",
accessList: ACCESS_LIST,
maxFeePerBlobGas: 1,
blobVersionedHashes: [BLOB_VERSIONED_HASH],
});
}

async signFullFieldsEIP7702(
counterParty: string,
amount: BigNumberish,
nonce: number = 0,
gasLimit: BigNumberish = 1_000_000,
): Promise<string> {
return await this.signer().signTransaction({
to: counterParty,
value: amount,
chainId: CHAIN_ID_DEC,
maxFeePerGas: 2000000000,
maxPriorityFeePerGas: 2000000000,
gasLimit,
nonce,
type: 4,
data: "0xdeadbeef",
accessList: ACCESS_LIST,
authorizationList: [createAuthorization(ALICE.privateKey, counterParty, 0)],
});
}
Comment thread
f3l1ph3s marked this conversation as resolved.
}

export const ALICE = new Account(
Expand Down Expand Up @@ -115,6 +226,27 @@ export const FERDIE = new Account(
"0x92db14e403b83dfe3df233f83dfa3a0d7096f21ca9b0d6d6b8d88b2b4ec1564e",
);

const ACCESS_LIST = [
{
address: BOB.address,
storageKeys: ["0x0000000000000000000000000000000000000000000000000000000000000000"],
},
];

const BLOB_VERSIONED_HASH = "0x0100000000000000000000000000000000000000000000000000000000000000";

function createAuthorization(privateKey: string, delegate: string, nonce: number = 0) {
const address = getAddress(delegate);
const digest = keccak256(concat(["0x05", encodeRlp([toBeArray(CHAIN_ID_DEC), address, toBeArray(nonce)])]));
const signature = new SigningKey(privateKey).sign(digest);
return {
chainId: CHAIN_ID_DEC,
address,
nonce,
signature,
};
}

export const TEST_ACCOUNTS = [ALICE, BOB, CHARLIE, DAVE, EVE, FERDIE];

/// Generates N random accounts.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -241,16 +241,22 @@ describe("Leader & Follower importer integration test", function () {
console.log("Type 2 (EIP-1559) transaction hash:", eip1559Hash);
await sendWithRetry("eth_sendRawTransaction", [eip1559Tx]);

// Wait for transactions to be mined on the leader before fetching them.
const getTransactionResult = async (txHash: string) => {
const response = await getTransactionByHashUntilConfirmed(txHash, 15);
return response.data.result;
};

// Verify on Leader
const leaderLegacyTx = await sendWithRetry("eth_getTransactionByHash", [legacyHash]);
const leaderLegacyTx = await getTransactionResult(legacyHash);
expect(leaderLegacyTx.from.toLowerCase()).to.equal(ALICE.address.toLowerCase());
expect(leaderLegacyTx.type).to.equal("0x0");

const leaderEIP2930Tx = await sendWithRetry("eth_getTransactionByHash", [eip2930Hash]);
const leaderEIP2930Tx = await getTransactionResult(eip2930Hash);
expect(leaderEIP2930Tx.from.toLowerCase()).to.equal(DAVE.address.toLowerCase());
expect(leaderEIP2930Tx.type).to.equal("0x1");

const leaderEIP1559Tx = await sendWithRetry("eth_getTransactionByHash", [eip1559Hash]);
const leaderEIP1559Tx = await getTransactionResult(eip1559Hash);
expect(leaderEIP1559Tx.from.toLowerCase()).to.equal(CHARLIE.address.toLowerCase());
expect(leaderEIP1559Tx.type).to.equal("0x2");

Expand All @@ -259,45 +265,45 @@ describe("Leader & Follower importer integration test", function () {

// Verify on Follower
updateProviderUrl("stratus-follower");
const followerLegacyTx = await sendWithRetry("eth_getTransactionByHash", [legacyHash]);
const followerLegacyTx = await getTransactionResult(legacyHash);
expect(followerLegacyTx.from.toLowerCase()).to.equal(ALICE.address.toLowerCase());
expect(followerLegacyTx.type).to.equal("0x0");

const followerEIP2930Tx = await sendWithRetry("eth_getTransactionByHash", [eip2930Hash]);
const followerEIP2930Tx = await getTransactionResult(eip2930Hash);
expect(followerEIP2930Tx.from.toLowerCase()).to.equal(DAVE.address.toLowerCase());
expect(followerEIP2930Tx.type).to.equal("0x1");

const followerEIP1559Tx = await sendWithRetry("eth_getTransactionByHash", [eip1559Hash]);
const followerEIP1559Tx = await getTransactionResult(eip1559Hash);
expect(followerEIP1559Tx.from.toLowerCase()).to.equal(CHARLIE.address.toLowerCase());
expect(followerEIP1559Tx.type).to.equal("0x2");

// Also verify receipts on both Leader and Follower
console.log("Verifying receipts on Leader...");
updateProviderUrl("stratus");
console.log("Getting receipt for Type 0 (Legacy) tx:", legacyHash);
const leaderLegacyReceipt = await sendWithRetry("eth_getTransactionReceipt", [legacyHash]);
const leaderLegacyReceipt = await sendWithRetry("eth_getTransactionReceipt", [legacyHash], 15, 1000);
expect(leaderLegacyReceipt.from.toLowerCase()).to.equal(ALICE.address.toLowerCase());

console.log("Getting receipt for Type 1 (EIP-2930) tx:", eip2930Hash);
const leaderEIP2930Receipt = await sendWithRetry("eth_getTransactionReceipt", [eip2930Hash]);
const leaderEIP2930Receipt = await sendWithRetry("eth_getTransactionReceipt", [eip2930Hash], 15, 1000);
expect(leaderEIP2930Receipt.from.toLowerCase()).to.equal(DAVE.address.toLowerCase());

console.log("Getting receipt for Type 2 (EIP-1559) tx:", eip1559Hash);
const leaderEIP1559Receipt = await sendWithRetry("eth_getTransactionReceipt", [eip1559Hash]);
const leaderEIP1559Receipt = await sendWithRetry("eth_getTransactionReceipt", [eip1559Hash], 15, 1000);
expect(leaderEIP1559Receipt.from.toLowerCase()).to.equal(CHARLIE.address.toLowerCase());

console.log("Verifying receipts on Follower...");
updateProviderUrl("stratus-follower");
console.log("Getting receipt for Type 0 (Legacy) tx:", legacyHash);
const followerLegacyReceipt = await sendWithRetry("eth_getTransactionReceipt", [legacyHash]);
const followerLegacyReceipt = await sendWithRetry("eth_getTransactionReceipt", [legacyHash], 15, 1000);
expect(followerLegacyReceipt.from.toLowerCase()).to.equal(ALICE.address.toLowerCase());

console.log("Getting receipt for Type 1 (EIP-2930) tx:", eip2930Hash);
const followerEIP2930Receipt = await sendWithRetry("eth_getTransactionReceipt", [eip2930Hash]);
const followerEIP2930Receipt = await sendWithRetry("eth_getTransactionReceipt", [eip2930Hash], 15, 1000);
expect(followerEIP2930Receipt.from.toLowerCase()).to.equal(DAVE.address.toLowerCase());

console.log("Getting receipt for Type 2 (EIP-1559) tx:", eip1559Hash);
const followerEIP1559Receipt = await sendWithRetry("eth_getTransactionReceipt", [eip1559Hash]);
const followerEIP1559Receipt = await sendWithRetry("eth_getTransactionReceipt", [eip1559Hash], 15, 1000);
expect(followerEIP1559Receipt.from.toLowerCase()).to.equal(CHARLIE.address.toLowerCase());
});
});
Loading
Loading