diff --git a/contracts/DecentralizedKV.sol b/contracts/DecentralizedKV.sol index 16f3ba6..464e236 100644 --- a/contracts/DecentralizedKV.sol +++ b/contracts/DecentralizedKV.sol @@ -19,6 +19,11 @@ contract DecentralizedKV is OwnableUpgradeable { uint256 public immutable dcfFactor; uint256 public immutable startTime; uint256 public immutable maxKvSize; + + /// @custom:spacer storageCost, dcfFactor, startTime, maxKvSize + /// @notice Spacer for backwards compatibility. + uint256[4] public kvSpacers; + uint40 public lastKvIdx; // number of entries in the store struct PhyAddr { @@ -35,6 +40,8 @@ contract DecentralizedKV is OwnableUpgradeable { /* index - skey, reverse lookup */ mapping(uint256 => bytes32) internal idxMap; + // TODO: Reserve extra slots (to a total of 50?) in the storage layout for future upgrades + constructor(uint256 _maxKvSize, uint256 _startTime, uint256 _storageCost, uint256 _dcfFactor) { maxKvSize = _maxKvSize; startTime = _startTime; diff --git a/contracts/EthStorageContract.sol b/contracts/EthStorageContract.sol index 44c19a5..d6cc8c9 100644 --- a/contracts/EthStorageContract.sol +++ b/contracts/EthStorageContract.sol @@ -12,6 +12,8 @@ contract EthStorageContract is StorageContract, Decoder { uint256 constant modulusBn254 = 0x30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001; uint256 constant fieldElementsPerBlob = 0x1000; + // TODO: Reserve extra slots (to a total of 50?) in the storage layout for future upgrades + event PutBlob(uint256 indexed kvIdx, uint256 indexed kvSize, bytes32 indexed dataHash); constructor( @@ -129,9 +131,7 @@ contract EthStorageContract is StorageContract, Decoder { PhyAddr memory kvInfo = kvMap[idxMap[kvIdx]]; Proof memory proof = abi.decode(decodeProof, (Proof)); // BLOB decoding check - if ( - !decodeSample(proof, uint256(keccak256(abi.encode(kvInfo.hash, miner, kvIdx))), sampleIdxInKv, mask) - ) { + if (!decodeSample(proof, uint256(keccak256(abi.encode(kvInfo.hash, miner, kvIdx))), sampleIdxInKv, mask)) { return false; } @@ -139,11 +139,7 @@ contract EthStorageContract is StorageContract, Decoder { return checkInclusive(kvInfo.hash, sampleIdxInKv, mask ^ uint256(encodedData), inclusiveProof); } - function getSampleIdx( - uint256 rows, - uint256 startShardId, - bytes32 hash0 - ) public view returns (uint256, uint256) { + function getSampleIdx(uint256 rows, uint256 startShardId, bytes32 hash0) public view returns (uint256, uint256) { uint256 parent = uint256(hash0) % rows; uint256 sampleIdx = parent + (startShardId << (shardEntryBits + sampleLenBits)); uint256 kvIdx = sampleIdx >> sampleLenBits; @@ -172,13 +168,21 @@ contract EthStorageContract is StorageContract, Decoder { (uint256 kvIdx, uint256 sampleIdxInKv) = getSampleIdx(rows, startShardId, hash0); require( - decodeAndCheckInclusive(kvIdx, sampleIdxInKv, miner, encodedSamples[i], masks[i], inclusiveProofs[i], decodeProof[i]), + decodeAndCheckInclusive( + kvIdx, + sampleIdxInKv, + miner, + encodedSamples[i], + masks[i], + inclusiveProofs[i], + decodeProof[i] + ), "invalid samples" ); hash0 = keccak256(abi.encode(hash0, encodedSamples[i])); } return hash0; - } + } // Write a large value to KV store. If the KV pair exists, overrides it. Otherwise, will append the KV to the KV array. function putBlob(bytes32 key, uint256 blobIdx, uint256 length) public payable virtual { diff --git a/contracts/StorageContract.sol b/contracts/StorageContract.sol index 18556c6..f1edbb5 100644 --- a/contracts/StorageContract.sol +++ b/contracts/StorageContract.sol @@ -29,13 +29,25 @@ abstract contract StorageContract is DecentralizedKV { uint256 public immutable diffAdjDivisor; uint256 public immutable treasuryShare; // 10000 = 1.0 - mapping(uint256 => MiningLib.MiningInfo) public infos; + /// @custom:spacer maxKvSizeBits, shardSizeBits, shardEntryBits, sampleLenBits, randomChecks + /// @notice Spacer for backwards compatibility. + uint256[5] public storSpacers1; + uint256 public minimumDiff; + + /// @custom:spacer cutoff, diffAdjDivisor, treasuryShare + /// @notice Spacer for backwards compatibility. + uint256[3] public storSpacers2; + uint256 public prepaidAmount; + + mapping(uint256 => MiningLib.MiningInfo) public infos; uint256 public nonceLimit; // maximum nonce per block address public treasury; uint256 public prepaidLastMineTime; + // TODO: Reserve extra slots (to a total of 50?) in the storage layout for future upgrades + constructor( Config memory _config, uint256 _startTime, @@ -106,7 +118,7 @@ abstract contract StorageContract is DecentralizedKV { function upfrontPayment() public view virtual override returns (uint256) { uint256 totalEntries = lastKvIdx + 1; // include the one to be put uint256 shardId = lastKvIdx >> shardEntryBits; // shard id of the new KV - // shard0 is already opened in constructor + // shard0 is already opened in constructor if ((totalEntries % (1 << shardEntryBits)) == 1 && shardId != 0) { // Open a new shard if the KV is the first one of the shard // and mark the shard is ready to mine. @@ -187,7 +199,7 @@ abstract contract StorageContract is DecentralizedKV { function miningReward(uint256 shardId, uint256 blockNumber) public view returns (uint256) { uint256 minedTs = block.timestamp - (block.number - blockNumber) * 12; - (,, uint256 minerReward) = _miningReward(shardId, minedTs); + (, , uint256 minerReward) = _miningReward(shardId, minedTs); return minerReward; } @@ -242,7 +254,8 @@ abstract contract StorageContract is DecentralizedKV { bytes[] calldata inclusiveProofs, bytes[] calldata decodeProof ) public virtual { - return _mine(blockNumber, shardId, miner, nonce, encodedSamples, masks, randaoProof, inclusiveProofs, decodeProof); + return + _mine(blockNumber, shardId, miner, nonce, encodedSamples, masks, randaoProof, inclusiveProofs, decodeProof); } function setNonceLimit(uint256 _nonceLimit) public onlyOwner {