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

Commit

Permalink
EIP166 - check that high-order bits of transaction nonce are either 0…
Browse files Browse the repository at this point in the history
… or CHAIN_ID
  • Loading branch information
gumb0 committed Mar 8, 2017
1 parent 2a7fcc8 commit 0a3e302
Show file tree
Hide file tree
Showing 14 changed files with 64 additions and 8 deletions.
15 changes: 12 additions & 3 deletions libethashseal/Ethash.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -158,9 +158,18 @@ void Ethash::verifyTransaction(ImportRequirements::value _ir, TransactionBase co
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.baseGasRequired(evmSchedule(EnvInfo(_bi))) > _t.gas())
BOOST_THROW_EXCEPTION(OutOfGasIntrinsic());
if (_ir & ImportRequirements::TransactionBasic)
{
if (_bi.number() >= chainParams().u256Param("metropolisForkBlock"))
{
unsigned const nonceChainId(chainParams().u256Param("nonceChainID"));
_t.checkNonceChainId(nonceChainId);
}

// Unneeded as it's checked again in Executive. Keep it here since tests assume it's checked.
if (_t.baseGasRequired(evmSchedule(EnvInfo(_bi))) > _t.gas())
BOOST_THROW_EXCEPTION(OutOfGasIntrinsic());
}
}

u256 Ethash::childGasLimit(BlockHeader const& _bi, u256 const& _gasFloorTarget) const
Expand Down
1 change: 1 addition & 0 deletions libethashseal/genesis/eip150Test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ R"E(
"metropolisForkBlock": "0xfffffffffffffff",
"networkID" : "0x01",
"chainID": "0x01",
"nonceChainID": "0x12",
"minGasLimit": "0x1388",
"maxGasLimit": "7fffffffffffffff",
"tieBreakingGas": false,
Expand Down
3 changes: 2 additions & 1 deletion libethashseal/genesis/eip158Test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,8 @@ R"E(
"durationLimit": "0x0d",
"blockReward": "0x4563918244F40000",
"registrar" : "0xc6d9d2cd449a754c494264e1809c50e34d64562b",
"networkID" : "0x1"
"networkID" : "0x1",
"nonceChainID": "0x12"
},
"genesis": {
"nonce": "0x0000000000000042",
Expand Down
1 change: 1 addition & 0 deletions libethashseal/genesis/frontierTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ R"E(
"metropolisForkBlock": "0xfffffffffffffff",
"networkID" : "0x01",
"chainID": "0x01",
"nonceChainID": "0x12",
"maximumExtraDataSize": "0x20",
"tieBreakingGas": false,
"minGasLimit": "0x1388",
Expand Down
1 change: 1 addition & 0 deletions libethashseal/genesis/homesteadTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ R"E(
"metropolisForkBlock": "0xfffffffffffffff",
"networkID" : "0x01",
"chainID": "0x01",
"nonceChainID": "0x12",
"minGasLimit": "0x1388",
"maxGasLimit": "7fffffffffffffff",
"tieBreakingGas": false,
Expand Down
1 change: 1 addition & 0 deletions libethashseal/genesis/mainNetwork.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ R"E(
"metropolisForkBlock": "0xffffffffffffffffff",
"networkID" : "0x01",
"chainID": "0x01",
"nonceChainID": "0x12",
"maximumExtraDataSize": "0x20",
"tieBreakingGas": false,
"minGasLimit": "0x1388",
Expand Down
1 change: 1 addition & 0 deletions libethashseal/genesis/mainNetworkTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ R"E(
"metropolisForkBlock": "0xfffffffffffffff",
"networkID" : "0x01",
"chainID": "0x01",
"nonceChainID": "0x12",
"maximumExtraDataSize": "0x20",
"tieBreakingGas": false,
"minGasLimit": "0x1388",
Expand Down
3 changes: 2 additions & 1 deletion libethashseal/genesis/metropolisTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,8 @@ R"E(
"durationLimit": "0x0d",
"blockReward": "0x4563918244F40000",
"registrar" : "0xc6d9d2cd449a754c494264e1809c50e34d64562b",
"networkID" : "0x1"
"networkID" : "0x1",
"nonceChainID": "0x12"
},
"genesis": {
"nonce": "0x0000000000000042",
Expand Down
3 changes: 2 additions & 1 deletion libethashseal/genesis/ropsten.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,8 @@ R"E(
"durationLimit": "0x0d",
"blockReward": "0x4563918244F40000",
"registrar": "",
"networkID" : "0x03"
"networkID" : "0x03",
"nonceChainID": "0x1c"
},
"genesis": {
"nonce": "0x0000000000000042",
Expand Down
1 change: 1 addition & 0 deletions libethashseal/genesis/transitionnetTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ R"E(
"metropolisForkBlock": "0xfffffffffffffff",
"networkID" : "0x01",
"chainID": "0x01",
"nonceChainID": "0x12",
"maximumExtraDataSize": "0x20",
"tieBreakingGas": false,
"minGasLimit": "0x1388",
Expand Down
1 change: 1 addition & 0 deletions libethcore/Exceptions.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ DEV_SIMPLE_EXCEPTION(TooMuchGasUsed);
DEV_SIMPLE_EXCEPTION(ExtraDataTooBig);
DEV_SIMPLE_EXCEPTION(ExtraDataIncorrect);
DEV_SIMPLE_EXCEPTION(InvalidSignature);
DEV_SIMPLE_EXCEPTION(InvalidChainIdInNonce);
DEV_SIMPLE_EXCEPTION(InvalidTransactionFormat);
DEV_SIMPLE_EXCEPTION(InvalidBlockFormat);
DEV_SIMPLE_EXCEPTION(InvalidUnclesHash);
Expand Down
12 changes: 12 additions & 0 deletions libethcore/Transaction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,11 @@ using namespace std;
using namespace dev;
using namespace dev::eth;

namespace
{
int const c_chainIdInNonceBits = 64;
}

TransactionBase::TransactionBase(TransactionSkeleton const& _ts, Secret const& _s):
m_type(_ts.creation ? ContractCreation : MessageCall),
m_nonce(_ts.nonce),
Expand Down Expand Up @@ -163,6 +168,13 @@ void TransactionBase::checkChainId(int chainId) const
BOOST_THROW_EXCEPTION(InvalidSignature());
}

