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

EIP 158 + 160 protocol update #3381

Merged
merged 25 commits into from
Nov 23, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
1dba464
Exp cost change.
chriseth Oct 26, 2016
47ae97b
Implement account existence / emptiness notions.
chriseth Oct 26, 2016
146cfd6
Implement effects of emptiness change.
chriseth Oct 26, 2016
04b0fa8
add EIP158 block to genesisInfo
Oct 27, 2016
803cb19
Replace bool by enum.
chriseth Oct 28, 2016
d379785
Fix isEmpty implementation for fresh accounts.
chriseth Oct 29, 2016
c85ae0c
Increment nonce for newly CREATEd accounts.
chriseth Oct 31, 2016
b004064
Remove changedness optimization for zero-value transfers.
chriseth Oct 31, 2016
e3711e4
transaction by eip155
Nov 4, 2016
5293e1e
Vitalik's tests for eip155
winsvega Nov 4, 2016
4a3c9a0
eip155 transaction update and testFillers
winsvega Nov 7, 2016
b6ad163
fix
winsvega Nov 8, 2016
6ad754d
Perform signature based chain ID check only after hard fork block.
chriseth Nov 9, 2016
bfa7983
fix eip155 transactions check before 155 block number
winsvega Nov 9, 2016
6f2fa5c
fix hash calculation for eip155 transaction
Nov 13, 2016
d0a4b8f
Update LLL code in tests to avoid using define-on-use variables
axic Nov 5, 2016
9d6a293
EIP158 testfillers and test fixes
Nov 14, 2016
90a3bd8
Limit code size (EIP170).
chriseth Nov 11, 2016
c802196
Update constant
chriseth Nov 11, 2016
e75dfff
Change max code size to 0x6000
chriseth Nov 13, 2016
403e118
eip170 codesize limit test filler
Nov 14, 2016
265e84d
restore missing transaction tests
winsvega Nov 20, 2016
02fa6ab
fix default transaction for tests
winsvega Nov 22, 2016
5dc25db
update Dragon HF blocknumber
winsvega Nov 23, 2016
8c40a2c
update code after rebase
winsvega Nov 23, 2016
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
18 changes: 15 additions & 3 deletions libethashseal/Ethash.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,9 @@ StringHashMap Ethash::jsInfo(BlockHeader const& _bi) const

