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

Eip86 CREATE #4046

Closed
wants to merge 30 commits into from
Closed
Show file tree
Hide file tree
Changes from 7 commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
4167f7c
Improve ccache usage
chfast Apr 14, 2017
f2b1b1a
change create tx
yann300 Apr 18, 2017
26b2f33
eip86_create
yann300 Apr 19, 2017
52422f5
thrown if address already used
yann300 Apr 19, 2017
88df551
move transaction verification checks to sealEngine
Apr 11, 2017
8201381
use BlockHeader in EnvInfo
winsvega Apr 18, 2017
d4b41c0
fixes
winsvega Apr 19, 2017
e4db842
json tests
winsvega Apr 19, 2017
d0d8fc3
MetropolisFakeExtVM
yann300 Apr 19, 2017
c348678
Merge pull request #4039 from winsvega/develop
winsvega Apr 19, 2017
de767ca
remove blockHash tests from stateTests
winsvega Apr 19, 2017
09f8b94
jsontests
winsvega Apr 19, 2017
995dbdb
remove (void)var
yann300 Apr 19, 2017
e95fdbb
check already used address only if after metropolis
yann300 Apr 19, 2017
231394a
Merge pull request #4047 from winsvega/remhash
winsvega Apr 19, 2017
6c30f3c
properly implement CREATE_PSH
yann300 Apr 19, 2017
ca3f062
remove MetropolisFakeExtVM
yann300 Apr 19, 2017
cf0bb90
fix build (evmjit)
yann300 Apr 20, 2017
d491c9d
Merge pull request #4042 from ethereum/ccache
chfast Apr 20, 2017
98b2371
change create tx
yann300 Apr 18, 2017
9931b85
eip86_create
yann300 Apr 19, 2017
8eeeace
thrown if address already used
yann300 Apr 19, 2017
22bae65
MetropolisFakeExtVM
yann300 Apr 19, 2017
406e4fd
remove (void)var
yann300 Apr 19, 2017
1fa7213
check already used address only if after metropolis
yann300 Apr 19, 2017
ffc5996
properly implement CREATE_PSH
yann300 Apr 19, 2017
4b2f69a
remove MetropolisFakeExtVM
yann300 Apr 19, 2017
99768e2
fix build (evmjit)
yann300 Apr 20, 2017
a0b8dbe
rename CREATE_PSH => CREATE_P2SH
yann300 Apr 21, 2017
dc795fd
Merge branch 'eip86_create' of github.com:ethereum/cpp-ethereum into …
yann300 Apr 21, 2017
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
2 changes: 1 addition & 1 deletion ethvm/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -299,7 +299,7 @@ int main(int argc, char** argv)
if (!code.empty())
executive.call(contractDestination, sender, value, gasPrice, &data, gas);
else
executive.create(sender, value, gasPrice, gas, &data, origin);
executive.create(sender, value, gasPrice, gas, &data, origin, Instruction::CREATE);

Timer timer;
if ((mode == Mode::Statistics || mode == Mode::Trace) && vmKind == VMKind::Interpreter)
Expand Down
1 change: 1 addition & 0 deletions libethcore/Exceptions.h
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ DEV_SIMPLE_EXCEPTION(InvalidNumber);
DEV_SIMPLE_EXCEPTION(InvalidZeroSignatureTransaction);
DEV_SIMPLE_EXCEPTION(BlockNotFound);
DEV_SIMPLE_EXCEPTION(UnknownParent);
DEV_SIMPLE_EXCEPTION(AddressAlreadyUsed);

DEV_SIMPLE_EXCEPTION(DatabaseAlreadyOpen);
DEV_SIMPLE_EXCEPTION(DAGCreationFailure);
Expand Down
19 changes: 16 additions & 3 deletions libethereum/Executive.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -251,7 +251,7 @@ bool Executive::execute()
m_s.subBalance(m_t.sender(), m_gasCost);

if (m_t.isCreation())
return create(m_t.sender(), m_t.value(), m_t.gasPrice(), m_t.gas() - (u256)m_baseGasRequired, &m_t.data(), m_t.sender());
return create(m_t.sender(), m_t.value(), m_t.gasPrice(), m_t.gas() - (u256)m_baseGasRequired, &m_t.data(), m_t.sender(), Instruction::CREATE);
else
return call(m_t.receiveAddress(), m_t.sender(), m_t.value(), m_t.gasPrice(), bytesConstRef(&m_t.data()), m_t.gas() - (u256)m_baseGasRequired);
}
Expand Down Expand Up @@ -324,7 +324,7 @@ bool Executive::call(CallParameters const& _p, u256 const& _gasPrice, Address co
return !m_ext;
}

