Use EIP-2930 for some transactions

This commit is contained in:
POA 2021-04-30 13:33:26 +03:00
parent 21a9d71f5f
commit 47dea054d0
6 changed files with 49 additions and 29 deletions

View File

@ -32,13 +32,13 @@ $ cd openethereum
$ cargo build --release --features final
```
To save time, you can download a pre-compiled binary from the [releases page](https://github.com/openethereum/openethereum/releases) (versions above v3.2.1 are supported). But you still need to maintain directory structure and naming conventions:
To save time, you can download a pre-compiled binary from the [releases page](https://github.com/openethereum/openethereum/releases) (versions >= v3.2.5 are supported). But you still need to maintain directory structure and naming conventions:
```bash
# move up from posdao-test-setup root
$ cd ..
$ mkdir -p openethereum/target/release/
# an example for macOS binary
$ curl -SfL 'https://github.com/openethereum/openethereum/releases/download/v3.2.2/openethereum-macos-v3.2.2.zip' -o openethereum/target/release/openethereum.zip
$ curl -SfL 'https://github.com/openethereum/openethereum/releases/download/v3.2.5-rc.1/openethereum-macos-v3.2.5-rc.1.zip' -o openethereum/target/release/openethereum.zip
$ unzip openethereum/target/release/openethereum.zip -d openethereum/target/release
$ chmod +x openethereum/target/release/openethereum
# check that it works and the version is correct (compare the version from the binary with version on the release page)
@ -55,13 +55,13 @@ To integrate with [Nethermind](https://github.com/NethermindEth/nethermind), the
```
So there should be two folders on the same level and `posdao-test-setup` will use a binary from the `nethermind` folder, namely the binary is assumed to be at `../nethermind/bin/Nethermind.Runner` relative to `posdao-test-setup` root.
A pre-compiled binary can be downloaded from the [releases page](https://github.com/NethermindEth/nethermind/releases) (>= v1.10.48 is supported). You need to maintain directory structure and naming conventions:
A pre-compiled binary can be downloaded from the [releases page](https://github.com/NethermindEth/nethermind/releases) (>= v1.10.66 is supported). You need to maintain directory structure and naming conventions:
```bash
# move up from posdao-test-setup root
$ cd ..
$ mkdir -p nethermind/bin
# an example for Linux binary
$ curl -SfL 'https://nethdev.blob.core.windows.net/builds/nethermind-linux-amd64-1.10.48-589bce9.zip' -o nethermind/bin/nethermind.zip
$ curl -SfL 'https://nethdev.blob.core.windows.net/builds/nethermind-linux-amd64-1.10.66-0b294a8.zip' -o nethermind/bin/nethermind.zip
$ unzip nethermind/bin/nethermind.zip -d nethermind/bin
$ chmod +x nethermind/bin/Nethermind.Runner
# check that it works and version is correct (compare the version from the binary with version on the release page)

View File

@ -5,9 +5,9 @@
"scripts": {
"after-start": "npm run checkers && npm run test && npm run watcher && npm run stop-test-setup",
"after-start-no-watcher": "npm run checkers && npm run test && npm run stop-test-setup",
"all": "npm run before-start && npm run start-test-setup-openethereum && npm run after-start",
"all-nethermind": "npm run before-start && npm run start-test-setup-nethermind && npm run after-start",
"all-nethermind-no-watcher": "npm run before-start && npm run start-test-setup-nethermind && npm run after-start-no-watcher",
"all": "CLIENT=openethereum npm run before-start && npm run start-test-setup-openethereum && npm run after-start",
"all-nethermind": "CLIENT=nethermind npm run before-start && npm run start-test-setup-nethermind && npm run after-start",
"all-nethermind-no-watcher": "CLIENT=nethermind npm run before-start && npm run start-test-setup-nethermind && npm run after-start-no-watcher",
"before-start": "npm i && npm run get-all-submodules && npm run cleanup && npm run compile-posdao-contracts && npm run make-spec",
"checkers": "(node scripts/watchOrdinaryNode.js &) && node scripts/deploy-staking-token.js && (node scripts/watchRandomSeed &)",
"cleanup": "bash scripts/stop-test-setup && rm -rf ./accounts ./config ./data && git checkout ./accounts && git checkout ./config && git checkout ./data",

View File

@ -22,6 +22,14 @@ async function main() {
console.log();
console.log();
// Explicitly activate EIP-2565
if (process.env.CLIENT == 'openethereum') {
specFile.accounts["0000000000000000000000000000000000000005"].builtin.pricing["0"].price = { modexp2565: {} };
} else if (process.env.CLIENT == 'nethermind') {
specFile.params.eip2565Transition = "0x0";
specFile.params.eip2718Transition = "0x0";
}
await promisify(fs.writeFile)(__dirname + '/../data/spec.json', JSON.stringify(specFile, null, ' '), 'UTF-8');
}

View File

@ -161,7 +161,7 @@ describe('Candidates place stakes on themselves', () => {
method: StakingAuRa.instance.methods.stake(candidate.staking, stakeBN.toString()),
gasPrice: '1000000000', // maxPriorityFeePerGas for EIP-1559, maxFeePerGas is calculated as baseFee + maxPriorityFeePerGas
gasLimit: '400000',
}, null, latestBlock.baseFee);
}, null, latestBlock.baseFee, []); // Use EIP-2930 here (and EIP-1559 if supported)
});
pp.tx(tx);
expect(tx.status, `Failed tx: ${tx.transactionHash}`).to.equal(true);

View File

