@@ -23,7 +23,7 @@ contract SPVContract is ISPVContract, Initializable {
2323
2424 struct SPVContractStorage {
2525 mapping (bytes32 => BlockData) blocksData;
26- mapping (uint256 => bytes32 ) blocksHeightToBlockHash;
26+ mapping (uint64 => bytes32 ) blocksHeightToBlockHash;
2727 bytes32 mainchainHead;
2828 uint256 lastEpochCumulativeWork;
2929 }
@@ -56,7 +56,7 @@ contract SPVContract is ISPVContract, Initializable {
5656
5757 function __SPVContract_init (
5858 bytes calldata blockHeaderRaw_ ,
59- uint256 blockHeight_ ,
59+ uint64 blockHeight_ ,
6060 uint256 cumulativeWork_
6161 ) external initializer {
6262 (BlockHeaderData memory blockHeader_ , bytes32 blockHash_ ) = _parseBlockHeaderRaw (
@@ -91,11 +91,11 @@ contract SPVContract is ISPVContract, Initializable {
9191 bytes32 [] memory blockHashes_
9292 ) = _parseBlockHeadersRaw (blockHeaderRawArray_);
9393
94- uint256 firstBlockHeight_ = getBlockHeight (blockHeaders_[0 ].prevBlockHash) + 1 ;
94+ uint64 firstBlockHeight_ = getBlockHeight (blockHeaders_[0 ].prevBlockHash) + 1 ;
9595 bytes32 currentTarget_ = getBlockTarget (blockHeaders_[0 ].prevBlockHash);
9696
97- for (uint256 i = 0 ; i < blockHeaderRawArray_.length ; ++ i) {
98- uint256 currentBlockHeight_ = firstBlockHeight_ + i;
97+ for (uint64 i = 0 ; i < blockHeaderRawArray_.length ; ++ i) {
98+ uint64 currentBlockHeight_ = firstBlockHeight_ + i;
9999
100100 currentTarget_ = _updateLastEpochCumulativeWork (currentTarget_, currentBlockHeight_);
101101
@@ -126,7 +126,7 @@ contract SPVContract is ISPVContract, Initializable {
126126 PrevBlockDoesNotExist (blockHeader_.prevBlockHash)
127127 );
128128
129- uint256 blockHeight_ = getBlockHeight (blockHeader_.prevBlockHash) + 1 ;
129+ uint64 blockHeight_ = getBlockHeight (blockHeader_.prevBlockHash) + 1 ;
130130 bytes32 currentTarget_ = getBlockTarget (blockHeader_.prevBlockHash);
131131
132132 currentTarget_ = _updateLastEpochCumulativeWork (currentTarget_, blockHeight_);
@@ -142,16 +142,7 @@ contract SPVContract is ISPVContract, Initializable {
142142 }
143143
144144 /// @inheritdoc ISPVContract
145- function validateBlockHash (bytes32 blockHash_ ) external view returns (bool , uint256 ) {
146- if (! isInMainchain (blockHash_)) {
147- return (false , 0 );
148- }
149-
150- return (true , getMainchainBlockHeight () - getBlockHeight (blockHash_));
151- }
152-
153- /// @inheritdoc ISPVContract
154- function verifyTx (
145+ function checkTxInclusion (
155146 bytes32 blockHash_ ,
156147 bytes32 txid_ ,
157148 bytes32 [] calldata merkleProof_ ,
@@ -164,6 +155,15 @@ contract SPVContract is ISPVContract, Initializable {
164155 return TxMerkleProof.verify (merkleProof_, directions_, reversedRoot_, txid_);
165156 }
166157
158+ /// @inheritdoc ISPVContract
159+ function getBlockStatus (bytes32 blockHash_ ) external view returns (bool , uint256 ) {
160+ if (! isInMainchain (blockHash_)) {
161+ return (false , 0 );
162+ }
163+
164+ return (true , getMainchainHeight () - getBlockHeight (blockHash_));
165+ }
166+
167167 /// @inheritdoc ISPVContract
168168 function getBlockInfo (bytes32 blockHash_ ) external view returns (BlockInfo memory blockInfo_ ) {
169169 if (! blockExists (blockHash_)) {
@@ -186,7 +186,7 @@ contract SPVContract is ISPVContract, Initializable {
186186
187187 /// @inheritdoc ISPVContract
188188 function getBlockMerkleRoot (bytes32 blockHash_ ) public view returns (bytes32 ) {
189- return _getBlockHeader (blockHash_) .merkleRoot;
189+ return _getSPVContractStorage ().blocksData[blockHash_] .merkleRoot;
190190 }
191191
192192 /// @inheritdoc ISPVContract
@@ -200,27 +200,27 @@ contract SPVContract is ISPVContract, Initializable {
200200 }
201201
202202 /// @inheritdoc ISPVContract
203- function getBlockHeight (bytes32 blockHash_ ) public view returns (uint256 ) {
203+ function getBlockHeight (bytes32 blockHash_ ) public view returns (uint64 ) {
204204 return _getSPVContractStorage ().blocksData[blockHash_].blockHeight;
205205 }
206206
207207 /// @inheritdoc ISPVContract
208- function getBlockHash (uint256 blockHeight_ ) public view returns (bytes32 ) {
208+ function getBlockHash (uint64 blockHeight_ ) public view returns (bytes32 ) {
209209 return _getSPVContractStorage ().blocksHeightToBlockHash[blockHeight_];
210210 }
211211
212212 /// @inheritdoc ISPVContract
213213 function getBlockTarget (bytes32 blockHash_ ) public view returns (bytes32 ) {
214- return TargetsHelper.bitsToTarget (_getBlockHeader (blockHash_) .bits);
214+ return TargetsHelper.bitsToTarget (_getSPVContractStorage ().blocksData[blockHash_] .bits);
215215 }
216216
217217 /// @inheritdoc ISPVContract
218218 function blockExists (bytes32 blockHash_ ) public view returns (bool ) {
219- return _getBlockHeader (blockHash_).time > 0 ;
219+ return _getBlockHeaderTime (blockHash_) > 0 ;
220220 }
221221
222222 /// @inheritdoc ISPVContract
223- function getMainchainBlockHeight () public view returns (uint256 ) {
223+ function getMainchainHeight () public view returns (uint256 ) {
224224 return getBlockHeight (_getSPVContractStorage ().mainchainHead);
225225 }
226226
@@ -232,11 +232,19 @@ contract SPVContract is ISPVContract, Initializable {
232232 function _addBlock (
233233 BlockHeaderData memory blockHeader_ ,
234234 bytes32 blockHash_ ,
235- uint256 blockHeight_
235+ uint64 blockHeight_
236236 ) internal {
237237 SPVContractStorage storage $ = _getSPVContractStorage ();
238238
239- $.blocksData[blockHash_] = BlockData ({header: blockHeader_, blockHeight: blockHeight_});
239+ $.blocksData[blockHash_] = BlockData ({
240+ prevBlockHash: blockHeader_.prevBlockHash,
241+ merkleRoot: blockHeader_.merkleRoot,
242+ version: blockHeader_.version,
243+ time: blockHeader_.time,
244+ nonce: blockHeader_.nonce,
245+ bits: blockHeader_.bits,
246+ blockHeight: blockHeight_
247+ });
240248
241249 _updateMainchainHead (blockHeader_, blockHash_, blockHeight_);
242250
@@ -246,7 +254,7 @@ contract SPVContract is ISPVContract, Initializable {
246254 function _updateMainchainHead (
247255 BlockHeaderData memory blockHeader_ ,
248256 bytes32 blockHash_ ,
249- uint256 blockHeight_
257+ uint64 blockHeight_
250258 ) internal {
251259 SPVContractStorage storage $ = _getSPVContractStorage ();
252260
@@ -270,31 +278,34 @@ contract SPVContract is ISPVContract, Initializable {
270278 $.blocksHeightToBlockHash[blockHeight_] = blockHash_;
271279
272280 bytes32 prevBlockHash_ = blockHeader_.prevBlockHash;
273- uint256 prevBlockHeight_ = blockHeight_ - 1 ;
281+ uint64 prevBlockHeight_ = blockHeight_ - 1 ;
274282
275283 do {
276284 $.blocksHeightToBlockHash[prevBlockHeight_] = prevBlockHash_;
277285
278- prevBlockHash_ = _getBlockHeader (prevBlockHash_).prevBlockHash;
279- -- prevBlockHeight_;
286+ prevBlockHash_ = _getSPVContractStorage ().blocksData[prevBlockHash_].prevBlockHash;
287+
288+ unchecked {
289+ -- prevBlockHeight_;
290+ }
280291 } while (getBlockHash (prevBlockHeight_) != prevBlockHash_ && prevBlockHash_ != 0 );
281292 }
282293 }
283294
284295 function _updateLastEpochCumulativeWork (
285296 bytes32 currentTarget_ ,
286- uint256 blockHeight_
297+ uint64 blockHeight_
287298 ) internal returns (bytes32 ) {
288299 SPVContractStorage storage $ = _getSPVContractStorage ();
289300
290301 if (TargetsHelper.isTargetAdjustmentBlock (blockHeight_)) {
291302 $.lastEpochCumulativeWork += TargetsHelper.countEpochCumulativeWork (currentTarget_);
292303
293- uint256 epochStartTime_ = _getBlockHeader (
304+ uint32 epochStartTime_ = _getBlockHeaderTime (
294305 getBlockHash (blockHeight_ - TargetsHelper.DIFFICULTY_ADJUSTMENT_INTERVAL)
295- ).time ;
296- uint256 epochEndTime_ = _getBlockHeader (getBlockHash (blockHeight_ - 1 )).time ;
297- uint256 passedTime_ = epochEndTime_ - epochStartTime_;
306+ );
307+ uint32 epochEndTime_ = _getBlockHeaderTime (getBlockHash (blockHeight_ - 1 ));
308+ uint32 passedTime_ = epochEndTime_ - epochStartTime_;
298309
299310 currentTarget_ = TargetsHelper.countNewRoundedTarget (currentTarget_, passedTime_);
300311 }
@@ -350,17 +361,17 @@ contract SPVContract is ISPVContract, Initializable {
350361 bytes32 toBlockHash_ = blockHeader_.prevBlockHash;
351362
352363 if (blockHeight_ - 1 < MEDIAN_PAST_BLOCKS) {
353- return _getBlockHeader (toBlockHash_).time ;
364+ return _getBlockHeaderTime (toBlockHash_);
354365 }
355366
356367 uint256 [] memory blocksTime_ = new uint256 [](MEDIAN_PAST_BLOCKS);
357368 bool needsSort_;
358369
359370 for (uint256 i = MEDIAN_PAST_BLOCKS; i > 0 ; -- i) {
360- uint32 currentTime_ = _getBlockHeader (toBlockHash_).time ;
371+ uint32 currentTime_ = _getBlockHeaderTime (toBlockHash_);
361372
362373 blocksTime_[i - 1 ] = currentTime_;
363- toBlockHash_ = _getBlockHeader (toBlockHash_) .prevBlockHash;
374+ toBlockHash_ = _getSPVContractStorage ().blocksData[toBlockHash_] .prevBlockHash;
364375
365376 if (i < MEDIAN_PAST_BLOCKS && currentTime_ > blocksTime_[i]) {
366377 needsSort_ = true ;
@@ -395,7 +406,7 @@ contract SPVContract is ISPVContract, Initializable {
395406 }
396407
397408 function _getBlockCumulativeWork (
398- uint256 blockHeight_ ,
409+ uint64 blockHeight_ ,
399410 bytes32 blockHash_
400411 ) internal view returns (uint256 ) {
401412 uint256 currentEpochCumulativeWork_ = getBlockTarget (blockHash_).countCumulativeWork (
@@ -405,8 +416,8 @@ contract SPVContract is ISPVContract, Initializable {
405416 return _getSPVContractStorage ().lastEpochCumulativeWork + currentEpochCumulativeWork_;
406417 }
407418
408- function _getBlockHeader (bytes32 blockHash_ ) internal view returns (BlockHeaderData storage ) {
409- return _getSPVContractStorage ().blocksData[blockHash_].header ;
419+ function _getBlockHeaderTime (bytes32 blockHash_ ) internal view returns (uint32 ) {
420+ return _getSPVContractStorage ().blocksData[blockHash_].time ;
410421 }
411422
412423 function _onlyNonExistingBlock (bytes32 blockHash_ ) internal view {
0 commit comments