oracle.sol 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174
  1. pragma solidity ^0.5.10;
  2. /**
  3. * @title CheckpointOracle
  4. * @author Gary Rong<garyrong@ethereum.org>, Martin Swende <martin.swende@ethereum.org>
  5. * @dev Implementation of the blockchain checkpoint registrar.
  6. */
  7. contract CheckpointOracle {
  8. /*
  9. Events
  10. */
  11. // NewCheckpointVote is emitted when a new checkpoint proposal receives a vote.
  12. event NewCheckpointVote(uint64 indexed index, bytes32 checkpointHash, uint8 v, bytes32 r, bytes32 s);
  13. /*
  14. Public Functions
  15. */
  16. constructor(address[] memory _adminlist, uint _sectionSize, uint _processConfirms, uint _threshold) public {
  17. for (uint i = 0; i < _adminlist.length; i++) {
  18. admins[_adminlist[i]] = true;
  19. adminList.push(_adminlist[i]);
  20. }
  21. sectionSize = _sectionSize;
  22. processConfirms = _processConfirms;
  23. threshold = _threshold;
  24. }
  25. /**
  26. * @dev Get latest stable checkpoint information.
  27. * @return section index
  28. * @return checkpoint hash
  29. * @return block height associated with checkpoint
  30. */
  31. function GetLatestCheckpoint()
  32. view
  33. public
  34. returns(uint64, bytes32, uint) {
  35. return (sectionIndex, hash, height);
  36. }
  37. // SetCheckpoint sets a new checkpoint. It accepts a list of signatures
  38. // @_recentNumber: a recent blocknumber, for replay protection
  39. // @_recentHash : the hash of `_recentNumber`
  40. // @_hash : the hash to set at _sectionIndex
  41. // @_sectionIndex : the section index to set
  42. // @v : the list of v-values
  43. // @r : the list or r-values
  44. // @s : the list of s-values
  45. function SetCheckpoint(
  46. uint _recentNumber,
  47. bytes32 _recentHash,
  48. bytes32 _hash,
  49. uint64 _sectionIndex,
  50. uint8[] memory v,
  51. bytes32[] memory r,
  52. bytes32[] memory s)
  53. public
  54. returns (bool)
  55. {
  56. // Ensure the sender is authorized.
  57. require(admins[msg.sender]);
  58. // These checks replay protection, so it cannot be replayed on forks,
  59. // accidentally or intentionally
  60. require(blockhash(_recentNumber) == _recentHash);
  61. // Ensure the batch of signatures are valid.
  62. require(v.length == r.length);
  63. require(v.length == s.length);
  64. // Filter out "future" checkpoint.
  65. if (block.number < (_sectionIndex+1)*sectionSize+processConfirms) {
  66. return false;
  67. }
  68. // Filter out "old" announcement
  69. if (_sectionIndex < sectionIndex) {
  70. return false;
  71. }
  72. // Filter out "stale" announcement
  73. if (_sectionIndex == sectionIndex && (_sectionIndex != 0 || height != 0)) {
  74. return false;
  75. }
  76. // Filter out "invalid" announcement
  77. if (_hash == ""){
  78. return false;
  79. }
  80. // EIP 191 style signatures
  81. //
  82. // Arguments when calculating hash to validate
  83. // 1: byte(0x19) - the initial 0x19 byte
  84. // 2: byte(0) - the version byte (data with intended validator)
  85. // 3: this - the validator address
  86. // -- Application specific data
  87. // 4 : checkpoint section_index(uint64)
  88. // 5 : checkpoint hash (bytes32)
  89. // hash = keccak256(checkpoint_index, section_head, cht_root, bloom_root)
  90. bytes32 signedHash = keccak256(abi.encodePacked(byte(0x19), byte(0), this, _sectionIndex, _hash));
  91. address lastVoter = address(0);
  92. // In order for us not to have to maintain a mapping of who has already
  93. // voted, and we don't want to count a vote twice, the signatures must
  94. // be submitted in strict ordering.
  95. for (uint idx = 0; idx < v.length; idx++){
  96. address signer = ecrecover(signedHash, v[idx], r[idx], s[idx]);
  97. require(admins[signer]);
  98. require(uint256(signer) > uint256(lastVoter));
  99. lastVoter = signer;
  100. emit NewCheckpointVote(_sectionIndex, _hash, v[idx], r[idx], s[idx]);
  101. // Sufficient signatures present, update latest checkpoint.
  102. if (idx+1 >= threshold){
  103. hash = _hash;
  104. height = block.number;
  105. sectionIndex = _sectionIndex;
  106. return true;
  107. }
  108. }
  109. // We shouldn't wind up here, reverting un-emits the events
  110. revert();
  111. }
  112. /**
  113. * @dev Get all admin addresses
  114. * @return address list
  115. */
  116. function GetAllAdmin()
  117. public
  118. view
  119. returns(address[] memory)
  120. {
  121. address[] memory ret = new address[](adminList.length);
  122. for (uint i = 0; i < adminList.length; i++) {
  123. ret[i] = adminList[i];
  124. }
  125. return ret;
  126. }
  127. /*
  128. Fields
  129. */
  130. // A map of admin users who have the permission to update CHT and bloom Trie root
  131. mapping(address => bool) admins;
  132. // A list of admin users so that we can obtain all admin users.
  133. address[] adminList;
  134. // Latest stored section id
  135. uint64 sectionIndex;
  136. // The block height associated with latest registered checkpoint.
  137. uint height;
  138. // The hash of latest registered checkpoint.
  139. bytes32 hash;
  140. // The frequency for creating a checkpoint
  141. //
  142. // The default value should be the same as the checkpoint size(32768) in the ethereum.
  143. uint sectionSize;
  144. // The number of confirmations needed before a checkpoint can be registered.
  145. // We have to make sure the checkpoint registered will not be invalid due to
  146. // chain reorg.
  147. //
  148. // The default value should be the same as the checkpoint process confirmations(256)
  149. // in the ethereum.
  150. uint processConfirms;
  151. // The required signatures to finalize a stable checkpoint.
  152. uint threshold;
  153. }