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

Commit

Permalink
Merge pull request #5705 from ethereum/eip-1108
Browse files Browse the repository at this point in the history
Implement EIP-1108: Reduce alt_bn128 precompile gas costs
  • Loading branch information
gumb0 authored Aug 22, 2019
2 parents ae1208b + c587337 commit 7e6095d
Show file tree
Hide file tree
Showing 9 changed files with 131 additions and 34 deletions.
3 changes: 2 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,9 @@
- Added: [#5634](https://github.com/ethereum/aleth/pull/5634) Bootnodes for Rinkeby and Goerli.
- 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/5708) [#5696](https://github.com/ethereum/aleth/pull/5708) Istanbul support: EIP-1344 ChainID opcode.
- Added: [#5696](https://github.com/ethereum/aleth/pull/5696) [#5708](https://github.com/ethereum/aleth/pull/5708) Istanbul support: EIP-1344 ChainID opcode.
- 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.
- Changed: [#5532](https://github.com/ethereum/aleth/pull/5532) The leveldb is upgraded to 1.22. This is breaking change on Windows and the old databases are not compatible.
- Changed: [#5559](https://github.com/ethereum/aleth/pull/5559) Update peer validation error messages.
Expand Down
4 changes: 2 additions & 2 deletions libethashseal/genesis/test/istanbulTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,8 @@ R"E(
"0000000000000000000000000000000000000003": { "precompiled": { "name": "ripemd160", "linear": { "base": 600, "word": 120 } } },
"0000000000000000000000000000000000000004": { "precompiled": { "name": "identity", "linear": { "base": 15, "word": 3 } } },
"0000000000000000000000000000000000000005": { "precompiled": { "name": "modexp" } },
"0000000000000000000000000000000000000006": { "precompiled": { "name": "alt_bn128_G1_add", "linear": { "base": 500, "word": 0 } } },
"0000000000000000000000000000000000000007": { "precompiled": { "name": "alt_bn128_G1_mul", "linear": { "base": 40000, "word": 0 } } },
"0000000000000000000000000000000000000006": { "precompiled": { "name": "alt_bn128_G1_add" } },
"0000000000000000000000000000000000000007": { "precompiled": { "name": "alt_bn128_G1_mul" } },
"0000000000000000000000000000000000000008": { "precompiled": { "name": "alt_bn128_pairing_product" } }
}
}
Expand Down
4 changes: 2 additions & 2 deletions libethashseal/genesis/test/istanbulTransitionTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,8 @@ R"E(
"0000000000000000000000000000000000000003": { "precompiled": { "name": "ripemd160", "linear": { "base": 600, "word": 120 } } },
"0000000000000000000000000000000000000004": { "precompiled": { "name": "identity", "linear": { "base": 15, "word": 3 } } },
"0000000000000000000000000000000000000005": { "precompiled": { "name": "modexp" } },
"0000000000000000000000000000000000000006": { "precompiled": { "name": "alt_bn128_G1_add", "linear": { "base": 500, "word": 0 } } },
"0000000000000000000000000000000000000007": { "precompiled": { "name": "alt_bn128_G1_mul", "linear": { "base": 40000, "word": 0 } } },
"0000000000000000000000000000000000000006": { "precompiled": { "name": "alt_bn128_G1_add" } },
"0000000000000000000000000000000000000007": { "precompiled": { "name": "alt_bn128_G1_mul" } },
"0000000000000000000000000000000000000008": { "precompiled": { "name": "alt_bn128_pairing_product"} }
}
}
Expand Down
21 changes: 9 additions & 12 deletions libethcore/ChainOperationParams.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,18 +27,15 @@ using namespace dev;
using namespace eth;

PrecompiledContract::PrecompiledContract(
unsigned _base,
unsigned _word,
PrecompiledExecutor const& _exec,
u256 const& _startingBlock
):
PrecompiledContract([=](bytesConstRef _in) -> bigint
{
bigint s = _in.size();
bigint b = _base;
bigint w = _word;
return b + (s + 31) / 32 * w;
}, _exec, _startingBlock)
unsigned _base, unsigned _word, PrecompiledExecutor const& _exec, u256 const& _startingBlock)
: PrecompiledContract(
[=](bytesConstRef _in, ChainOperationParams const&, u256 const&) -> bigint {
bigint s = _in.size();
bigint b = _base;
bigint w = _word;
return b + (s + 31) / 32 * w;
},
_exec, _startingBlock)
{}

ChainOperationParams::ChainOperationParams():
Expand Down
6 changes: 5 additions & 1 deletion libethcore/ChainOperationParams.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,11 @@ class PrecompiledContract
u256 const& _startingBlock = 0
);

