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

Commit

Permalink
Merge pull request #5700 from ethereum/eip-1884
Browse files Browse the repository at this point in the history
Implement EIP-1884: Repricing for trie-size-dependent opcodes in LegacyVM
  • Loading branch information
gumb0 authored Sep 2, 2019
2 parents 9ec9d33 + c95460c commit 02ca548
Show file tree
Hide file tree
Showing 7 changed files with 126 additions and 9 deletions.
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 @@ -150,7 +151,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 @@ -1456,6 +1456,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;

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

0 comments on commit 02ca548

Please sign in to comment.