Skip to content
This repository has been archived by the owner on Feb 26, 2024. It is now read-only.

Commit

Permalink
fix: add EIP2930 Access List Transactions (#943)
Browse files Browse the repository at this point in the history
Co-authored-by: David Murdoch <[email protected]>
  • Loading branch information
MicaiahReid and davidmurdoch authored Aug 28, 2021
1 parent eb41cfd commit 794c4b3
Show file tree
Hide file tree
Showing 60 changed files with 7,573 additions and 6,664 deletions.
1 change: 1 addition & 0 deletions src/chains/ethereum/block/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
export * from "./src/block";
export * from "./src/runtime-block";
export * from "./src/snapshots";
export * from "./src/serialize";
35 changes: 10 additions & 25 deletions src/chains/ethereum/block/package-lock.json

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

4 changes: 2 additions & 2 deletions src/chains/ethereum/block/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -57,13 +57,13 @@
"typescript": "4.1.3"
},
"dependencies": {
"@ethereumjs/common": "2.3.0",
"@ethereumjs/common": "2.4.0",
"@ganache/ethereum-address": "0.1.1-alpha.0",
"@ganache/ethereum-transaction": "0.1.1-alpha.0",
"@ganache/ethereum-utils": "0.1.1-alpha.0",
"@ganache/rlp": "0.1.1-alpha.0",
"@ganache/utils": "0.1.1-alpha.0",
"emittery": "0.7.2",
"ethereumjs-util": "7.0.9"
"ethereumjs-util": "7.1.0"
}
}
77 changes: 38 additions & 39 deletions src/chains/ethereum/block/src/block.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
import { Data, Quantity } from "@ganache/utils";
import {
BlockTransaction,
EthereumRawTx,
GanacheRawBlockTransactionMetaData
GanacheRawBlockTransactionMetaData,
GanacheRawExtraTx,
TransactionFactory,
TypedDatabaseTransaction,
TypedTransaction
} from "@ganache/ethereum-transaction";
import type Common from "@ethereumjs/common";
import { encode, decode } from "@ganache/rlp";
import { BlockHeader, makeHeader } from "./runtime-block";
import { keccak, BUFFER_EMPTY } from "@ganache/utils";
import { keccak } from "@ganache/utils";
import {
EthereumRawBlockHeader,
GanacheRawBlock,
Expand All @@ -19,7 +21,7 @@ export class Block {
protected _size: number;
protected _raw: EthereumRawBlockHeader;
protected _common: Common;
protected _rawTransactions: EthereumRawTx[];
protected _rawTransactions: TypedDatabaseTransaction[];
protected _rawTransactionMetaData: GanacheRawBlockTransactionMetaData[];

public header: BlockHeader;
Expand Down Expand Up @@ -49,17 +51,17 @@ export class Block {

getTransactions() {
const common = this._common;
return this._rawTransactions.map(
(raw, index) =>
new BlockTransaction(
raw,
this._rawTransactionMetaData[index],
this.hash().toBuffer(),
this.header.number.toBuffer(),
Quantity.from(index).toBuffer(),
common
)
);
return this._rawTransactions.map((raw, index) => {
const [from, hash] = this._rawTransactionMetaData[index];
const extra: GanacheRawExtraTx = [
from,
hash,
this.hash().toBuffer(),
this.header.number.toBuffer(),
Quantity.from(index).toBuffer()
];
return TransactionFactory.fromDatabaseTx(raw, common, extra);
});
}

toJSON(includeFullTransactions = false) {
Expand All @@ -69,14 +71,15 @@ export class Block {
const number = this.header.number.toBuffer();
const common = this._common;
const jsonTxs = this._rawTransactions.map((raw, index) => {
const tx = new BlockTransaction(
raw,
this._rawTransactionMetaData[index],
const [from, hash] = this._rawTransactionMetaData[index];
const extra: GanacheRawExtraTx = [
from,
hash,
hashBuffer,
number,
Quantity.from(index).toBuffer(),
common
);
Quantity.from(index).toBuffer()
];
const tx = TransactionFactory.fromDatabaseTx(raw, common, extra);
return txFn(tx);
});

Expand All @@ -89,7 +92,7 @@ export class Block {
};
}

static rawFromJSON(json: any) {
static rawFromJSON(json: any, common: Common) {
const header: EthereumRawBlockHeader = [
Data.from(json.parentHash).toBuffer(),
Data.from(json.sha3Uncles).toBuffer(),
Expand All @@ -108,20 +111,16 @@ export class Block {
Data.from(json.nonce).toBuffer()
];
const totalDifficulty = Quantity.from(json.totalDifficulty).toBuffer();
const txs: EthereumRawTx[] = [];
const txs: TypedDatabaseTransaction[] = [];
const extraTxs: GanacheRawBlockTransactionMetaData[] = [];
json.transactions.forEach(tx => {
txs.push([
Quantity.from(tx.nonce).toBuffer(),
Quantity.from(tx.gasPrice).toBuffer(),
Quantity.from(tx.gas).toBuffer(),
tx.to == null ? BUFFER_EMPTY : Address.from(tx.to).toBuffer(),
Quantity.from(tx.value).toBuffer(),
Data.from(tx.input).toBuffer(),
Quantity.from(tx.v).toBuffer(),
Quantity.from(tx.r).toBuffer(),
Quantity.from(tx.s).toBuffer()
]);
const typedTx = TransactionFactory.fromRpc(tx, common);
const raw = typedTx.toEthRawTransaction(
typedTx.v.toBuffer(),
typedTx.r.toBuffer(),
typedTx.s.toBuffer()
);
txs.push(<TypedDatabaseTransaction>raw);
extraTxs.push([
Quantity.from(tx.from).toBuffer(),
Quantity.from(tx.hash).toBuffer()
Expand All @@ -133,17 +132,17 @@ export class Block {

getTxFn(
include = false
): (tx: BlockTransaction) => ReturnType<BlockTransaction["toJSON"]> | Data {
): (tx: TypedTransaction) => ReturnType<TypedTransaction["toJSON"]> | Data {
if (include) {
return (tx: BlockTransaction) => tx.toJSON();
return (tx: TypedTransaction) => tx.toJSON(this._common);
} else {
return (tx: BlockTransaction) => tx.hash;
return (tx: TypedTransaction) => tx.hash;
}
}

static fromParts(
rawHeader: EthereumRawBlockHeader,
txs: EthereumRawTx[],
txs: TypedDatabaseTransaction[],
totalDifficulty: Buffer,
extraTxs: GanacheRawBlockTransactionMetaData[],
size: number,
Expand Down
28 changes: 13 additions & 15 deletions src/chains/ethereum/block/src/runtime-block.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,9 @@ import { EthereumRawBlockHeader, serialize } from "./serialize";
import { Address } from "@ganache/ethereum-address";
import { Block } from "./block";
import {
EthereumRawTx,
TypedDatabaseTransaction,
GanacheRawBlockTransactionMetaData,
RuntimeTransaction
TypedTransaction
} from "@ganache/ethereum-transaction";
import { StorageKeys } from "@ganache/ethereum-utils";

Expand Down Expand Up @@ -94,6 +94,7 @@ export class RuntimeBlock {
coinbase: { buf: Buffer; toBuffer: () => Buffer };
number: BnExtra;
gasLimit: BnExtra;
gasUsed: BnExtra;
timestamp: BnExtra;
};

Expand All @@ -102,6 +103,7 @@ export class RuntimeBlock {
parentHash: Data,
coinbase: Address,
gasLimit: Buffer,
gasUsed: Buffer,
timestamp: Quantity,
difficulty: Quantity,
previousBlockTotalDifficulty: Quantity
Expand All @@ -117,22 +119,14 @@ export class RuntimeBlock {
previousBlockTotalDifficulty.toBigInt() + difficulty.toBigInt()
).toBuffer(),
gasLimit: new BnExtra(gasLimit),
gasUsed: new BnExtra(gasUsed),
timestamp: new BnExtra(ts)
};
}

/**
* Returns the serialization of all block data, the hash of the block header,
* and a map of the hashed and raw storage keys
*
* @param transactionsTrie
* @param receiptTrie
* @param bloom
* @param stateRoot
* @param gasUsed
* @param extraData
* @param transactions
* @param storageKeys
*/
finalize(
transactionsTrie: Buffer,
Expand All @@ -141,7 +135,7 @@ export class RuntimeBlock {
stateRoot: Buffer,
gasUsed: bigint,
extraData: Data,
transactions: RuntimeTransaction[],
transactions: TypedTransaction[],
storageKeys: StorageKeys
) {
const { header } = this;
Expand All @@ -163,10 +157,10 @@ export class RuntimeBlock {
BUFFER_8_ZERO // nonce
];
const { totalDifficulty } = header;
const txs: EthereumRawTx[] = [];
const txs: TypedDatabaseTransaction[] = [];
const extraTxs: GanacheRawBlockTransactionMetaData[] = [];
transactions.forEach(tx => {
txs.push(tx.raw);
txs.push(<TypedDatabaseTransaction>tx.raw);
extraTxs.push([tx.from.toBuffer(), tx.hash.toBuffer()]);
});
const { serialized, size } = serialize([
Expand All @@ -181,7 +175,11 @@ export class RuntimeBlock {
// deserialization work since we already have everything in a deserialized
// state here. We'll just set it ourselves by reaching into the "_private"
// fields.
const block = new Block(null, null);
const block = new Block(
null,
// TODO(hack)!
transactions.length > 0 ? transactions[0].common : null
);
(block as any)._raw = rawHeader;
(block as any)._rawTransactions = txs;
(block as any).header = makeHeader(rawHeader, totalDifficulty);
Expand Down
4 changes: 2 additions & 2 deletions src/chains/ethereum/block/src/serialize.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import {
EthereumRawTx,
TypedDatabaseTransaction,
GanacheRawBlockTransactionMetaData
} from "@ganache/ethereum-transaction";
import { digest, encodeLength, encodeRange, encode } from "@ganache/rlp";
Expand Down Expand Up @@ -29,7 +29,7 @@ export type EthereumRawBlockHeader = [
];
export type EthereumRawBlock = [
rawHeader: EthereumRawBlockHeader,
rawTransactions: EthereumRawTx[],
rawTransactions: TypedDatabaseTransaction[],
uncles: []
];
type Head<T extends any[]> = T extends [...infer Head, any] ? Head : any[];
Expand Down
Loading

0 comments on commit 794c4b3

Please sign in to comment.