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

Create Transaction Factory and Introduce EIP2930 Access List Transactions #943

Merged
merged 72 commits into from
Aug 28, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
72 commits
Select commit Hold shift + click to select a range
43ffb2e
add tx type 1
MicaiahReid Jul 27, 2021
5f49acd
fix debug.test.ts compilation error
davidmurdoch Aug 11, 2021
1338a4a
rename raw and accesslist tx types
MicaiahReid Aug 12, 2021
c6a2a83
improve error message
MicaiahReid Aug 13, 2021
613e15d
remove todos
MicaiahReid Aug 13, 2021
c6d48b2
cleanup unusable code paths
MicaiahReid Aug 13, 2021
8b7df43
add typed transaction test cases for eth api
MicaiahReid Aug 13, 2021
9e02684
add transaction factory tests
MicaiahReid Aug 13, 2021
7c5d84d
remove unused imports
MicaiahReid Aug 13, 2021
c955544
fix transaction tests
MicaiahReid Aug 13, 2021
18fadd2
add tx type 1
MicaiahReid Jul 27, 2021
d9d9a12
fix debug.test.ts compilation error
davidmurdoch Aug 11, 2021
5c03891
rename raw and accesslist tx types
MicaiahReid Aug 12, 2021
8eb41d9
improve error message
MicaiahReid Aug 13, 2021
9206e99
remove todos
MicaiahReid Aug 13, 2021
603b599
cleanup unusable code paths
MicaiahReid Aug 13, 2021
f0b6a99
add typed transaction test cases for eth api
MicaiahReid Aug 13, 2021
455da2d
add transaction factory tests
MicaiahReid Aug 13, 2021
8c605b5
remove unused imports
MicaiahReid Aug 13, 2021
493fe51
fix transaction tests
MicaiahReid Aug 13, 2021
11b9d0b
Merge branch 'tx-types7' of github.com:trufflesuite/ganache-core into…
MicaiahReid Aug 13, 2021
4f2137c
cleaning up
MicaiahReid Aug 13, 2021
386c960
clean up. improve check for tx type
MicaiahReid Aug 13, 2021
63d44b7
clean import path
MicaiahReid Aug 13, 2021
c5d9822
more cleanup of unused logic paths
MicaiahReid Aug 13, 2021
6d689ed
reformat factory. check eips for each tx type
MicaiahReid Aug 13, 2021
7d51c98
remove redundant test
MicaiahReid Aug 13, 2021
1dab284
negative test cases for tx types pre berlin
MicaiahReid Aug 13, 2021
0a56607
only return legacy tx type if EIP2718 is activated
MicaiahReid Aug 16, 2021
daa2b4e
converts typed txs to legacy pre eip2718
MicaiahReid Aug 16, 2021
ded7c00
fix path for import
MicaiahReid Aug 16, 2021
7c34b72
fix issue with fetching block txs
MicaiahReid Aug 17, 2021
c307878
fix issue with validating signature of typed txs
MicaiahReid Aug 17, 2021
fe6a3a1
add forking test
MicaiahReid Aug 17, 2021
af40a69
reformat factory. check eips for each tx type
MicaiahReid Aug 13, 2021
f967903
remove redundant test
MicaiahReid Aug 13, 2021
b5a59a7
negative test cases for tx types pre berlin
MicaiahReid Aug 13, 2021
f02b324
only return legacy tx type if EIP2718 is activated
MicaiahReid Aug 16, 2021
c543d3d
converts typed txs to legacy pre eip2718
MicaiahReid Aug 16, 2021
5fc8b66
Merge branch 'feat/tx-factory-eip-check' of github.com:trufflesuite/g…
MicaiahReid Aug 17, 2021
ab30325
Apply suggestions from code review
MicaiahReid Aug 19, 2021
945002c
remove unused imports
MicaiahReid Aug 19, 2021
3470a5f
cleanup unused JSDOC notes
MicaiahReid Aug 19, 2021
b94fd3e
Merge branch 'tx-types7' of github.com:trufflesuite/ganache-core into…
MicaiahReid Aug 19, 2021
b1f1fa3
add type for all eip capabilities
MicaiahReid Aug 19, 2021
eb45fcb
reformat factory. check eips for each tx type
MicaiahReid Aug 13, 2021
01b4052
remove redundant test
MicaiahReid Aug 13, 2021
7580f85
negative test cases for tx types pre berlin
MicaiahReid Aug 13, 2021
8f26baf
only return legacy tx type if EIP2718 is activated
MicaiahReid Aug 16, 2021
4734180
converts typed txs to legacy pre eip2718
MicaiahReid Aug 16, 2021
bd04674
check activated eips on receipt retreival
MicaiahReid Aug 17, 2021
d194539
Merge branch 'feat/tx-factory-eip-check' of github.com:trufflesuite/g…
MicaiahReid Aug 19, 2021
e7ade05
stripping type away from legacy tx
MicaiahReid Aug 19, 2021
652cc47
remove unused export
MicaiahReid Aug 19, 2021
8f9ae8a
remove unused references
MicaiahReid Aug 19, 2021
b576eae
removed unused imports
MicaiahReid Aug 20, 2021
46aa9aa
optimize eip2930 data fee calculation
MicaiahReid Aug 20, 2021
e218110
use eip2930 data fee calculation
MicaiahReid Aug 20, 2021
ca63504
use coded errors in tx factory
MicaiahReid Aug 20, 2021
b4b0f92
use our own lib for data conversions
MicaiahReid Aug 20, 2021
1454d04
make expected values in tests the same every time
MicaiahReid Aug 24, 2021
0dd866b
let to const
MicaiahReid Aug 24, 2021
b248899
removing frozen/fake tx and resolving side effects
MicaiahReid Aug 24, 2021
c43297b
add comment
MicaiahReid Aug 24, 2021
d134856
fix capability check
MicaiahReid Aug 25, 2021
d0d18a7
remove reference to fake-transaction
MicaiahReid Aug 25, 2021
304dd21
fix typo
MicaiahReid Aug 25, 2021
3796cb9
replace RuntimeTransaction usage with TypedTransaction
MicaiahReid Aug 25, 2021
32577db
Merge branch 'develop' into tx-types7
davidmurdoch Aug 25, 2021
e9e09b3
make the tests work!
davidmurdoch Aug 26, 2021
808f6be
Merge branch 'tx-types7' of github.com:trufflesuite/ganache into tx-t…
davidmurdoch Aug 26, 2021
aad4b01
fix some failing tests that don't have anything to do with the rest o…
davidmurdoch Aug 28, 2021
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
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;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure I can see the need to add this field. Maybe this is something the VM requires now?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, the new version of ethereumjs-vm needs this field.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay. We set it to the parent's gasUsed in some cases, which seems odd to me.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

From what I've seen, we do that whenever we're trying to simulate a transaction or estimate gas. We can discuss, but I'm pretty sure the cases where it's set to the parent's gasUsed makes sense.

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
MicaiahReid marked this conversation as resolved.
Show resolved Hide resolved
* @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