void TransactionBase::checkNonceChainId(unsigned _chainId) const
{
unsigned const nonceChainId = static_cast<unsigned>(m_nonce >> c_chainIdInNonceBits);
if (nonceChainId != _chainId && nonceChainId != 0)
BOOST_THROW_EXCEPTION(InvalidChainIdInNonce());
}

int64_t TransactionBase::baseGasRequired(bool _contractCreation, bytesConstRef _data, EVMSchedule const& _es)
{
int64_t g = _contractCreation ? _es.txCreateGas : _es.txGas;
Expand Down
8 changes: 6 additions & 2 deletions libethcore/Transaction.h
Original file line number Diff line number Diff line change
Expand Up @@ -86,14 +86,18 @@ class TransactionBase
/// Force the sender to a particular value. This will result in an invalid transaction RLP.
void forceSender(Address const& _a) { m_sender = _a; }

/// @throws InvalidSValue if the signature has an invalid S value.
/// @throws InvalidSignature 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
/// @throws InvalidSignature 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;

/// @throws InvalidChainIdInNonce if the chain id encoded in high-order bits of nonce is neither 0 nor equal to @a _chainId
/// 0 is the chain ID of the pre-EIP166 rules, which should also be considered valid after EIP166
void checkNonceChainId(unsigned _chainId) const;

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

Expand Down
21 changes: 21 additions & 0 deletions test/libethereum/Transaction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -147,4 +147,25 @@ BOOST_AUTO_TEST_CASE(toTransactionExceptionConvert)
BOOST_CHECK_MESSAGE(toTransactionException(notEx) == TransactionException::Unknown, "Unexpected should be TransactionException::Unknown");
}

BOOST_AUTO_TEST_CASE(NonceChainIdZeroAllowed)
{
u256 nonce = 123;
Transaction tr(1, 1, 1, Address(), bytes(), nonce);
tr.checkNonceChainId(456); // check that it doesn't throw
}

BOOST_AUTO_TEST_CASE(RequiredChainIdAllowed)
{
u256 nonce = (u256(28) << 64) + 123;
Transaction tr(1, 1, 1, Address(), bytes(), nonce);
tr.checkNonceChainId(28); // check that it doesn't throw
}

BOOST_AUTO_TEST_CASE(IncorrectChainIdNotAllowed)
{
u256 nonce = (u256(28) << 64) + 123;
Transaction tr(1, 1, 1, Address(), bytes(), nonce);
BOOST_CHECK_THROW(tr.checkNonceChainId(18), InvalidChainIdInNonce);
}

BOOST_AUTO_TEST_SUITE_END()

0 comments on commit 0a3e302

Please sign in to comment.