admin管理员组文章数量:1332881
I am developing a contract that needs to use historical Chainlink prices.
I use the following approach: The caller passes the roundId to contract, according to which we get the price data. Contract get the next roundId to make sure that the roundId is in the right time range.
Current understanding: proxyRoundId = phaseId >> x64 | aggregatorRoundId proxyRoundId - increases monotonously(+1) each new round within same phase. Increases nonmonotonically if phase change. phaseId - depends on Argregator version/implementation. When change aggregator increases phaseId(+1). aggregatorRoundId - starts from 1 and increases monotonously(+1) with each new round.
I checked the value of RoundData for oracles during the transition between phases and did not fully understand the logic of publishing RoundData.
The contract -
roundId uint80 : 18446744073709551727 => phaseId 1, aggregatorRoundId 111
answer int256 : 99939094
startedAt uint256 : 1725911063
updatedAt uint256 : 1725911063
answeredInRound uint80 : 18446744073709551727
roundId uint80 : 36893488147419103233 => phaseId 2, aggregatorRoundId 1
answer int256 : 99894945
startedAt uint256 : 1720771216
updatedAt uint256 : 1720771295
answeredInRound uint80 : 36893488147419103233
Questions:
- Why RoundData(36893488147419103233).updatedAt < RoundData(18446744073709551727).updatedAt? Based on the current understanding, the new phase should have the newest values compared to the previous one.
- I think that for this task I can try to use a binary search by roundId and check RoundData.updatedAt, but the implementation in the contract consumes a lot of gas. Do you know more effective ways to get roundId by timestamp?
- Up to what time are the rounds in the old phase updated (when is the switch to the new phase)?
- How is it optimal to search for prices based on historical data if the timestamp may overlap in different phases?
I am developing a contract that needs to use historical Chainlink prices.
I use the following approach: The caller passes the roundId to contract, according to which we get the price data. Contract get the next roundId to make sure that the roundId is in the right time range.
Current understanding: proxyRoundId = phaseId >> x64 | aggregatorRoundId proxyRoundId - increases monotonously(+1) each new round within same phase. Increases nonmonotonically if phase change. phaseId - depends on Argregator version/implementation. When change aggregator increases phaseId(+1). aggregatorRoundId - starts from 1 and increases monotonously(+1) with each new round.
I checked the value of RoundData for oracles during the transition between phases and did not fully understand the logic of publishing RoundData.
The contract - https://etherscan.io/address/0xa569d910839Ae8865Da8F8e70FfFb0cBA869F961
roundId uint80 : 18446744073709551727 => phaseId 1, aggregatorRoundId 111
answer int256 : 99939094
startedAt uint256 : 1725911063
updatedAt uint256 : 1725911063
answeredInRound uint80 : 18446744073709551727
roundId uint80 : 36893488147419103233 => phaseId 2, aggregatorRoundId 1
answer int256 : 99894945
startedAt uint256 : 1720771216
updatedAt uint256 : 1720771295
answeredInRound uint80 : 36893488147419103233
Questions:
- Why RoundData(36893488147419103233).updatedAt < RoundData(18446744073709551727).updatedAt? Based on the current understanding, the new phase should have the newest values compared to the previous one.
- I think that for this task I can try to use a binary search by roundId and check RoundData.updatedAt, but the implementation in the contract consumes a lot of gas. Do you know more effective ways to get roundId by timestamp?
- Up to what time are the rounds in the old phase updated (when is the switch to the new phase)?
- How is it optimal to search for prices based on historical data if the timestamp may overlap in different phases?
1 Answer
Reset to default 0Here is a Pseudocode for Binary Search
function findRoundId(uint256 targetTimestamp) public view returns (uint80 roundId) {
AggregatorV3Interface aggregator = AggregatorV3Interface(AGGREGATOR_ADDRESS);
uint80 low = aggregator.firstRound();
uint80 high = aggregator.latestRound();
while (low < high) {
uint80 mid = low + (high - low) / 2;
(, , , uint256 midTimestamp, ) = aggregator.getRoundData(mid);
if (midTimestamp < targetTimestamp) {
low = mid + 1;
} else {
high = mid;
}
}
return low; // Closest round ID
}
本文标签: Issues with chainlink historical data feedsStack Overflow
版权声明:本文标题:Issues with chainlink historical data feeds - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1742296126a2448760.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论