bigint cost(bytesConstRef _in) const { return m_cost(_in); }
bigint cost(
bytesConstRef _in, ChainOperationParams const& _chainParams, u256 const& _blockNumber) const
{
return m_cost(_in, _chainParams, _blockNumber);
}
std::pair<bool, bytes> execute(bytesConstRef _in) const { return m_execute(_in); }

u256 const& startingBlock() const { return m_startingBlock; }
Expand Down
23 changes: 19 additions & 4 deletions libethcore/Precompiled.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,11 @@
*/

#include "Precompiled.h"
#include "ChainOperationParams.h"
#include <libdevcore/Log.h>
#include <libdevcore/SHA3.h>
#include <libdevcrypto/Hash.h>
#include <libdevcrypto/Common.h>
#include <libdevcrypto/Hash.h>
#include <libdevcrypto/LibSnark.h>
#include <libethcore/Common.h>
using namespace std;
Expand Down Expand Up @@ -172,7 +173,7 @@ namespace
}
}

ETH_REGISTER_PRECOMPILED_PRICER(modexp)(bytesConstRef _in)
ETH_REGISTER_PRECOMPILED_PRICER(modexp)(bytesConstRef _in, ChainOperationParams const&, u256 const&)
{
bigint const baseLength(parseBigEndianRightPadded(_in, 0, 32));
bigint const expLength(parseBigEndianRightPadded(_in, 32, 32));
Expand All @@ -189,19 +190,33 @@ ETH_REGISTER_PRECOMPILED(alt_bn128_G1_add)(bytesConstRef _in)
return dev::crypto::alt_bn128_G1_add(_in);
}

ETH_REGISTER_PRECOMPILED_PRICER(alt_bn128_G1_add)
(bytesConstRef /*_in*/, ChainOperationParams const& _chainParams, u256 const& _blockNumber)
{
return _blockNumber < _chainParams.istanbulForkBlock ? 500 : 150;
}

ETH_REGISTER_PRECOMPILED(alt_bn128_G1_mul)(bytesConstRef _in)
{
return dev::crypto::alt_bn128_G1_mul(_in);
}

ETH_REGISTER_PRECOMPILED_PRICER(alt_bn128_G1_mul)
(bytesConstRef /*_in*/, ChainOperationParams const& _chainParams, u256 const& _blockNumber)
{
return _blockNumber < _chainParams.istanbulForkBlock ? 40000 : 6000;
}

ETH_REGISTER_PRECOMPILED(alt_bn128_pairing_product)(bytesConstRef _in)
{
return dev::crypto::alt_bn128_pairing_product(_in);
}

ETH_REGISTER_PRECOMPILED_PRICER(alt_bn128_pairing_product)(bytesConstRef _in)
ETH_REGISTER_PRECOMPILED_PRICER(alt_bn128_pairing_product)
(bytesConstRef _in, ChainOperationParams const& _chainParams, u256 const& _blockNumber)
{
return 100000 + (_in.size() / 192) * 80000;
auto const k = _in.size() / 192;
return _blockNumber < _chainParams.istanbulForkBlock ? 100000 + k * 80000 : 45000 + k * 34000;
}

}
12 changes: 10 additions & 2 deletions libethcore/Precompiled.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,11 @@ namespace dev
{
namespace eth
{
struct ChainOperationParams;

using PrecompiledExecutor = std::function<std::pair<bool, bytes>(bytesConstRef _in)>;
using PrecompiledPricer = std::function<bigint(bytesConstRef _in)>;
using PrecompiledPricer = std::function<bigint(
bytesConstRef _in, ChainOperationParams const& _chainParams, u256 const& _blockNumber)>;

DEV_SIMPLE_EXCEPTION(ExecutorNotFound);
DEV_SIMPLE_EXCEPTION(PricerNotFound);
Expand Down Expand Up @@ -66,6 +68,12 @@ class PrecompiledRegistrar

// TODO: unregister on unload with a static object.
#define ETH_REGISTER_PRECOMPILED(Name) static std::pair<bool, bytes> __eth_registerPrecompiledFunction ## Name(bytesConstRef _in); static PrecompiledExecutor __eth_registerPrecompiledFactory ## Name = ::dev::eth::PrecompiledRegistrar::registerExecutor(#Name, &__eth_registerPrecompiledFunction ## Name); static std::pair<bool, bytes> __eth_registerPrecompiledFunction ## Name
#define ETH_REGISTER_PRECOMPILED_PRICER(Name) static bigint __eth_registerPricerFunction ## Name(bytesConstRef _in); static PrecompiledPricer __eth_registerPricerFactory ## Name = ::dev::eth::PrecompiledRegistrar::registerPricer(#Name, &__eth_registerPricerFunction ## Name); static bigint __eth_registerPricerFunction ## Name
#define ETH_REGISTER_PRECOMPILED_PRICER(Name) \
static bigint __eth_registerPricerFunction##Name( \
bytesConstRef _in, ChainOperationParams const& _chainParams, u256 const& _blockNumber); \
static PrecompiledPricer __eth_registerPricerFactory##Name = \
::dev::eth::PrecompiledRegistrar::registerPricer( \
#Name, &__eth_registerPricerFunction##Name); \
static bigint __eth_registerPricerFunction##Name
}
}
6 changes: 5 additions & 1 deletion libethcore/SealEngine.h
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,11 @@ class SealEngineFace
{
return m_params.precompiled.count(_a) != 0 && _blockNumber >= m_params.precompiled.at(_a).startingBlock();
}
virtual bigint costOfPrecompiled(Address const& _a, bytesConstRef _in, u256 const&) const { return m_params.precompiled.at(_a).cost(_in); }
virtual bigint costOfPrecompiled(
Address const& _a, bytesConstRef _in, u256 const& _blockNumber) const
{
return m_params.precompiled.at(_a).cost(_in, m_params, _blockNumber);
}
virtual std::pair<bool, bytes> executePrecompiled(Address const& _a, bytesConstRef _in, u256 const&) const { return m_params.precompiled.at(_a).execute(_in); }