EVMSchedule const& Ethash::evmSchedule(EnvInfo const& _envInfo) const
{
if (_envInfo.number() >= chainParams().u256Param("EIP150ForkBlock"))
if (_envInfo.number() >= chainParams().u256Param("EIP158ForkBlock"))
return EIP158Schedule;
else if (_envInfo.number() >= chainParams().u256Param("EIP150ForkBlock"))
return EIP150Schedule;
else if (_envInfo.number() >= chainParams().u256Param("homsteadForkBlock"))
return HomesteadSchedule;
Expand Down Expand Up @@ -165,8 +167,18 @@ void Ethash::verify(Strictness _s, BlockHeader const& _bi, BlockHeader const& _p

void Ethash::verifyTransaction(ImportRequirements::value _ir, TransactionBase const& _t, BlockHeader const& _bi) const
{
if (_ir & ImportRequirements::TransactionSignatures && _bi.number() >= chainParams().u256Param("homsteadForkBlock"))
_t.checkLowS();
if (_ir & ImportRequirements::TransactionSignatures)
{
if (_bi.number() >= chainParams().u256Param("homsteadForkBlock"))
_t.checkLowS();
if (_bi.number() >= chainParams().u256Param("EIP158ForkBlock"))
{
int chainID(chainParams().u256Param("chainID"));
_t.checkChainId(chainID);
}
else
_t.checkChainId(-4);
}
// Unneeded as it's checked again in Executive. Keep it here since tests assume it's checked.
if (_ir & ImportRequirements::TransactionBasic && _t.gasRequired(evmSchedule(EnvInfo(_bi))) > _t.gas())
BOOST_THROW_EXCEPTION(OutOfGasIntrinsic());
Expand Down
37 changes: 24 additions & 13 deletions libethashseal/GenesisInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ R"ETHEREUM(
"durationLimit": "0x08",
"blockReward": "0x14D1120D7B160000",
"registrar": "5e70c0bbcd5636e0f9f9316e9f8633feb64d4050",
"networkID" : "0x0"
"networkID" : "0x00"
},
"genesis": {
"nonce": "0x000000000000002a",
Expand Down Expand Up @@ -88,7 +88,8 @@ R"ETHEREUM(
"durationLimit": "0x0d",
"blockReward": "0x4563918244F40000",
"registrar": "",
"networkID" : "0x2"
"networkID" : "0x02",
"chainID": "0x02"
},
"genesis": {
"nonce": "0x00006d6f7264656e",
Expand Down Expand Up @@ -120,6 +121,9 @@ R"E(
"homsteadForkBlock": "0xffffffffffffffff",
"daoHardforkBlock": "0xfffffffffffffff",
"EIP150ForkBlock": "0xfffffffffffffff",
"EIP158ForkBlock": "0xfffffffffffffff",
"networkID" : "0x01",
"chainID": "0x01",
"maximumExtraDataSize": "0x20",
"tieBreakingGas": false,
"minGasLimit": "0x1388",
Expand All @@ -129,8 +133,7 @@ R"E(
"difficultyBoundDivisor": "0x0800",
"durationLimit": "0x0d",
"blockReward": "0x4563918244F40000",
"registrar" : "0xc6d9d2cd449a754c494264e1809c50e34d64562b",
"networkID" : "0x1"
"registrar" : "0xc6d9d2cd449a754c494264e1809c50e34d64562b"
},
"genesis": {
"nonce": "0x0000000000000042",
Expand Down Expand Up @@ -161,6 +164,9 @@ R"E(
"homsteadForkBlock": "0x05",
"daoHardforkBlock": "0x08",
"EIP150ForkBlock": "0x0a",
"EIP158ForkBlock": "0x0e",
"networkID" : "0x01",
"chainID": "0x01",
"maximumExtraDataSize": "0x20",
"tieBreakingGas": false,
"minGasLimit": "0x1388",
Expand All @@ -170,8 +176,7 @@ R"E(
"difficultyBoundDivisor": "0x0800",
"durationLimit": "0x0d",
"blockReward": "0x4563918244F40000",
"registrar" : "0xc6d9d2cd449a754c494264e1809c50e34d64562b",
"networkID" : "0x1"
"registrar" : "0xc6d9d2cd449a754c494264e1809c50e34d64562b"
},
"genesis": {
"nonce": "0x0000000000000042",
Expand Down Expand Up @@ -202,6 +207,9 @@ R"E(
"maximumExtraDataSize": "0x20",
"daoHardforkBlock": "0x1d4c00",
"EIP150ForkBlock": "0x259518",
"EIP158ForkBlock": "0x28d138",
"networkID" : "0x01",
"chainID": "0x01",
"minGasLimit": "0x1388",
"maxGasLimit": "7fffffffffffffff",
"tieBreakingGas": false,
Expand All @@ -210,8 +218,7 @@ R"E(
"difficultyBoundDivisor": "0x0800",
"durationLimit": "0x0d",
"blockReward": "0x4563918244F40000",
"registrar" : "0xc6d9d2cd449a754c494264e1809c50e34d64562b",
"networkID" : "0x1"
"registrar" : "0xc6d9d2cd449a754c494264e1809c50e34d64562b"
},
"genesis": {
"nonce": "0x0000000000000042",
Expand Down Expand Up @@ -240,8 +247,11 @@ R"E(
"params": {
"accountStartNonce": "0x00",
"maximumExtraDataSize": "0x20",
"daoHardforkBlock": "0xfffffff",
"daoHardforkBlock": "0xfffffffffffffff",
"EIP150ForkBlock": "0x00",
"EIP158ForkBlock": "0xfffffffffffffff",
"networkID" : "0x01",
"chainID": "0x01",
"minGasLimit": "0x1388",
"maxGasLimit": "7fffffffffffffff",
"tieBreakingGas": false,
Expand All @@ -250,8 +260,7 @@ R"E(
"difficultyBoundDivisor": "0x0800",
"durationLimit": "0x0d",
"blockReward": "0x4563918244F40000",
"registrar" : "0xc6d9d2cd449a754c494264e1809c50e34d64562b",
"networkID" : "0x1"
"registrar" : "0xc6d9d2cd449a754c494264e1809c50e34d64562b"
},
"genesis": {
"nonce": "0x0000000000000042",
Expand Down Expand Up @@ -282,6 +291,9 @@ R"E(
"homsteadForkBlock": "0x118c30",
"daoHardforkBlock": "0x1d4c00",
"EIP150ForkBlock": "0xfffffffffffffff",
"EIP158ForkBlock": "0xfffffffffffffff",
"networkID" : "0x01",
"chainID": "0x01",
"maximumExtraDataSize": "0x20",
"tieBreakingGas": false,
"minGasLimit": "0x1388",
Expand All @@ -291,8 +303,7 @@ R"E(
"difficultyBoundDivisor": "0x0800",
"durationLimit": "0x0d",
"blockReward": "0x4563918244F40000",
"registrar" : "0xc6d9d2cd449a754c494264e1809c50e34d64562b",
"networkID" : "0x1"
"registrar" : "0xc6d9d2cd449a754c494264e1809c50e34d64562b"
},
"genesis": {
"nonce": "0x0000000000000042",
Expand Down
44 changes: 40 additions & 4 deletions libethcore/Transaction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -64,10 +64,20 @@ TransactionBase::TransactionBase(bytesConstRef _rlpData, CheckTransaction _check
BOOST_THROW_EXCEPTION(InvalidTransactionFormat() << errinfo_comment("transaction data RLP must be an array"));

m_data = rlp[field = 5].toBytes();
byte v = rlp[field = 6].toInt<byte>() - 27;

byte v = rlp[field = 6].toInt<byte>();
h256 r = rlp[field = 7].toInt<u256>();
h256 s = rlp[field = 8].toInt<u256>();

if (v > 36)
m_chainId = (v - 35) / 2;
else if (v == 27 || v == 28)
m_chainId = -4;
else
BOOST_THROW_EXCEPTION(InvalidSignature());

v = v - (m_chainId * 2 + 35);

if (rlp.itemCount() > 9)
BOOST_THROW_EXCEPTION(InvalidTransactionFormat() << errinfo_comment("to many fields in the transaction RLP"));

Expand Down Expand Up @@ -116,19 +126,26 @@ void TransactionBase::sign(Secret const& _priv)
m_vrs = sigStruct;
}

void TransactionBase::streamRLP(RLPStream& _s, IncludeSignature _sig) const
void TransactionBase::streamRLP(RLPStream& _s, IncludeSignature _sig, bool _forEip155hash) const
{
if (m_type == NullTransaction)
return;
_s.appendList((_sig ? 3 : 0) + 6);

_s.appendList((_sig || _forEip155hash ? 3 : 0) + 6);
_s << m_nonce << m_gasPrice << m_gas;
if (m_type == MessageCall)
_s << m_receiveAddress;
else
_s << "";
_s << m_value << m_data;

if (_sig)
_s << (m_vrs.v + 27) << (u256)m_vrs.r << (u256)m_vrs.s;
{
int vOffset = m_chainId*2 + 35;
_s << (m_vrs.v + vOffset) << (u256)m_vrs.r << (u256)m_vrs.s;
}
else if (_forEip155hash)
_s << m_chainId << 0 << 0;
}

static const u256 c_secp256k1n("115792089237316195423570985008687907852837564279074904382605163141518161494337");
Expand All @@ -139,6 +156,12 @@ void TransactionBase::checkLowS() const
BOOST_THROW_EXCEPTION(InvalidSignature());
}

void TransactionBase::checkChainId(int chainId) const
{
if (m_chainId != chainId && m_chainId != -4)
BOOST_THROW_EXCEPTION(InvalidSignature());
}

bigint TransactionBase::gasRequired(bool _contractCreation, bytesConstRef _data, EVMSchedule const& _es, u256 const& _gas)
{
bigint ret = (_contractCreation ? _es.txCreateGas : _es.txGas) + _gas;
Expand All @@ -147,3 +170,16 @@ bigint TransactionBase::gasRequired(bool _contractCreation, bytesConstRef _data,
return ret;
}

h256 TransactionBase::sha3(IncludeSignature _sig) const
{
if (_sig == WithSignature && m_hashWith)
return m_hashWith;

RLPStream s;
streamRLP(s, _sig, m_chainId > 0 && _sig == WithoutSignature);

auto ret = dev::sha3(s.out());
if (_sig == WithSignature)
m_hashWith = ret;
return ret;
}
10 changes: 8 additions & 2 deletions libethcore/Transaction.h
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,11 @@ class TransactionBase
/// @throws InvalidSValue if the signature has an invalid S value.
void checkLowS() const;

/// @throws InvalidSValue if the chain id is neither -4 nor equal to @a chainId
/// Note that "-4" is the chain ID of the pre-155 rules, which should also be considered valid
/// after EIP155
void checkChainId(int chainId = -4) const;

/// @returns true if transaction is non-null.
explicit operator bool() const { return m_type != NullTransaction; }

Expand All @@ -99,13 +104,13 @@ class TransactionBase
bool isMessageCall() const { return m_type == MessageCall; }

/// Serialises this transaction to an RLPStream.
void streamRLP(RLPStream& _s, IncludeSignature _sig = WithSignature) const;
void streamRLP(RLPStream& _s, IncludeSignature _sig = WithSignature, bool _forEip155hash = false) const;

/// @returns the RLP serialisation of this transaction.
bytes rlp(IncludeSignature _sig = WithSignature) const { RLPStream s; streamRLP(s, _sig); return s.out(); }

/// @returns the SHA3 hash of the RLP serialisation of this transaction.
h256 sha3(IncludeSignature _sig = WithSignature) const { if (_sig == WithSignature && m_hashWith) return m_hashWith; RLPStream s; streamRLP(s, _sig); auto ret = dev::sha3(s.out()); if (_sig == WithSignature) m_hashWith = ret; return ret; }
h256 sha3(IncludeSignature _sig = WithSignature) const;

/// @returns the amount of ETH to be transferred by this (message-call) transaction, in Wei. Synonym for endowment().
u256 value() const { return m_value; }
Expand Down Expand Up @@ -169,6 +174,7 @@ class TransactionBase
u256 m_gas; ///< The total gas to convert, paid for from sender's account. Any unused gas gets refunded once the contract is ended.
bytes m_data; ///< The data associated with the transaction, or the initialiser if it's a creation transaction.
SignatureStruct m_vrs; ///< The signature of the transaction. Encodes the sender.
int m_chainId = -4; ///< EIP155 value for calculating transaction hash https://github.com/ethereum/EIPs/issues/155

mutable h256 m_hashWith; ///< Cached hash of transaction with signature.
mutable Address m_sender; ///< Cached sender, determined from signature.
Expand Down
5 changes: 4 additions & 1 deletion libethereum/Account.h
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,9 @@ class Account
/// @returns true if the account is unchanged from creation.
bool isDirty() const { return !m_isUnchanged; }

/// @returns true if the nonce, balance and code is zero / empty. Code is considered empty
/// during creation phase.
bool isEmpty() const { return nonce() == 0 && balance() == 0 && (isFreshCode() ? code().empty() : codeHash() == EmptySHA3); }

/// @returns the balance of this account. Can be altered in place.
u256& balance() { return m_balance; }
Expand All @@ -119,7 +122,7 @@ class Account
u256 const& balance() const { return m_balance; }

/// Increments the balance of this account by the given amount. It's a bigint, so can be negative.
void addBalance(bigint _i) { if (!_i) return; m_balance = (u256)((bigint)m_balance + _i); changed(); }
void addBalance(bigint _i) { m_balance = (u256)((bigint)m_balance + _i); changed(); }

/// @returns the nonce of the account. Can be altered in place.
u256& nonce() { return m_nonce; }
Expand Down
9 changes: 6 additions & 3 deletions libethereum/Block.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -625,8 +625,9 @@ u256 Block::enact(VerifiedBlockRef const& _block, BlockChain const& _bc)
applyRewards(rewarded, _bc.chainParams().blockReward);

// Commit all cached state changes to the state trie.
bool removeEmptyAccounts = m_currentBlock.number() >= _bc.chainParams().u256Param("EIP158ForkBlock");
DEV_TIMED_ABOVE("commit", 500)
m_state.commit();
m_state.commit(removeEmptyAccounts ? State::CommitBehaviour::RemoveEmptyAccounts : State::CommitBehaviour::KeepEmptyAccounts);

// Hash the state trie and check against the state_root hash in m_currentBlock.
if (m_currentBlock.stateRoot() != m_previousBlock.stateRoot() && m_currentBlock.stateRoot() != rootHash())
Expand Down Expand Up @@ -688,7 +689,7 @@ void Block::performIrregularModifications()
Addresses allDAOs = childDaos();
for (Address const& dao: allDAOs)
m_state.transferBalance(dao, recipient, m_state.balance(dao));
m_state.commit();
m_state.commit(State::CommitBehaviour::KeepEmptyAccounts);
}
}

Expand Down Expand Up @@ -768,7 +769,9 @@ void Block::commitToSeal(BlockChain const& _bc, bytes const& _extraData)
applyRewards(uncleBlockHeaders, _bc.chainParams().blockReward);

// Commit any and all changes to the trie that are in the cache, then update the state root accordingly.
m_state.commit();
bool removeEmptyAccounts = m_currentBlock.number() >= _bc.chainParams().u256Param("EIP158ForkBlock");
DEV_TIMED_ABOVE("commit", 500)
m_state.commit(removeEmptyAccounts ? State::CommitBehaviour::RemoveEmptyAccounts : State::CommitBehaviour::KeepEmptyAccounts);

clog(StateDetail) << "Post-reward stateRoot:" << m_state.rootHash();
clog(StateDetail) << m_state;
Expand Down
7 changes: 5 additions & 2 deletions libethereum/Executive.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -310,7 +310,8 @@ bool Executive::create(Address _sender, u256 _endowment, u256 _gasPrice, u256 _g
if (!_init.empty())
m_ext = make_shared<ExtVM>(m_s, m_envInfo, m_sealEngine, m_newAddress, _sender, _origin, _endowment, _gasPrice, bytesConstRef(), _init, sha3(_init), m_depth);

m_s.createContract(m_newAddress);
bool incrementNonce = m_envInfo.number() >= m_sealEngine.chainParams().u256Param("EIP158ForkBlock");
m_s.createContract(m_newAddress, incrementNonce);
m_s.transferBalance(_sender, m_newAddress, _endowment);

if (_init.empty())
Expand Down Expand Up @@ -358,7 +359,9 @@ bool Executive::go(OnOpFunc const& _onOp)
m_res->gasForDeposit = m_gas;
m_res->depositSize = out.size();
}
if (out.size() * m_ext->evmSchedule().createDataGas <= m_gas)
if (out.size() > m_ext->evmSchedule().maxCodeSize)
BOOST_THROW_EXCEPTION(OutOfGas());
else if (out.size() * m_ext->evmSchedule().createDataGas <= m_gas)
{
if (m_res)
m_res->codeDeposit = CodeDeposit::Success;
Expand Down
8 changes: 7 additions & 1 deletion libethereum/ExtVM.h
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,13 @@ class ExtVM: public ExtVMFace
virtual u256 balance(Address _a) override final { return m_s.balance(_a); }

/// Does the account exist?
virtual bool exists(Address _a) override final { return m_s.addressInUse(_a); }
virtual bool exists(Address _a) override final
{
if (evmSchedule().emptinessIsNonexistence())
return m_s.accountNonemptyAndExisting(_a);
else
return m_s.addressInUse(_a);
}

/// Suicide the associated contract to the given address.
virtual void suicide(Address _a) override final
Expand Down
Loading