From bb06fdb8313bcf093fa6e8f0ddf355c2b80eddf3 Mon Sep 17 00:00:00 2001 From: Ali Behjati Date: Fri, 18 Nov 2022 14:42:06 +0100 Subject: [PATCH] [eth] Gas improvement: Optimize getPrice and getEmaPrice (#389) * Optimize getPrice and getEmaPrice --- ethereum/contracts/pyth/Pyth.sol | 32 ++++++++++++++++++++++++++ ethereum/forge-test/GasBenchmark.t.sol | 9 ++++++++ 2 files changed, 41 insertions(+) diff --git a/ethereum/contracts/pyth/Pyth.sol b/ethereum/contracts/pyth/Pyth.sol index 088b3ca9..2a195214 100644 --- a/ethereum/contracts/pyth/Pyth.sol +++ b/ethereum/contracts/pyth/Pyth.sol @@ -235,6 +235,38 @@ abstract contract Pyth is PythGetters, PythSetters, AbstractPyth { ); } + // This is an overwrite of the same method in AbstractPyth.sol + // to be more gas efficient. It cannot move to PythGetters as it + // is overwriting the interface. Even indirect calling of a similar + // method from PythGetter has some gas overhead. + function getPriceUnsafe( + bytes32 id + ) public view override returns (PythStructs.Price memory price) { + PythInternalStructs.PriceInfo storage info = _state.latestPriceInfo[id]; + price.publishTime = info.publishTime; + price.expo = info.expo; + price.price = info.price; + price.conf = info.conf; + + require(price.publishTime != 0, "price feed for the given id is not pushed or does not exist"); + } + + // This is an overwrite of the same method in AbstractPyth.sol + // to be more gas efficient. It cannot move to PythGetters as it + // is overwriting the interface. Even indirect calling of a similar + // method from PythGetter has some gas overhead. + function getEmaPriceUnsafe( + bytes32 id + ) public view override returns (PythStructs.Price memory price) { + PythInternalStructs.PriceInfo storage info = _state.latestPriceInfo[id]; + price.publishTime = info.publishTime; + price.expo = info.expo; + price.price = info.emaPrice; + price.conf = info.emaConf; + + require(price.publishTime != 0, "price feed for the given id is not pushed or does not exist"); + } + function parsePriceFeedUpdates( bytes[] calldata updateData, bytes32[] calldata priceIds, diff --git a/ethereum/forge-test/GasBenchmark.t.sol b/ethereum/forge-test/GasBenchmark.t.sol index bb30954a..e26d45a5 100644 --- a/ethereum/forge-test/GasBenchmark.t.sol +++ b/ethereum/forge-test/GasBenchmark.t.sol @@ -130,6 +130,15 @@ contract GasBenchmark is Test, WormholeTestUtils, PythTestUtils { pyth.getPrice(priceIds[0]); } + + function testBenchmarkGetEmaPrice() public { + // Set the block timestamp to 0. As prices have < 10 timestamp and staleness + // is set to 60 seconds, the getPrice should work as expected. + vm.warp(0); + + pyth.getEmaPrice(priceIds[0]); + } + function testBenchmarkGetUpdateFee() public view { pyth.getUpdateFee(freshPricesUpdateData); }