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

Implement EIP-1884: Repricing for trie-size-dependent opcodes in LegacyVM #5700

Merged
merged 4 commits into from
Sep 2, 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
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
- Added: [#5640](https://github.com/ethereum/aleth/pull/5640) Support EIP-1702 Generalized Account Versioning Scheme (active only in Experimental fork.)
- 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) [#5708](https://github.com/ethereum/aleth/pull/5708) Istanbul support: EIP-1344 ChainID opcode.
- Added: [#5700](https://github.com/ethereum/aleth/pull/5700) Istanbul support: EIP 1884 Repricing for trie-size-dependent opcodes.
- Added: [#5701](https://github.com/ethereum/aleth/issues/5701) Outputs ENR text representation in admin.nodeInfo RPC.
- Added: [#5705](https://github.com/ethereum/aleth/pull/5705) Istanbul support: EIP 1108 Reduce alt_bn128 precompile gas costs.
- Added: [#5707](https://github.com/ethereum/aleth/pull/5707) Aleth waits for 2 seconds after sending disconnect to peer before closing socket.
Expand Down
5 changes: 5 additions & 0 deletions libethcore/EVMSchedule.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ struct EVMSchedule
bool haveCreate2 = false;
bool haveExtcodehash = false;
bool haveChainID = false;
bool haveSelfbalance = false;
std::array<unsigned, 8> tierStepGas;
unsigned expGas = 10;
unsigned expByteGas = 10;
Expand Down Expand Up @@ -151,7 +152,11 @@ static const EVMSchedule ConstantinopleFixSchedule = [] {
static const EVMSchedule IstanbulSchedule = [] {
EVMSchedule schedule = ConstantinopleFixSchedule;
schedule.txDataNonZeroGas = 16;
schedule.sloadGas = 800;
schedule.balanceGas = 700;
schedule.extcodehashGas = 700;
schedule.haveChainID = true;
schedule.haveSelfbalance = true;
return schedule;
}();

Expand Down
3 changes: 2 additions & 1 deletion libevm/Instruction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ static const std::map<Instruction, InstructionInfo> c_instructionInfo =
{ Instruction::DIFFICULTY, { "DIFFICULTY", 0, 1, Tier::Base } },
{ Instruction::GASLIMIT, { "GASLIMIT", 0, 1, Tier::Base } },
{ Instruction::CHAINID, { "CHAINID", 0, 1, Tier::Base } },
{ Instruction::SELFBALANCE, { "SELFBALANCE", 0, 1, Tier::Low } },
{ 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 @@ -229,4 +230,4 @@ InstructionInfo instructionInfo(Instruction _inst)


}
}
}
15 changes: 8 additions & 7 deletions libevm/Instruction.h
Original file line number Diff line number Diff line change
Expand Up @@ -75,13 +75,14 @@ enum class Instruction : uint8_t
RETURNDATACOPY = 0x3e, ///< copy data returned from previous call to memory
EXTCODEHASH = 0x3f, ///< get external code hash

BLOCKHASH = 0x40, ///< get hash of most recent complete block
COINBASE, ///< get the block's coinbase address
TIMESTAMP, ///< get the block's timestamp
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
BLOCKHASH = 0x40, ///< get hash of most recent complete block
COINBASE, ///< get the block's coinbase address
TIMESTAMP, ///< get the block's timestamp
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
SELFBALANCE, ///< get balance of the current address

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 @@ -1452,6 +1452,19 @@ void LegacyVM::interpretCases()
}
NEXT

CASE(SELFBALANCE)
{
ON_OP();

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

updateIOGas();

m_SPP[0] = m_ext->balance(m_ext->myAddress);
}
NEXT

CASE(POP)
{
ON_OP();
Expand Down
2 changes: 1 addition & 1 deletion libevm/LegacyVMConfig.h
Original file line number Diff line number Diff line change
Expand Up @@ -234,7 +234,7 @@ namespace dev
&&DIFFICULTY, \
&&GASLIMIT, \
&&CHAINID, \
&&INVALID, \
&&SELFBALANCE, \
&&INVALID, \
&&INVALID, \
&&INVALID, \
Expand Down
96 changes: 96 additions & 0 deletions test/unittests/libevm/VMTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -577,6 +577,84 @@ class AlethInterpreterChainIDTestFixture : public ChainIDTestFixture
{}
};

class SelfBalanceFixture : public TestOutputHelperFixture
{
public:
explicit SelfBalanceFixture(VMFace* _vm) : vm{_vm} { state.addBalance(address, 1 * ether); }

void testSelfBalanceWorksInIstanbul()
{
ExtVM extVm(state, envInfo, *se, address, address, address, value, gasPrice, {}, ref(code),
sha3(code), version, depth, isCreate, staticCall);

owning_bytes_ref ret = vm->exec(gas, extVm, OnOpFunc{});

BOOST_REQUIRE_EQUAL(fromBigEndian<u256>(ret), 1 * ether);
}

void testSelfBalanceHasCorrectCost()
{
ExtVM extVm(state, envInfo, *se, address, address, address, value, gasPrice, {}, ref(code),
sha3(code), version, depth, isCreate, staticCall);

bigint gasBefore;
bigint gasAfter;
auto onOp = [&gasBefore, &gasAfter](uint64_t /*steps*/, uint64_t /* PC */,
Instruction _instr, bigint /*newMemSize*/, bigint /*gasCost*/, bigint _gas,
VMFace const*, ExtVMFace const*) {
if (_instr == Instruction::SELFBALANCE)
gasBefore = _gas;
else if (gasBefore != 0 && gasAfter == 0)
gasAfter = _gas;
};

vm->exec(gas, extVm, onOp);

BOOST_REQUIRE_EQUAL(gasBefore - gasAfter, 5);
}

void testSelfBalanceisInvalidBeforeIstanbul()
{
se.reset(ChainParams(genesisInfo(Network::ConstantinopleFixTest)).createSealEngine());
version = ConstantinopleFixSchedule.accountVersion;
Copy link
Contributor

Choose a reason for hiding this comment

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

How come the account version is available in the Constantinople Fix schedule..do we need to reference it in this test since from what I understand it's been punted to post-Istanbul?

Copy link
Member Author

Choose a reason for hiding this comment

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

Versioning still exists in the code for all forks, with version being 0 in all forks before we activate version 1 (currently it's Experimental fork)

This line is actually redundant.


ExtVM extVm(state, envInfo, *se, address, address, address, value, gasPrice, {}, ref(code),
sha3(code), version, depth, isCreate, staticCall);

BOOST_REQUIRE_THROW(vm->exec(gas, extVm, OnOpFunc{}), BadInstruction);
}


BlockHeader blockHeader{initBlockHeader()};
LastBlockHashes lastBlockHashes;
Address address{KeyPair::create().address()};
State state{0};
std::unique_ptr<SealEngineFace> se{
ChainParams(genesisInfo(Network::IstanbulTest)).createSealEngine()};
EnvInfo envInfo{blockHeader, lastBlockHashes, 0, se->chainParams().chainID};

u256 value = 0;
u256 gasPrice = 1;
u256 version = IstanbulSchedule.accountVersion;
int depth = 0;
bool isCreate = false;
bool staticCall = false;
u256 gas = 1000000;

// let b : = selfbalance()
// mstore(0, b)
// return(0, 32)
bytes code = fromHex("478060005260206000f350");

std::unique_ptr<VMFace> vm;
};

class LegacyVMSelfBalanceFixture : public SelfBalanceFixture
{
public:
LegacyVMSelfBalanceFixture() : SelfBalanceFixture{new LegacyVM} {}
};

} // namespace

BOOST_FIXTURE_TEST_SUITE(LegacyVMSuite, TestOutputHelperFixture)
Expand Down Expand Up @@ -774,6 +852,24 @@ BOOST_AUTO_TEST_CASE(LegacyVMChainIDisInvalidBeforeIstanbul)
}
BOOST_AUTO_TEST_SUITE_END()

BOOST_FIXTURE_TEST_SUITE(LegacyVMSelfBalanceSuite, LegacyVMSelfBalanceFixture)

BOOST_AUTO_TEST_CASE(LegacyVMSelfBalanceworksInIstanbul)
{
testSelfBalanceWorksInIstanbul();
}

BOOST_AUTO_TEST_CASE(LegacyVMSelfBalanceHasCorrectCost)
{
testSelfBalanceHasCorrectCost();
}

BOOST_AUTO_TEST_CASE(LegacyVMSelfBalanceisInvalidBeforeIstanbul)
{
testSelfBalanceisInvalidBeforeIstanbul();
}
BOOST_AUTO_TEST_SUITE_END()

BOOST_AUTO_TEST_SUITE_END()

BOOST_FIXTURE_TEST_SUITE(AlethInterpreterSuite, TestOutputHelperFixture)
Expand Down