@@ -50,6 +50,8 @@ type Network struct {
50
50
InitialCoinbase types.Currency `json:"initialCoinbase"`
51
51
MinimumCoinbase types.Currency `json:"minimumCoinbase"`
52
52
InitialTarget types.BlockID `json:"initialTarget"`
53
+ BlockInterval time.Duration `json:"blockInterval"`
54
+ MaturityDelay uint64 `json:"maturityDelay"`
53
55
54
56
HardforkDevAddr struct {
55
57
Height uint64 `json:"height"`
@@ -225,7 +227,7 @@ func (s State) SufficientlyHeavierThan(t State) bool {
225
227
226
228
// BlockInterval is the expected wall clock time between consecutive blocks.
227
229
func (s State ) BlockInterval () time.Duration {
228
- return 10 * time . Minute
230
+ return s . Network . BlockInterval
229
231
}
230
232
231
233
// BlockReward returns the reward for mining a child block.
@@ -240,7 +242,7 @@ func (s State) BlockReward() types.Currency {
240
242
// MaturityHeight is the height at which various outputs created in the child
241
243
// block will "mature" (become spendable).
242
244
func (s State ) MaturityHeight () uint64 {
243
- return s .childHeight () + 144
245
+ return s .childHeight () + s . Network . MaturityDelay
244
246
}
245
247
246
248
// SiafundCount is the number of siafunds in existence.
@@ -256,12 +258,12 @@ func (s State) AncestorDepth() uint64 {
256
258
257
259
// FoundationSubsidy returns the Foundation subsidy output for the child block.
258
260
// If no subsidy is due, the returned output has a value of zero.
259
- func (s State ) FoundationSubsidy () (sco types.SiacoinOutput ) {
261
+ func (s State ) FoundationSubsidy () (sco types.SiacoinOutput , exists bool ) {
260
262
sco .Address = s .FoundationPrimaryAddress
261
263
262
264
subsidyPerBlock := types .Siacoins (30000 )
263
- const blocksPerYear = 144 * 365
264
- const blocksPerMonth = blocksPerYear / 12
265
+ blocksPerYear := uint64 ( 365 * 24 * time . Hour / s . BlockInterval ())
266
+ blocksPerMonth : = blocksPerYear / 12
265
267
hardforkHeight := s .Network .HardforkFoundation .Height
266
268
if s .childHeight () < hardforkHeight || (s .childHeight ()- hardforkHeight )% blocksPerMonth != 0 {
267
269
sco .Value = types .ZeroCurrency
@@ -270,7 +272,7 @@ func (s State) FoundationSubsidy() (sco types.SiacoinOutput) {
270
272
} else {
271
273
sco .Value = subsidyPerBlock .Mul64 (blocksPerMonth )
272
274
}
273
- return
275
+ return sco , ! sco . Value . IsZero ()
274
276
}
275
277
276
278
// NonceFactor is the factor by which all block nonces must be divisible.
@@ -626,31 +628,7 @@ func (ms *MidState) fileContractElement(ts V1TransactionSupplement, id types.Fil
626
628
if i , ok := ms .created [id ]; ok {
627
629
return ms .fces [i ], true
628
630
}
629
- return ts .fileContractElement (id )
630
- }
631
-
632
- func (ms * MidState ) mustSiacoinElement (ts V1TransactionSupplement , id types.SiacoinOutputID ) types.SiacoinElement {
633
- sce , ok := ms .siacoinElement (ts , id )
634
- if ! ok {
635
- panic ("missing SiacoinElement" )
636
- }
637
- return sce
638
- }
639
-
640
- func (ms * MidState ) mustSiafundElement (ts V1TransactionSupplement , id types.SiafundOutputID ) types.SiafundElement {
641
- sfe , ok := ms .siafundElement (ts , id )
642
- if ! ok {
643
- panic ("missing SiafundElement" )
644
- }
645
- return sfe
646
- }
647
-
648
- func (ms * MidState ) mustFileContractElement (ts V1TransactionSupplement , id types.FileContractID ) types.FileContractElement {
649
- fce , ok := ms .fileContractElement (ts , id )
650
- if ! ok {
651
- panic ("missing FileContractElement" )
652
- }
653
- return fce
631
+ return ts .revision (id )
654
632
}
655
633
656
634
func (ms * MidState ) spent (id types.ElementID ) (types.TransactionID , bool ) {
@@ -684,6 +662,25 @@ func NewMidState(s State) *MidState {
684
662
}
685
663
}
686
664
665
+ // A V1StorageProofSupplement pairs a file contract with the block ID used to
666
+ // derive its storage proof leaf index.
667
+ type V1StorageProofSupplement struct {
668
+ FileContract types.FileContractElement
669
+ WindowID types.BlockID
670
+ }
671
+
672
+ // EncodeTo implements types.EncoderTo.
673
+ func (sps V1StorageProofSupplement ) EncodeTo (e * types.Encoder ) {
674
+ sps .FileContract .EncodeTo (e )
675
+ sps .WindowID .EncodeTo (e )
676
+ }
677
+
678
+ // DecodeFrom implements types.DecoderFrom.
679
+ func (sps * V1StorageProofSupplement ) DecodeFrom (d * types.Decoder ) {
680
+ sps .FileContract .DecodeFrom (d )
681
+ sps .WindowID .DecodeFrom (d )
682
+ }
683
+
687
684
// A V1TransactionSupplement contains elements that are associated with a v1
688
685
// transaction, but not included in the transaction. For example, v1
689
686
// transactions reference the ID of each SiacoinOutput they spend, but do not
@@ -695,24 +692,23 @@ type V1TransactionSupplement struct {
695
692
SiacoinInputs []types.SiacoinElement
696
693
SiafundInputs []types.SiafundElement
697
694
RevisedFileContracts []types.FileContractElement
698
- ValidFileContracts []types.FileContractElement
699
- StorageProofBlockIDs []types.BlockID // must match ValidFileContracts
695
+ StorageProofs []V1StorageProofSupplement
700
696
}
701
697
702
698
// EncodeTo implements types.EncoderTo.
703
699
func (ts V1TransactionSupplement ) EncodeTo (e * types.Encoder ) {
704
700
types .EncodeSlice (e , ts .SiacoinInputs )
705
701
types .EncodeSlice (e , ts .SiafundInputs )
706
702
types .EncodeSlice (e , ts .RevisedFileContracts )
707
- types .EncodeSlice (e , ts .ValidFileContracts )
703
+ types .EncodeSlice (e , ts .StorageProofs )
708
704
}
709
705
710
706
// DecodeFrom implements types.DecoderFrom.
711
707
func (ts * V1TransactionSupplement ) DecodeFrom (d * types.Decoder ) {
712
708
types .DecodeSlice (d , & ts .SiacoinInputs )
713
709
types .DecodeSlice (d , & ts .SiafundInputs )
714
710
types .DecodeSlice (d , & ts .RevisedFileContracts )
715
- types .DecodeSlice (d , & ts .ValidFileContracts )
711
+ types .DecodeSlice (d , & ts .StorageProofs )
716
712
}
717
713
718
714
func (ts V1TransactionSupplement ) siacoinElement (id types.SiacoinOutputID ) (sce types.SiacoinElement , ok bool ) {
@@ -733,27 +729,22 @@ func (ts V1TransactionSupplement) siafundElement(id types.SiafundOutputID) (sfe
733
729
return
734
730
}
735
731
736
- func (ts V1TransactionSupplement ) fileContractElement (id types.FileContractID ) (fce types.FileContractElement , ok bool ) {
732
+ func (ts V1TransactionSupplement ) revision (id types.FileContractID ) (fce types.FileContractElement , ok bool ) {
737
733
for _ , fce := range ts .RevisedFileContracts {
738
734
if types .FileContractID (fce .ID ) == id {
739
735
return fce , true
740
736
}
741
737
}
742
- for _ , fce := range ts .ValidFileContracts {
743
- if types .FileContractID (fce .ID ) == id {
744
- return fce , true
745
- }
746
- }
747
738
return
748
739
}
749
740
750
- func (ts V1TransactionSupplement ) storageProofWindowID (id types.FileContractID ) types. BlockID {
751
- for i , fce := range ts .ValidFileContracts {
752
- if types .FileContractID (fce .ID ) == id {
753
- return ts . StorageProofBlockIDs [ i ]
741
+ func (ts V1TransactionSupplement ) storageProof (id types.FileContractID ) ( sps V1StorageProofSupplement , ok bool ) {
742
+ for _ , sps := range ts .StorageProofs {
743
+ if types .FileContractID (sps . FileContract .ID ) == id {
744
+ return sps , true
754
745
}
755
746
}
756
- panic ( "missing contract for storage proof window ID" ) // developer error
747
+ return
757
748
}
758
749
759
750
// A V1BlockSupplement contains elements that are associated with a v1 block,
0 commit comments