protected:
Expand Down
86 changes: 77 additions & 9 deletions test/unittests/libethcore/PrecompiledTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -198,7 +198,7 @@ BOOST_AUTO_TEST_CASE(modexpCostFermatTheorem)
"03"
"fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2e"
"fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f");
auto res = cost(bytesConstRef(in.data(), in.size()));
auto res = cost(ref(in), {}, {});

BOOST_REQUIRE_EQUAL(static_cast<int>(res), 13056);
}
Expand All @@ -213,7 +213,7 @@ BOOST_AUTO_TEST_CASE(modexpCostTooLarge)
"0000000000000000000000000000000000000000000000000000000000000020"
"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"
"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd");
auto res = cost(bytesConstRef(in.data(), in.size()));
auto res = cost(ref(in), {}, {});

BOOST_REQUIRE_MESSAGE(res == bigint{"47428439751604713645494675459558567056699385719046375030561826409641217900517324"}, "Got: " + toString(res));
}
Expand All @@ -231,7 +231,7 @@ BOOST_AUTO_TEST_CASE(modexpCostEmptyExponent)
"998877665544332211998877665544332211" // M
"9978" // Garbage that should be ignored
);
auto res = cost(bytesConstRef(in.data(), in.size()));
auto res = cost(ref(in), {}, {});

BOOST_REQUIRE_MESSAGE(res == bigint{"12"}, "Got: " + toString(res));
}
Expand All @@ -248,7 +248,7 @@ BOOST_AUTO_TEST_CASE(modexpCostZeroExponent)
"000000" // E
"112233445566778899aa" // M
);
auto res = cost(bytesConstRef(in.data(), in.size()));
auto res = cost(ref(in), {}, {});

BOOST_REQUIRE_MESSAGE(res == bigint{"5"}, "Got: " + toString(res));
}
Expand All @@ -265,7 +265,7 @@ BOOST_AUTO_TEST_CASE(modexpCostApproximated)
"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" // E
"112233445566778899aa" // M
);
auto res = cost(bytesConstRef(in.data(), in.size()));
auto res = cost(ref(in), {}, {});

BOOST_REQUIRE_MESSAGE(res == bigint{"1315"}, "Got: " + toString(res));
}
Expand All @@ -282,7 +282,7 @@ BOOST_AUTO_TEST_CASE(modexpCostApproximatedPartialByte)
"02ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" // E
"112233445566778899aa" // M
);
auto res = cost(bytesConstRef(in.data(), in.size()));
auto res = cost(ref(in), {}, {});

BOOST_REQUIRE_MESSAGE(res == bigint{"1285"}, "Got: " + toString(res));
}
Expand All @@ -299,7 +299,7 @@ BOOST_AUTO_TEST_CASE(modexpCostApproximatedGhost)
"000000000000000000000000000000000000000000000000000000000000000000" // E
"112233445566778899aa" // M
);
auto res = cost(bytesConstRef(in.data(), in.size()));
auto res = cost(ref(in), {}, {});

BOOST_REQUIRE_MESSAGE(res == bigint{"40"}, "Got: " + toString(res));
}
Expand All @@ -316,7 +316,7 @@ BOOST_AUTO_TEST_CASE(modexpCostMidRange)
"000000000000000000000000000000000000000000000000000000000000000000" // E
"112233445566778899aa" // M
);
auto res = cost(bytesConstRef(in.data(), in.size()));
auto res = cost(ref(in), {}, {});