@ -41,8 +41,8 @@ function prepareTxToField(to) {
return to;
}
function signTransaction(txMessage, isEIP1559, privateKey) {
const messageHash = web3.utils.keccak256('0x' + (isEIP1559 ? '02' : '') + rlp.encode(txMessage).toString('hex'));
function signTransaction(txMessage, txType, privateKey) {
const messageHash = web3.utils.keccak256('0x' + (txType > 0 ? `0${txType}` : '') + rlp.encode(txMessage).toString('hex'));
let privateKeyBuffer;
if (Buffer.isBuffer(privateKey)) {
@ -54,9 +54,9 @@ function signTransaction(txMessage, isEIP1559, privateKey) {
const sigObj = secp256k1.ecdsaSign(Buffer.from(messageHash.slice(2), "hex"), privateKeyBuffer);
const signature = Buffer.from(sigObj.signature).toString('hex');
const chainId = isEIP1559 ? txMessage[0] : txMessage[6];
const chainId = txType > 0 ? txMessage[0] : txMessage[6];
let v;
if (isEIP1559) {
if (txType > 0) {
v = (sigObj.recid != 0) ? web3.utils.toHex(sigObj.recid) : '';
} else {
v = web3.utils.toHex(sigObj.recid + 27 + chainId * 2 + 8);
@ -64,39 +64,44 @@ function signTransaction(txMessage, isEIP1559, privateKey) {
const r = '0x' + signature.slice(0, 64);
const s = '0x' + signature.slice(64, 128);
const txMessageSigned = isEIP1559 ? txMessage : txMessage.slice(0, 6);
const txMessageSigned = txType > 0 ? txMessage : txMessage.slice(0, 6);
txMessageSigned.push(v);
txMessageSigned.push(r);
txMessageSigned.push(s);
const rawTransaction = '0x' + (isEIP1559 ? '02' : '') + rlp.encode(txMessageSigned).toString('hex');
const rawTransaction = '0x' + (txType > 0 ? `0${txType}` : '') + rlp.encode(txMessageSigned).toString('hex');
const transactionHash = web3.utils.keccak256(rawTransaction);
const rawTransactionRLP = isEIP1559 ? '0x' + rlp.encode(rawTransaction).toString('hex') : rawTransaction;
const rawTransactionRLP = txType > 0 ? '0x' + rlp.encode(rawTransaction).toString('hex') : rawTransaction;
return { messageHash, v, r, s, rawTransaction: rawTransactionRLP, transactionHash };
}
module.exports = function (transaction, privateKey) {
module.exports = function (transaction, privateKey, txType) {
const chainId = prepareTxIntegerField(transaction.chainId, 'Chain id');
const nonce = prepareTxIntegerField(transaction.nonce, 'Nonce');
const maxPriorityFeePerGas = prepareTxIntegerField(transaction.maxPriorityFeePerGas, 'maxPriorityFeePerGas');
const maxFeePerGas = prepareTxIntegerField(transaction.maxFeePerGas, 'maxFeePerGas');
const gas = prepareTxIntegerField(transaction.gas, 'Gas limit');
const to = prepareTxToField(transaction.to);
const value = prepareTxIntegerField(transaction.value, 'Value');
const data = prepareTxDataField(transaction.data);
const txMessage = [
chainId,
nonce,
maxPriorityFeePerGas,
maxFeePerGas,
let txMessage = [chainId, nonce];
if (txType == 2) { // EIP-1559
txMessage.push(prepareTxIntegerField(transaction.maxPriorityFeePerGas, 'maxPriorityFeePerGas'));
txMessage.push(prepareTxIntegerField(transaction.maxFeePerGas, 'maxFeePerGas'));
} else if (txType == 1) { // EIP-2930
txMessage.push(prepareTxIntegerField(transaction.gasPrice, 'Gas price'));
} else {
throw "Unsupported transaction type";
}
txMessage = txMessage.concat([
gas,
to,
value,
data,
transaction.accessList
];
]);
return signTransaction(txMessage, true, privateKey);
return signTransaction(txMessage, txType, privateKey);
}

View File

@ -2,7 +2,7 @@
const EthereumTx = require('ethereumjs-tx');
const fs = require('fs');
const path = require('path');
const sign1559Transaction = require('./sign1559Tx.js');
const sign2718Transaction = require('./sign2718Tx.js');
/*
* Expects the following structure for tx_details:
{
@ -35,7 +35,7 @@ function getPrivateKey(web3, address) {
return pkBuff;
}
module.exports = async function (web3, tx_details, privateKey, eip1559BaseFee) {
module.exports = async function (web3, tx_details, privateKey, eip1559BaseFee, eip2930AccessList) {
let from = tx_details.from;
let to = tx_details.to;
let value = web3.utils.toHex(tx_details.value || 0);
@ -98,14 +98,21 @@ module.exports = async function (web3, tx_details, privateKey, eip1559BaseFee) {
_tx.maxFeePerGas = web3.utils.toBN(eip1559BaseFee).add(web3.utils.toBN(gasPrice)).toString(); // maxFeePerGas = baseFee + maxPriorityFeePerGas
}
_tx.maxPriorityFeePerGas = gasPrice;
}
if (eip1559BaseFee || eip2930AccessList) {
_tx.gas = _tx.gasLimit;
_tx.accessList = [];
_tx.accessList = eip2930AccessList || [];
}
dbg(' **** _tx =', _tx);
if (eip1559BaseFee) { // EIP-1559 is active
const signedTx = sign1559Transaction(_tx, privateKey);
const signedTx = sign2718Transaction(_tx, privateKey, 2); // EIP-1559
const serializedTx = signedTx.rawTransaction;
return web3.eth.sendSignedTransaction(serializedTx);
} else if (eip2930AccessList) {
const signedTx = sign2718Transaction(_tx, privateKey, 1); // EIP-2930
const serializedTx = signedTx.rawTransaction;
return web3.eth.sendSignedTransaction(serializedTx);
} else {