bool Executive::create(Address _sender, u256 _endowment, u256 _gasPrice, u256 _gas, bytesConstRef _init, Address _origin)
bool Executive::create(Address _sender, u256 _endowment, u256 _gasPrice, u256 _gas, bytesConstRef _init, Address _origin, Instruction _creationType)
{
u256 nonce = m_s.getNonce(_sender);
if (_sender != MaxAddress) // EIP86
Expand All @@ -336,7 +336,17 @@ bool Executive::create(Address _sender, u256 _endowment, u256 _gasPrice, u256 _g

// We can allow for the reverted state (i.e. that with which m_ext is constructed) to contain the m_orig.address, since
// we delete it explicitly if we decide we need to revert.
m_newAddress = right160(sha3(rlpList(_sender, nonce)));
if (m_envInfo.number() >= m_sealEngine.chainParams().u256Param("Metropolis"))
{
// EIP86
Address pushedAddress = MaxAddress;
if (_creationType == Instruction::CREATE_PSH)
pushedAddress = _sender;
m_newAddress = right160(sha3(pushedAddress.asBytes() + sha3(_init).asBytes()));
}
else
m_newAddress = right160(sha3(rlpList(_sender, nonce)));

m_gas = _gas;

// Transfer ether before deploying the code. This will also create new
Expand Down Expand Up @@ -391,6 +401,9 @@ bool Executive::go(OnOpFunc const& _onOp)
auto vm = _onOp ? VMFactory::create(VMKind::Interpreter) : VMFactory::create();
if (m_isCreation)
{
if (m_envInfo.number() >= m_sealEngine.chainParams().u256Param("Metropolis") && m_s.addressHasCode(m_newAddress))
BOOST_THROW_EXCEPTION(AddressAlreadyUsed()); // EIP86

auto out = vm->exec(m_gas, *m_ext, _onOp);
if (m_res)
{
Expand Down
2 changes: 1 addition & 1 deletion libethereum/Executive.h
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ class Executive

/// Set up the executive for evaluating a bare CREATE (contract-creation) operation.
/// @returns false iff go() must be called (and thus a VM execution in required).
bool create(Address _txSender, u256 _endowment, u256 _gasPrice, u256 _gas, bytesConstRef _code, Address _originAddress);
bool create(Address _txSender, u256 _endowment, u256 _gasPrice, u256 _gas, bytesConstRef _code, Address _originAddress, Instruction _creationType);
/// Set up the executive for evaluating a bare CALL (message call) operation.
/// @returns false iff go() must be called (and thus a VM execution in required).
bool call(Address _receiveAddress, Address _txSender, u256 _txValue, u256 _gasPrice, bytesConstRef _txData, u256 _gas);
Expand Down
4 changes: 2 additions & 2 deletions libethereum/ExtVM.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -115,10 +115,10 @@ void ExtVM::setStore(u256 _n, u256 _v)
m_s.setStorage(myAddress, _n, _v);
}

h160 ExtVM::create(u256 _endowment, u256& io_gas, bytesConstRef _code, OnOpFunc const& _onOp)
h160 ExtVM::create(u256 _endowment, u256& io_gas, bytesConstRef _code, OnOpFunc const& _onOp, Instruction _creationType)
{
Executive e{m_s, envInfo(), m_sealEngine, depth + 1};
if (!e.create(myAddress, _endowment, gasPrice, io_gas, _code, origin))
if (!e.create(myAddress, _endowment, gasPrice, io_gas, _code, origin, _creationType))
{
go(depth, e, _onOp);
e.accrueSubState(sub);
Expand Down
2 changes: 1 addition & 1 deletion libethereum/ExtVM.h
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ class ExtVM: public ExtVMFace
virtual size_t codeSizeAt(Address _a) override final;

/// Create a new contract.
virtual h160 create(u256 _endowment, u256& io_gas, bytesConstRef _code, OnOpFunc const& _onOp = {}) override final;
virtual h160 create(u256 _endowment, u256& io_gas, bytesConstRef _code, OnOpFunc const& _onOp = {}, Instruction _creationType = Instruction::CREATE) override final;

/// Create a new message call. Leave _myAddressOverride as the default to use the present address as caller.
/// @returns success flag and output data, if any.
Expand Down
2 changes: 1 addition & 1 deletion libevm/ExtVMFace.h
Original file line number Diff line number Diff line change
Expand Up @@ -298,7 +298,7 @@ class ExtVMFace
virtual void suicide(Address) { sub.suicides.insert(myAddress); }

/// Create a new (contract) account.
virtual h160 create(u256, u256&, bytesConstRef, OnOpFunc const&) { return h160(); }
virtual h160 create(u256, u256&, bytesConstRef, OnOpFunc const&, Instruction) { return h160(); }
Copy link
Member

Choose a reason for hiding this comment

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

I would better make OnOpFunc parameter the last one, because it's kind of different than all the others - all others are configuring the creation and this one is a callback


/// Make a new message call.
/// @returns success flag and output data, if any.
Expand Down
8 changes: 8 additions & 0 deletions libevm/VM.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,14 @@ void VM::interpretCases()
//
// Call-related instructions
//

CASE(CREATE_PSH)
{
if (!m_schedule->haveCreatePsh)
throwBadInstruction();
m_bounce = &VM::caseCreate;
Copy link
Member

Choose a reason for hiding this comment

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

It should be available only after Metropolis and generate BadInstruction before. See for example how REVERT handles this

}
BREAK

CASE(CREATE)
{
Expand Down
2 changes: 1 addition & 1 deletion libevm/VM.h
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ class VM: public VMFace
void copyCode(int);
const void* const* c_jumpTable = 0;
bool m_caseInit = false;

typedef void (VM::*MemFnPtr)();
MemFnPtr m_bounce = 0;
MemFnPtr m_onFail = 0;
Expand Down
3 changes: 2 additions & 1 deletion libevm/VMCalls.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,8 @@ void VM::caseCreate()
if (!m_schedule->staticCallDepthLimit())
createGas -= createGas / 64;
u256 gas = createGas;
m_SPP[0] = (u160)m_ext->create(endowment, gas, bytesConstRef(m_mem.data() + initOff, initSize), m_onOp);
m_SPP[0] = (u160)m_ext->create(endowment, gas, bytesConstRef(m_mem.data() + initOff, initSize), m_onOp, m_OP);

*m_io_gas_p -= (createGas - gas);
m_io_gas = uint64_t(*m_io_gas_p);
}
Expand Down
2 changes: 2 additions & 0 deletions libevmcore/EVMSchedule.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ struct EVMSchedule
bool eip150Mode = false;
bool eip158Mode = false;
bool haveRevert = false;
bool haveCreatePsh = false;
std::array<unsigned, 8> tierStepGas;
unsigned expGas = 10;
unsigned expByteGas = 10;
Expand Down Expand Up @@ -109,6 +110,7 @@ static const EVMSchedule MetropolisSchedule = []
{
EVMSchedule schedule = EIP158Schedule;
schedule.haveRevert = true;
schedule.haveCreatePsh = true;
return schedule;
}();

Expand Down
2 changes: 2 additions & 0 deletions libevmcore/Instruction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,7 @@ const std::map<std::string, Instruction> dev::eth::c_instructions =
{ "LOG3", Instruction::LOG3 },
{ "LOG4", Instruction::LOG4 },
{ "CREATE", Instruction::CREATE },
{ "CREATE_PSH", Instruction::CREATE_PSH },
{ "CALL", Instruction::CALL },
{ "CALLCODE", Instruction::CALLCODE },
{ "RETURN", Instruction::RETURN },
Expand Down Expand Up @@ -313,6 +314,7 @@ static const std::map<Instruction, InstructionInfo> c_instructionInfo =
{ Instruction::LOG3, { "LOG3", 0, 5, 0, true, Tier::Special } },
{ Instruction::LOG4, { "LOG4", 0, 6, 0, true, Tier::Special } },
{ Instruction::CREATE, { "CREATE", 0, 3, 1, true, Tier::Special } },
{ Instruction::CREATE_PSH, { "CREATE_PSH", 0, 3, 1, true, Tier::Special } },
{ Instruction::CALL, { "CALL", 0, 7, 1, true, Tier::Special } },
{ Instruction::CALLCODE, { "CALLCODE", 0, 7, 1, true, Tier::Special } },
{ Instruction::RETURN, { "RETURN", 0, 2, 0, true, Tier::Zero } },
Expand Down
3 changes: 2 additions & 1 deletion libevmcore/Instruction.h
Original file line number Diff line number Diff line change
Expand Up @@ -183,11 +183,12 @@ enum class Instruction: uint8_t
JUMPCI, ///< conditionally alter the program counter - pre-verified
BAD, ///< placed to force invalid instruction exception

CREATE = 0xf0, ///< create a new account with associated code
CREATE = 0xf0, ///< create a new account with associated code. (since EIP86: sha3((MaxAddress + sha3(code))
CALL, ///< message-call into an account
CALLCODE, ///< message-call with another account's code only
RETURN, ///< halt execution returning output data
DELEGATECALL, ///< like CALLCODE but keeps caller's value and sender
CREATE_PSH = 0xfb, ///< create a new account with associated code. sha3((sender + sha3(code))
REVERT = 0xfd, ///< stop execution and revert state changes, without consuming all provided gas
SUICIDE = 0xff ///< halt execution and register account for later deletion
};
Expand Down
19 changes: 18 additions & 1 deletion test/tools/jsontests/vm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,9 @@ FakeExtVM::FakeExtVM(EnvInfo const& _envInfo, unsigned _depth): /// TODO: XXX:
ExtVMFace(_envInfo, Address(), Address(), Address(), 0, 1, bytesConstRef(), bytes(), EmptySHA3, _depth)
{}

h160 FakeExtVM::create(u256 _endowment, u256& io_gas, bytesConstRef _init, OnOpFunc const&)
h160 FakeExtVM::create(u256 _endowment, u256& io_gas, bytesConstRef _init, OnOpFunc const&, Instruction _creationType)
{
(void)_creationType;
Address na = right160(sha3(rlpList(myAddress, get<1>(addresses[myAddress]))));

Transaction t(_endowment, gasPrice, io_gas, _init.toBytes());
Expand Down Expand Up @@ -281,6 +282,22 @@ eth::OnOpFunc FakeExtVM::simpleTrace() const
};
}

MetropolisFakeExtVM::MetropolisFakeExtVM(EnvInfo const& _envInfo, unsigned _depth):
FakeExtVM(_envInfo, _depth)
{}

h160 MetropolisFakeExtVM::create(u256 _endowment, u256& io_gas, bytesConstRef _init, OnOpFunc const&, Instruction _creationType)
{
Address pushedAddress = MaxAddress;
if (_creationType == Instruction::CREATE_PSH)
pushedAddress = myAddress;
Address na = right160(sha3(pushedAddress.asBytes() + sha3(_init).asBytes()));

Transaction t(_endowment, gasPrice, io_gas, _init.toBytes());
callcreates.push_back(t);
return na;
}

namespace dev { namespace test {

void doVMTests(json_spirit::mValue& _v, bool _fillin)
Expand Down
9 changes: 8 additions & 1 deletion test/tools/jsontests/vm.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ class FakeExtVM: public eth::ExtVMFace
virtual void suicide(Address _a) override { std::get<0>(addresses[_a]) += std::get<0>(addresses[myAddress]); addresses.erase(myAddress); }
virtual bytes const& codeAt(Address _a) override { return std::get<3>(addresses[_a]); }
virtual size_t codeSizeAt(Address _a) override { return std::get<3>(addresses[_a]).size(); }
virtual h160 create(u256 _endowment, u256& io_gas, bytesConstRef _init, eth::OnOpFunc const&) override;
virtual h160 create(u256 _endowment, u256& io_gas, bytesConstRef _init, eth::OnOpFunc const&, eth::Instruction) override;
virtual std::pair<bool, eth::owning_bytes_ref> call(eth::CallParameters&) override;
void setTransaction(Address _caller, u256 _value, u256 _gasPrice, bytes const& _data);
void setContract(Address _myAddress, u256 _myBalance, u256 _myNonce, std::map<u256, u256> const& _storage, bytes const& _code);
Expand All @@ -80,5 +80,12 @@ class FakeExtVM: public eth::ExtVMFace
u256 execGas;
};

class MetropolisFakeExtVM: public FakeExtVM
Copy link
Member

Choose a reason for hiding this comment

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

This class looks not used

Copy link
Contributor Author

Choose a reason for hiding this comment

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

yep we will try to remove the entire fakeExtVM with @winsvega

{
public:
MetropolisFakeExtVM(eth::EnvInfo const& _envInfo, unsigned _depth = 0);
virtual h160 create(u256 _endowment, u256& io_gas, bytesConstRef _init, eth::OnOpFunc const&, eth::Instruction) override;
};


} } // Namespace Close