Skip to content
This repository has been archived by the owner on Oct 28, 2021. It is now read-only.

Implement EIP-1344: CHAINID opcode in LegacyVM #5696

Merged
merged 6 commits into from
Aug 5, 2019
Merged
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
3 changes: 2 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@
- Added: [#5624](https://github.com/ethereum/aleth/pull/5624) Remove useless peers from peer list.
- Added: [#5634](https://github.com/ethereum/aleth/pull/5634) Bootnodes for Rinkeby and Goerli.
- Added: [#5640](https://github.com/ethereum/aleth/pull/5640) Support EIP-1702 Generalized Account Versioning Scheme (active only in Experimental fork.)
- Added: [#5690](https://github.com/ethereum/aleth/issues/5690) Istanbul support: EIP-2028 transaction data gas cost reduction.
- Added: [#5691](https://github.com/ethereum/aleth/pull/5691) Istanbul support: EIP-2028 Transaction data gas cost reduction.
- Added: [#5696](https://github.com/ethereum/aleth/pull/5696) Istanbul support: EIP-1344 ChainID opcode.
- Added: [#5701](https://github.com/ethereum/aleth/issues/5701) Outputs ENR text representation in admin.nodeInfo RPC.
- Changed: [#5532](https://github.com/ethereum/aleth/pull/5532) The leveldb is upgraded to 1.22. This is breaking change on Windows and the old databases are not compatible.
- Changed: [#5559](https://github.com/ethereum/aleth/pull/5559) Update peer validation error messages.
Expand Down
2 changes: 1 addition & 1 deletion aleth-vm/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -262,7 +262,7 @@ int main(int argc, char** argv)

unique_ptr<SealEngineFace> se(ChainParams(genesisInfo(networkName)).createSealEngine());
LastBlockHashes lastBlockHashes;
EnvInfo const envInfo(blockHeader, lastBlockHashes, 0);
EnvInfo const envInfo(blockHeader, lastBlockHashes, 0 /* gasUsed */, se->chainParams().chainID);

Transaction t;
Address contractDestination("1122334455667788991011121314151617181920");
Expand Down
2 changes: 2 additions & 0 deletions libethcore/EVMSchedule.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ struct EVMSchedule
bool haveStaticCall = false;
bool haveCreate2 = false;
bool haveExtcodehash = false;
bool haveChainID = false;
std::array<unsigned, 8> tierStepGas;
unsigned expGas = 10;
unsigned expByteGas = 10;
Expand Down Expand Up @@ -150,6 +151,7 @@ static const EVMSchedule ConstantinopleFixSchedule = [] {
static const EVMSchedule IstanbulSchedule = [] {
EVMSchedule schedule = ConstantinopleFixSchedule;
schedule.txDataNonZeroGas = 16;
schedule.haveChainID = true;
return schedule;
}();

Expand Down
7 changes: 5 additions & 2 deletions libethereum/Block.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -629,7 +629,8 @@ u256 Block::enact(VerifiedBlockRef const& _block, BlockChain const& _bc)
return tdIncrease;
}

ExecutionResult Block::execute(LastBlockHashesFace const& _lh, Transaction const& _t, Permanence _p, OnOpFunc const& _onOp)
ExecutionResult Block::execute(
LastBlockHashesFace const& _lh, Transaction const& _t, Permanence _p, OnOpFunc const& _onOp)
{
if (isSealed())
BOOST_THROW_EXCEPTION(InvalidOperationOnSealedBlock());
Expand All @@ -638,7 +639,9 @@ ExecutionResult Block::execute(LastBlockHashesFace const& _lh, Transaction const
// transaction as possible.
uncommitToSeal();

std::pair<ExecutionResult, TransactionReceipt> resultReceipt = m_state.execute(EnvInfo(info(), _lh, gasUsed()), *m_sealEngine, _t, _p, _onOp);
EnvInfo const envInfo{info(), _lh, gasUsed(), m_sealEngine->chainParams().chainID};
std::pair<ExecutionResult, TransactionReceipt> resultReceipt =
m_state.execute(envInfo, *m_sealEngine, _t, _p, _onOp);

if (_p == Permanence::Committed)
{
Expand Down
2 changes: 2 additions & 0 deletions libethereum/BlockChain.h
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,8 @@ class BlockChain

LastBlockHashesFace const& lastBlockHashes() const { return *m_lastBlockHashes; }

int chainID() const { return m_params.chainID; }

/** Get the block blooms for a number of blocks. Thread-safe.
* @returns the object pertaining to the blocks:
* level 0:
Expand Down
20 changes: 11 additions & 9 deletions libethereum/Executive.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -180,25 +180,27 @@ string StandardTrace::multilineTrace() const
[](std::string a, Json::Value b) { return a + Json::FastWriter().write(b); });
}

Executive::Executive(Block& _s, BlockChain const& _bc, unsigned _level):
m_s(_s.mutableState()),
m_envInfo(_s.info(), _bc.lastBlockHashes(), 0),
Executive::Executive(Block& _s, BlockChain const& _bc, unsigned _level)
: m_s(_s.mutableState()),
m_envInfo(_s.info(), _bc.lastBlockHashes(), 0, _bc.chainID()),
m_depth(_level),
m_sealEngine(*_bc.sealEngine())
{
}

Executive::Executive(Block& _s, LastBlockHashesFace const& _lh, unsigned _level):
m_s(_s.mutableState()),
m_envInfo(_s.info(), _lh, 0),
Executive::Executive(Block& _s, LastBlockHashesFace const& _lh, unsigned _level)
: m_s(_s.mutableState()),
m_envInfo(_s.info(), _lh, 0, _s.sealEngine()->chainParams().chainID),
m_depth(_level),
m_sealEngine(*_s.sealEngine())
{
}

Executive::Executive(State& io_s, Block const& _block, unsigned _txIndex, BlockChain const& _bc, unsigned _level):
m_s(createIntermediateState(io_s, _block, _txIndex, _bc)),
m_envInfo(_block.info(), _bc.lastBlockHashes(), _txIndex ? _block.receipt(_txIndex - 1).cumulativeGasUsed() : 0),
Executive::Executive(
State& io_s, Block const& _block, unsigned _txIndex, BlockChain const& _bc, unsigned _level)
: m_s(createIntermediateState(io_s, _block, _txIndex, _bc)),
m_envInfo(_block.info(), _bc.lastBlockHashes(),
_txIndex ? _block.receipt(_txIndex - 1).cumulativeGasUsed() : 0, _bc.chainID()),
m_depth(_level),
m_sealEngine(*_bc.sealEngine())
{
Expand Down
5 changes: 3 additions & 2 deletions libethereum/State.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -656,12 +656,13 @@ std::pair<ExecutionResult, TransactionReceipt> State::execute(EnvInfo const& _en
return make_pair(res, receipt);
}

void State::executeBlockTransactions(Block const& _block, unsigned _txCount, LastBlockHashesFace const& _lastHashes, SealEngineFace const& _sealEngine)
void State::executeBlockTransactions(Block const& _block, unsigned _txCount,
LastBlockHashesFace const& _lastHashes, SealEngineFace const& _sealEngine)
{
u256 gasUsed = 0;
for (unsigned i = 0; i < _txCount; ++i)
{
EnvInfo envInfo(_block.info(), _lastHashes, gasUsed);
EnvInfo envInfo(_block.info(), _lastHashes, gasUsed, _sealEngine.chainParams().chainID);

Executive e(*this, envInfo, _sealEngine);
executeTransaction(e, _block.pending()[i], OnOpFunc());
Expand Down
2 changes: 1 addition & 1 deletion libevm/EVMC.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ namespace
{
evmc_revision toRevision(EVMSchedule const& _schedule) noexcept
{
if (_schedule.txDataNonZeroGas == 16)
if (_schedule.haveChainID)
return EVMC_ISTANBUL;
if (_schedule.haveCreate2 && !_schedule.eip1283Mode)
return EVMC_PETERSBURG;
Expand Down
11 changes: 7 additions & 4 deletions libevm/ExtVMFace.h
Original file line number Diff line number Diff line change
Expand Up @@ -141,14 +141,15 @@ struct CallParameters
class EnvInfo
{
public:
EnvInfo(BlockHeader const& _current, LastBlockHashesFace const& _lh, u256 const& _gasUsed)
: m_headerInfo(_current), m_lastHashes(_lh), m_gasUsed(_gasUsed)
EnvInfo(BlockHeader const& _current, LastBlockHashesFace const& _lh, u256 const& _gasUsed,
u256 const& _chainID)
: m_headerInfo(_current), m_lastHashes(_lh), m_gasUsed(_gasUsed), m_chainID(_chainID)
{}
// Constructor with custom gasLimit - used in some synthetic scenarios like eth_estimateGas RPC
// method
EnvInfo(BlockHeader const& _current, LastBlockHashesFace const& _lh, u256 const& _gasUsed,
u256 const& _gasLimit)
: EnvInfo(_current, _lh, _gasUsed)
u256 const& _gasLimit, u256 const& _chainID)
: EnvInfo(_current, _lh, _gasUsed, _chainID)
{
m_headerInfo.setGasLimit(_gasLimit);
}
Expand All @@ -162,11 +163,13 @@ class EnvInfo
u256 const& gasLimit() const { return m_headerInfo.gasLimit(); }
LastBlockHashesFace const& lastHashes() const { return m_lastHashes; }
u256 const& gasUsed() const { return m_gasUsed; }
u256 const& chainID() const { return m_chainID; }

private:
BlockHeader m_headerInfo;
LastBlockHashesFace const& m_lastHashes;
u256 m_gasUsed;
u256 m_chainID;
};

/// Represents a call result.
Expand Down
8 changes: 5 additions & 3 deletions libevm/Instruction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ namespace dev
{
namespace eth
{

// clang-format off
static const std::map<Instruction, InstructionInfo> c_instructionInfo =
{ // Args, Ret, GasPriceTier
{ Instruction::STOP, { "STOP", 0, 0, Tier::Zero } },
Expand Down Expand Up @@ -74,6 +74,7 @@ static const std::map<Instruction, InstructionInfo> c_instructionInfo =
{ Instruction::NUMBER, { "NUMBER", 0, 1, Tier::Base } },
{ Instruction::DIFFICULTY, { "DIFFICULTY", 0, 1, Tier::Base } },
{ Instruction::GASLIMIT, { "GASLIMIT", 0, 1, Tier::Base } },
{ Instruction::CHAINID, { "CHAINID", 0, 1, Tier::Base } },
{ Instruction::POP, { "POP", 1, 0, Tier::Base } },
{ Instruction::MLOAD, { "MLOAD", 1, 1, Tier::VeryLow } },
{ Instruction::MSTORE, { "MSTORE", 2, 0, Tier::VeryLow } },
Expand Down Expand Up @@ -215,8 +216,9 @@ static const std::map<Instruction, InstructionInfo> c_instructionInfo =
{ Instruction::PUSHC, { "PUSHC", 0, 1, Tier::VeryLow } },
{ Instruction::JUMPC, { "JUMPC", 1, 0, Tier::Mid } },
{ Instruction::JUMPCI, { "JUMPCI", 2, 0, Tier::High } },
};

};
// clang-format on

InstructionInfo instructionInfo(Instruction _inst)
{
auto it = c_instructionInfo.find(_inst);
Expand Down
1 change: 1 addition & 0 deletions libevm/Instruction.h
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ enum class Instruction : uint8_t
NUMBER, ///< get the block's number
DIFFICULTY, ///< get the block's difficulty
GASLIMIT, ///< get the block's gas limit
CHAINID, ///< get the network's ChainID

POP = 0x50, ///< remove item from stack
MLOAD, ///< load word from memory
Expand Down
13 changes: 13 additions & 0 deletions libevm/LegacyVM.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1439,6 +1439,19 @@ void LegacyVM::interpretCases()
}
NEXT

CASE(CHAINID)
{
ON_OP();

if (!m_schedule->haveChainID)
throwBadInstruction();

updateIOGas();

m_SPP[0] = m_ext->envInfo().chainID();
}
NEXT

CASE(POP)
{
ON_OP();
Expand Down
4 changes: 2 additions & 2 deletions libevm/LegacyVMConfig.h
Original file line number Diff line number Diff line change
Expand Up @@ -226,14 +226,14 @@ namespace dev
&&EXTCODECOPY, \
&&RETURNDATASIZE, \
&&RETURNDATACOPY, \
&&EXTCODEHASH, \
&&EXTCODEHASH, \
&&BLOCKHASH, /* 40, */ \
&&COINBASE, \
&&TIMESTAMP, \
&&NUMBER, \
&&DIFFICULTY, \
&&GASLIMIT, \
&&INVALID, \
&&CHAINID, \
&&INVALID, \
&&INVALID, \
&&INVALID, \
Expand Down
5 changes: 3 additions & 2 deletions libweb3jsonrpc/Debug.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -88,8 +88,9 @@ Json::Value Debug::traceBlock(Block const& _block, Json::Value const& _json)
Transaction t = _block.pending()[k];

u256 const gasUsed = k ? _block.receipt(k - 1).cumulativeGasUsed() : 0;
EnvInfo envInfo(_block.info(), m_eth.blockChain().lastBlockHashes(), gasUsed);
Executive e(s, envInfo, *m_eth.blockChain().sealEngine());
auto const& bc = m_eth.blockChain();
EnvInfo envInfo(_block.info(), bc.lastBlockHashes(), gasUsed, bc.chainID());
Executive e(s, envInfo, *bc.sealEngine());

eth::ExecutionResult er;
e.setResultRecipient(er);
Expand Down
4 changes: 2 additions & 2 deletions test/tools/jsontests/vm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ EnvInfo FakeExtVM::importEnv(mObject const& _o, LastBlockHashesFace const& _last
blockHeader.setTimestamp(toInt64(_o.at("currentTimestamp")));
blockHeader.setAuthor(Address(_o.at("currentCoinbase").get_str()));
blockHeader.setNumber(toUint64(_o.at("currentNumber")));
return EnvInfo(blockHeader, _lastBlockHashes, 0);
return {blockHeader, _lastBlockHashes, 0, 0};
}

mObject FakeExtVM::exportState()
Expand Down Expand Up @@ -443,7 +443,7 @@ json_spirit::mValue VmTestSuite::doTests(json_spirit::mValue const& _input, bool
BOOST_REQUIRE_MESSAGE(testInput.count("logs") > 0, testname + " logs field is missing.");
BOOST_REQUIRE_MESSAGE(testInput.at("logs").type() == str_type, testname + " logs field is not a string.");

dev::test::FakeExtVM test(eth::EnvInfo{BlockHeader{}, lastBlockHashes, 0});
dev::test::FakeExtVM test(eth::EnvInfo{BlockHeader{}, lastBlockHashes, 0, 0});
test.importState(testInput.at("post").get_obj());
test.importCallCreates(testInput.at("callcreates").get_array());

Expand Down
2 changes: 1 addition & 1 deletion test/tools/libtesteth/ImportTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -386,7 +386,7 @@ void ImportTest::importEnv(json_spirit::mObject const& _o)
header.setAuthor(Address(_o.at("currentCoinbase").get_str()));

m_lastBlockHashes.reset(new TestLastBlockHashes(lastHashes(header.number())));
m_envInfo.reset(new EnvInfo(header, *m_lastBlockHashes, 0));
m_envInfo.reset(new EnvInfo(header, *m_lastBlockHashes, 0, 0));
}

// import state from not fully declared json_spirit::mObject, writing to _stateOptionsMap which fields were defined in json
Expand Down
30 changes: 12 additions & 18 deletions test/unittests/libethereum/ExecutiveTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,12 @@ class ExecutiveTest : public testing::Test
ethash.setChainParams(ChainParams{genesisInfo(eth::Network::IstanbulTransitionTest)});
}

// called after blockHeader is set up
EnvInfo envInfo() const
{
return {blockHeader, lastBlockHashes, 0, ethash.chainParams().chainID};
}

Ethash ethash;
BlockHeader blockHeader;
TestLastBlockHashes lastBlockHashes{{}};
Expand All @@ -39,14 +45,12 @@ class ExecutiveTest : public testing::Test

TEST_F(ExecutiveTest, callUsesAccountVersion)
{
EnvInfo envInfo(blockHeader, lastBlockHashes, 0);

state.createContract(receiveAddress);
u256 version = 1;
state.setCode(receiveAddress, bytes{code}, version);
state.commit(State::CommitBehaviour::RemoveEmptyAccounts);

Executive executive(state, envInfo, ethash);
Executive executive(state, envInfo(), ethash);

bool done = executive.call(receiveAddress, txSender, txValue, gasPrice, txData, gas);

Expand All @@ -59,9 +63,7 @@ TEST_F(ExecutiveTest, createUsesLatestForkVersion)
// block in Istanbul fork
blockHeader.setNumber(10);

EnvInfo envInfo(blockHeader, lastBlockHashes, 0);

Executive executive(state, envInfo, ethash);
Executive executive(state, envInfo(), ethash);

bool done = executive.create(txSender, txValue, gasPrice, gas, ref(code), txSender);

Expand All @@ -71,14 +73,12 @@ TEST_F(ExecutiveTest, createUsesLatestForkVersion)

TEST_F(ExecutiveTest, createOpcodeUsesParentVersion)
{
EnvInfo envInfo(blockHeader, lastBlockHashes, 0);

state.createContract(txSender);
u256 version = 1;
state.setCode(txSender, bytes{code}, version);
state.commit(State::CommitBehaviour::RemoveEmptyAccounts);

Executive executive(state, envInfo, ethash);
Executive executive(state, envInfo(), ethash);

bool done = executive.createOpcode(txSender, txValue, gasPrice, gas, ref(code), txSender);

Expand All @@ -88,14 +88,12 @@ TEST_F(ExecutiveTest, createOpcodeUsesParentVersion)

TEST_F(ExecutiveTest, create2OpcodeUsesParentVersion)
{
EnvInfo envInfo(blockHeader, lastBlockHashes, 0);

state.createContract(txSender);
u256 version = 1;
state.setCode(txSender, bytes{code}, version);
state.commit(State::CommitBehaviour::RemoveEmptyAccounts);

Executive executive(state, envInfo, ethash);
Executive executive(state, envInfo(), ethash);

bool done = executive.create2Opcode(txSender, txValue, gasPrice, gas, ref(code), txSender, 0);

Expand All @@ -105,14 +103,12 @@ TEST_F(ExecutiveTest, create2OpcodeUsesParentVersion)

TEST_F(ExecutiveTest, emptyInitCodeSetsParentVersion)
{
EnvInfo envInfo(blockHeader, lastBlockHashes, 0);

state.createContract(txSender);
u256 version = 1;
state.setCode(txSender, bytes{code}, version);
state.commit(State::CommitBehaviour::RemoveEmptyAccounts);

Executive executive(state, envInfo, ethash);
Executive executive(state, envInfo(), ethash);

bytes initCode;
bool done = executive.createOpcode(txSender, txValue, gasPrice, gas, ref(initCode), txSender);
Expand All @@ -124,14 +120,12 @@ TEST_F(ExecutiveTest, emptyInitCodeSetsParentVersion)

TEST_F(ExecutiveTest, createdContractHasParentVersion)
{
EnvInfo envInfo(blockHeader, lastBlockHashes, 0);

state.createContract(txSender);
u256 version = 1;
state.setCode(txSender, bytes{code}, version);
state.commit(State::CommitBehaviour::RemoveEmptyAccounts);

Executive executive(state, envInfo, ethash);
Executive executive(state, envInfo(), ethash);

// mstore(0, 0x60)
// return(0, 0x20)
Expand Down
Loading