@@ -8,6 +8,7 @@ import "@openzeppelin/contracts/utils/introspection/ERC165Checker.sol";
88import "../UsingWitnet.sol " ;
99import "../interfaces/V2/IWitnetBytecodes.sol " ;
1010import "../interfaces/IWitnetRequest.sol " ;
11+ import "../libs/WitnetLib.sol " ;
1112import "../patterns/Clonable.sol " ;
1213
1314abstract contract WitnetRequestTemplate
@@ -29,7 +30,10 @@ abstract contract WitnetRequestTemplate
2930 /// @notice SHA-256 hash of the Witnet Data Request bytecode.
3031 bytes32 public override hash;
3132
32- /// @notice Unique id of last request attempt.
33+ /// @notice Unique id of last update attempt.
34+ uint256 public lastAttemptId;
35+
36+ /// @notice Unique id of last update that got solved successfully.
3337 uint256 public lastId;
3438
3539 /// @notice Reference to Witnet Data Requests Bytecode Registry
@@ -100,17 +104,13 @@ abstract contract WitnetRequestTemplate
100104 __sources = abi.encode (_sources);
101105 }
102106 {
103- require (
104- uint8 (_registry.lookupRadonReducer (_aggregator).opcode) != 0 ,
105- "WitnetRequestTemplate: unknown aggregator "
106- );
107+ // revert if the aggregator reducer is unknown
108+ _registry.lookupRadonReducer (_aggregator);
107109 _AGGREGATOR_HASH = _aggregator;
108110 }
109111 {
110- require (
111- uint8 (_registry.lookupRadonReducer (_tally).opcode) != 0 ,
112- "WitnetRequestTemplate: unknown tally "
113- );
112+ // revert if the tally reducer is unknown
113+ _registry.lookupRadonReducer (_tally);
114114 _TALLY_HASH = _tally;
115115 }
116116 }
@@ -158,17 +158,20 @@ abstract contract WitnetRequestTemplate
158158 wasInitialized
159159 returns (uint256 _usedFunds )
160160 {
161- if (
162- lastId == 0
163- || (
164- _witnetCheckResultAvailability (lastId)
165- && witnet.isError (_witnetReadResult (lastId))
166- )
167- ) {
168- (lastId, _usedFunds) = _witnetPostRequest (this );
169- if (_usedFunds < msg .value ) {
170- payable (msg .sender ).transfer (msg .value - _usedFunds);
161+ uint _lastAttempt = lastAttemptId;
162+ if (updating ()) {
163+ _usedFunds = _witnetUpgradeReward (_lastAttempt);
164+ } else {
165+ if (
166+ _lastAttempt > 0
167+ && ! witnet.isError (_witnetReadResult (_lastAttempt))
168+ ) {
169+ lastId = _lastAttempt;
171170 }
171+ (lastAttemptId, _usedFunds) = _witnetPostRequest (this );
172+ }
173+ if (_usedFunds < msg .value ) {
174+ payable (msg .sender ).transfer (msg .value - _usedFunds);
172175 }
173176 }
174177
@@ -177,23 +180,41 @@ abstract contract WitnetRequestTemplate
177180 public view
178181 returns (bool )
179182 {
183+ uint _lastAttempt = lastAttemptId;
180184 return (
181- lastId == 0
182- || _witnetCheckResultAvailability (lastId )
185+ _lastAttempt > 0
186+ && ! _witnetCheckResultAvailability (_lastAttempt )
183187 );
184188 }
185189
186- function read ()
187- virtual
188- external view
189- notUpdating
190- returns (bool , bytes memory )
190+ function lastValue ()
191+ virtual external view
192+ returns (
193+ bytes memory _value ,
194+ bytes32 _witnetDrTxHash ,
195+ uint256 _witnetTimestamp
196+ )
191197 {
192- Witnet.Result memory _result = _witnetReadResult (lastId);
193- return (
194- _result.success,
195- _parseWitnetResult (_result.value)
196- );
198+ Witnet.Response memory _response;
199+ Witnet.Result memory _result;
200+ if (
201+ ! updating ()
202+ && lastAttemptId > 0
203+ ) {
204+ _response = witnet.readResponse (lastAttemptId);
205+ _result = WitnetLib.resultFromCborBytes (_response.cborBytes);
206+ }
207+ if (WitnetLib.failed (_result)) {
208+ if (lastId > 0 ) {
209+ _response = witnet.readResponse (lastId);
210+ _result = WitnetLib.resultFromCborBytes (_response.cborBytes);
211+ } else {
212+ revert ("WitnetRequestTemplate: no value yet " );
213+ }
214+ }
215+ _value = _parseWitnetResult (_result.value);
216+ _witnetDrTxHash = _response.drTxHash;
217+ _witnetTimestamp = _response.timestamp;
197218 }
198219
199220
0 commit comments