BOOST_REQUIRE_MESSAGE(res == ((74 * 74 / 4 + 96 * 74 - 3072) * 8) / 20, "Got: " + toString(res));
}
Expand All @@ -333,7 +333,7 @@ BOOST_AUTO_TEST_CASE(modexpCostHighRange)
"000000000000000000000000000000000000000000000000000000000000000000" // E
"112233445566778899aa" // M
);
auto res = cost(bytesConstRef(in.data(), in.size()));
auto res = cost(ref(in), {}, {});

BOOST_REQUIRE_MESSAGE(res == ((1025 * 1025 / 16 + 480 * 1025 - 199680) * 8) / 20, "Got: " + toString(res));
}
Expand Down Expand Up @@ -717,4 +717,72 @@ BOOST_AUTO_TEST_CASE(bench_bn256Pairing, *ut::label("bench"))
benchmarkPrecompiled("alt_bn128_pairing_product", tests, 1000);
}

BOOST_AUTO_TEST_CASE(ecaddCostBeforeIstanbul)
{
PrecompiledPricer cost = PrecompiledRegistrar::pricer("alt_bn128_G1_add");

ChainParams chainParams{genesisInfo(eth::Network::IstanbulTransitionTest)};

auto res = cost({}, chainParams, 1);

BOOST_REQUIRE_EQUAL(static_cast<int>(res), 500);
}

BOOST_AUTO_TEST_CASE(ecaddCostIstanbul)
{
PrecompiledPricer cost = PrecompiledRegistrar::pricer("alt_bn128_G1_add");

ChainParams chainParams{genesisInfo(eth::Network::IstanbulTransitionTest)};

auto res = cost({}, chainParams, 2);

BOOST_REQUIRE_EQUAL(static_cast<int>(res), 150);
}

BOOST_AUTO_TEST_CASE(ecmulBeforeIstanbul)
{
PrecompiledPricer cost = PrecompiledRegistrar::pricer("alt_bn128_G1_mul");

ChainParams chainParams{genesisInfo(eth::Network::IstanbulTransitionTest)};

auto res = cost({}, chainParams, 1);

BOOST_REQUIRE_EQUAL(static_cast<int>(res), 40000);
}

BOOST_AUTO_TEST_CASE(ecmulCostIstanbul)
{
PrecompiledPricer cost = PrecompiledRegistrar::pricer("alt_bn128_G1_mul");

ChainParams chainParams{genesisInfo(eth::Network::IstanbulTransitionTest)};

auto res = cost({}, chainParams, 2);

BOOST_REQUIRE_EQUAL(static_cast<int>(res), 6000);
}

BOOST_AUTO_TEST_CASE(ecpairingCost)
{
PrecompiledPricer cost = PrecompiledRegistrar::pricer("alt_bn128_pairing_product");

ChainParams chainParams{genesisInfo(eth::Network::IstanbulTransitionTest)};

bytes in{fromHex(
"0x1c76476f4def4bb94541d57ebba1193381ffa7aa76ada664dd31c16024c43f593034dd2920f673e204fee281"
"1c678745fc819b55d3e9d294e45c9b03a76aef41209dd15ebff5d46c4bd888e51a93cf99a7329636c63514396b"
"4a452003a35bf704bf11ca01483bfa8b34b43561848d28905960114c8ac04049af4b6315a416782bb8324af6cf"
"c93537a2ad1a445cfd0ca2a71acd7ac41fadbf933c2a51be344d120a2a4cf30c1bf9845f20c6fe39e07ea2cce6"
"1f0c9bb048165fe5e4de877550111e129f1cf1097710d41c4ac70fcdfa5ba2023c6ff1cbeac322de49d1b6df7c"
"2032c61a830e3c17286de9462bf242fca2883585b93870a73853face6a6bf411198e9393920d483a7260bfb731"
"fb5d25f1aa493335a9e71297e485b7aef312c21800deef121f1e76426a00665e5c4479674322d4f75edadd46de"
"bd5cd992f6ed090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b12c85ea5db8c6d"
"eb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa")};

auto costBeforeIstanbul = cost(ref(in), chainParams, 1);
BOOST_CHECK_EQUAL(static_cast<int>(costBeforeIstanbul), in.size() / 192 * 80000 + 100000);

auto costIstanbul = cost(ref(in), chainParams, 2);
BOOST_CHECK_EQUAL(static_cast<int>(costIstanbul), in.size() / 192 * 34000 + 45000);
}

BOOST_AUTO_TEST_SUITE_END()

0 comments on commit 7e6095d

Please sign in to comment.