miner.hoon 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160
  1. /= dk /apps/dumbnet/lib/types
  2. /= sp /common/stark/prover
  3. /= dumb-transact /common/tx-engine
  4. /= * /common/zoon
  5. ::
  6. :: everything to do with mining and mining state
  7. ::
  8. |_ [m=mining-state:dk =blockchain-constants:dumb-transact]
  9. +* t ~(. dumb-transact blockchain-constants)
  10. +| %admin
  11. :: +set-mining: set .mining
  12. ++ set-mining
  13. |= mine=?
  14. ^- mining-state:dk
  15. m(mining mine)
  16. ::
  17. :: +set-pubkey: set .pubkey
  18. ++ set-pubkeys
  19. |= pks=(list lock:t)
  20. ^- mining-state:dk
  21. =. pubkeys.m
  22. (~(gas z-in *(z-set lock:t)) pks)
  23. m
  24. ::
  25. :: +set-shares validate and set .shares
  26. ++ set-shares
  27. |= shr=(list [lock:t @])
  28. =/ s=shares:t (~(gas z-by *(z-map lock:t @)) shr)
  29. ?. (validate:shares:t s)
  30. ~|('invalid shares' !!)
  31. m(shares s)
  32. ::
  33. +| %candidate-block
  34. ++ set-pow
  35. |= prf=proof:sp
  36. ^- mining-state:dk
  37. m(pow.candidate-block (some prf))
  38. ::
  39. ++ set-digest
  40. ^- mining-state:dk
  41. m(digest.candidate-block (compute-digest:page:t candidate-block.m))
  42. ::
  43. :: +update-timestamp: updates timestamp on candidate block if needed
  44. ::
  45. :: this should be run every time we get a poke.
  46. ++ update-timestamp
  47. |= now=@da
  48. ^- mining-state:dk
  49. ?: |(=(*page:t candidate-block.m) !mining.m)
  50. :: not mining or no candidate block is set so no need to update timestamp
  51. m
  52. ?: %+ gte timestamp.candidate-block.m
  53. (time-in-secs:page:t (sub now update-candidate-timestamp-interval:t))
  54. :: has not been ~m2, so leave timestamp alone
  55. m
  56. =. timestamp.candidate-block.m (time-in-secs:page:t now)
  57. =/ print-var
  58. %- trip
  59. ^- @t
  60. %^ cat 3
  61. 'candidate block timestamp updated: '
  62. (scot %$ timestamp.candidate-block.m)
  63. ~> %slog.[0 [%leaf print-var]]
  64. m
  65. ::
  66. :: +heard-new-tx: potentially changes candidate block in reaction to a raw-tx
  67. ++ heard-new-tx
  68. |= raw=raw-tx:t
  69. ^- mining-state:dk
  70. ~> %slog.[3 'miner: heard-new-tx']
  71. ~> %slog.[3 (cat 3 'miner: heard-new-tx: raw-tx: ' (to-b58:hash:t id.raw))]
  72. ::
  73. :: if the mining pubkey is not set, do nothing
  74. ?: =(*(z-set lock:t) pubkeys.m) m
  75. :: check to see if block is valid with tx - this checks whether the inputs
  76. :: exist, whether the new size will exceed block size, and whether timelocks
  77. :: are valid
  78. =/ tx=(unit tx:t) (mole |.((new:tx:t raw height.candidate-block.m)))
  79. ?~ tx
  80. :: invalid tx. we don't emit a %liar effect from this because it might
  81. :: just not be valid for this particular block
  82. m
  83. =/ new-acc=(unit tx-acc:t)
  84. (process:tx-acc:t candidate-acc.m u.tx height.candidate-block.m)
  85. ?~ new-acc
  86. ::~& >>> """
  87. :: tx {(trip (to-b58:hash:t id.raw))} cannot be added to candidate
  88. :: block.
  89. :: """
  90. m
  91. :: we can add tx to candidate-block
  92. =. tx-ids.candidate-block.m
  93. (~(put z-in tx-ids.candidate-block.m) id.raw)
  94. =/ old-fees=coins:t fees.candidate-acc.m
  95. =. candidate-acc.m u.new-acc
  96. =/ new-fees=coins:t fees.candidate-acc.m
  97. :: check if new-fees != old-fees to determine if split should be recalculated.
  98. :: since we don't have replace-by-fee
  99. ?: =(new-fees old-fees)
  100. :: fees are equal so no need to recalculate split
  101. m
  102. :: fees are unequal. for this miner, fees are only ever monotonically
  103. :: incremented and so this assertion should never fail.
  104. ?> (gth new-fees old-fees)
  105. =/ fee-diff=coins:t (sub new-fees old-fees)
  106. :: compute old emission+fees
  107. =/ old-assets=coins:t
  108. %+ roll ~(val z-by coinbase.candidate-block.m)
  109. |= [c=coins:t sum=coins:t]
  110. (add c sum)
  111. =/ new-assets=coins:t (add old-assets fee-diff)
  112. =. coinbase.candidate-block.m
  113. (new:coinbase-split:t new-assets shares.m)
  114. m
  115. ::
  116. :: +heard-new-block: refreshes the candidate block to be mined in reaction to a new block
  117. ::
  118. :: when we hear a new heaviest block, we need to update the candidate we're attempting
  119. :: to mine. that means we should update the parent and page number of the block, and carry
  120. :: over any transactions we had previously been attempting to include that werent
  121. :: included in the most recent block.
  122. ++ heard-new-block
  123. |= [c=consensus-state:dk p=pending-state:dk now=@da]
  124. ^- mining-state:dk
  125. ::
  126. :: do a sanity check that we have a heaviest block, and that the heaviest block
  127. :: is not the parent of our current candidate block
  128. ?~ heaviest-block.c
  129. :: genesis block has its own codepath, which is why this conditional does not attempt
  130. :: to generate the genesis block
  131. ~> %slog.[0 leaf+"attempted to generate new candidate block when we have no genesis block"]
  132. m
  133. ?: =(u.heaviest-block.c parent.candidate-block.m)
  134. ~> %slog.[0 leaf+"heaviest block unchanged, do not generate new candidate block"]
  135. m
  136. ?: =(*(z-set lock:t) pubkeys.m)
  137. ~> %slog.[0 leaf+"no pubkey(s) set so no new candidate block will be generated"]
  138. m
  139. =/ print-var
  140. %- trip
  141. ^- @t
  142. %^ cat 3
  143. 'generating new candidate block with parent: '
  144. (to-b58:hash:t u.heaviest-block.c)
  145. ~> %slog.[0 [%leaf print-var]]
  146. =. candidate-block.m
  147. %- new-candidate:page:t
  148. :* (to-page:local-page:t (~(got z-by blocks.c) u.heaviest-block.c))
  149. now
  150. (~(got z-by targets.c) u.heaviest-block.c)
  151. shares.m
  152. ==
  153. =. candidate-acc.m
  154. (new:tx-acc:t (~(get z-by balance.c) u.heaviest-block.c))
  155. ::
  156. :: roll over the pending txs and try to include them in the new candidate block
  157. %+ roll ~(val z-by raw-txs.p)
  158. |= [raw=raw-tx:t min=_m]
  159. (heard-new-tx raw)
  160. --