Skip to content

Commit c36cd6f

Browse files
authored
Merge branch 'master' into element-id
2 parents 4fe2c45 + 09f8e35 commit c36cd6f

24 files changed

+2575
-262
lines changed

Diff for: .github/workflows/main.yml

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
name: Lint & Test
2+
on:
3+
pull_request:
4+
push:
5+
branches:
6+
- master
7+
8+
jobs:
9+
test:
10+
uses: SiaFoundation/workflows/.github/workflows/go-test.yml@master
11+
with:
12+
try-build: false

Diff for: .github/workflows/nightly.yml

-32
This file was deleted.

Diff for: .github/workflows/test.yml

-34
This file was deleted.

Diff for: consensus/state.go

+37-46
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,8 @@ type Network struct {
5050
InitialCoinbase types.Currency `json:"initialCoinbase"`
5151
MinimumCoinbase types.Currency `json:"minimumCoinbase"`
5252
InitialTarget types.BlockID `json:"initialTarget"`
53+
BlockInterval time.Duration `json:"blockInterval"`
54+
MaturityDelay uint64 `json:"maturityDelay"`
5355

5456
HardforkDevAddr struct {
5557
Height uint64 `json:"height"`
@@ -225,7 +227,7 @@ func (s State) SufficientlyHeavierThan(t State) bool {
225227

226228
// BlockInterval is the expected wall clock time between consecutive blocks.
227229
func (s State) BlockInterval() time.Duration {
228-
return 10 * time.Minute
230+
return s.Network.BlockInterval
229231
}
230232

231233
// BlockReward returns the reward for mining a child block.
@@ -240,7 +242,7 @@ func (s State) BlockReward() types.Currency {
240242
// MaturityHeight is the height at which various outputs created in the child
241243
// block will "mature" (become spendable).
242244
func (s State) MaturityHeight() uint64 {
243-
return s.childHeight() + 144
245+
return s.childHeight() + s.Network.MaturityDelay
244246
}
245247

246248
// SiafundCount is the number of siafunds in existence.
@@ -256,12 +258,12 @@ func (s State) AncestorDepth() uint64 {
256258

257259
// FoundationSubsidy returns the Foundation subsidy output for the child block.
258260
// 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) {
260262
sco.Address = s.FoundationPrimaryAddress
261263

262264
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
265267
hardforkHeight := s.Network.HardforkFoundation.Height
266268
if s.childHeight() < hardforkHeight || (s.childHeight()-hardforkHeight)%blocksPerMonth != 0 {
267269
sco.Value = types.ZeroCurrency
@@ -270,7 +272,7 @@ func (s State) FoundationSubsidy() (sco types.SiacoinOutput) {
270272
} else {
271273
sco.Value = subsidyPerBlock.Mul64(blocksPerMonth)
272274
}
273-
return
275+
return sco, !sco.Value.IsZero()
274276
}
275277

276278
// 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
626628
if i, ok := ms.created[id]; ok {
627629
return ms.fces[i], true
628630
}
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)
654632
}
655633

656634
func (ms *MidState) spent(id types.ElementID) (types.TransactionID, bool) {
@@ -684,6 +662,25 @@ func NewMidState(s State) *MidState {
684662
}
685663
}
686664

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+
687684
// A V1TransactionSupplement contains elements that are associated with a v1
688685
// transaction, but not included in the transaction. For example, v1
689686
// transactions reference the ID of each SiacoinOutput they spend, but do not
@@ -695,24 +692,23 @@ type V1TransactionSupplement struct {
695692
SiacoinInputs []types.SiacoinElement
696693
SiafundInputs []types.SiafundElement
697694
RevisedFileContracts []types.FileContractElement
698-
ValidFileContracts []types.FileContractElement
699-
StorageProofBlockIDs []types.BlockID // must match ValidFileContracts
695+
StorageProofs []V1StorageProofSupplement
700696
}
701697

702698
// EncodeTo implements types.EncoderTo.
703699
func (ts V1TransactionSupplement) EncodeTo(e *types.Encoder) {
704700
types.EncodeSlice(e, ts.SiacoinInputs)
705701
types.EncodeSlice(e, ts.SiafundInputs)
706702
types.EncodeSlice(e, ts.RevisedFileContracts)
707-
types.EncodeSlice(e, ts.ValidFileContracts)
703+
types.EncodeSlice(e, ts.StorageProofs)
708704
}
709705

710706
// DecodeFrom implements types.DecoderFrom.
711707
func (ts *V1TransactionSupplement) DecodeFrom(d *types.Decoder) {
712708
types.DecodeSlice(d, &ts.SiacoinInputs)
713709
types.DecodeSlice(d, &ts.SiafundInputs)
714710
types.DecodeSlice(d, &ts.RevisedFileContracts)
715-
types.DecodeSlice(d, &ts.ValidFileContracts)
711+
types.DecodeSlice(d, &ts.StorageProofs)
716712
}
717713

718714
func (ts V1TransactionSupplement) siacoinElement(id types.SiacoinOutputID) (sce types.SiacoinElement, ok bool) {
@@ -733,27 +729,22 @@ func (ts V1TransactionSupplement) siafundElement(id types.SiafundOutputID) (sfe
733729
return
734730
}
735731

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) {
737733
for _, fce := range ts.RevisedFileContracts {
738734
if types.FileContractID(fce.ID) == id {
739735
return fce, true
740736
}
741737
}
742-
for _, fce := range ts.ValidFileContracts {
743-
if types.FileContractID(fce.ID) == id {
744-
return fce, true
745-
}
746-
}
747738
return
748739
}
749740

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
754745
}
755746
}
756-
panic("missing contract for storage proof window ID") // developer error
747+
return
757748
}
758749

759750
// A V1BlockSupplement contains elements that are associated with a v1 block,

Diff for: consensus/update.go

+22-8
Original file line numberDiff line numberDiff line change
@@ -463,13 +463,20 @@ func (ms *MidState) addAttestationElement(ae types.AttestationElement) {
463463
func (ms *MidState) ApplyTransaction(txn types.Transaction, ts V1TransactionSupplement) {
464464
txid := txn.ID()
465465
for _, sci := range txn.SiacoinInputs {
466-
ms.spendSiacoinElement(ms.mustSiacoinElement(ts, sci.ParentID), txid)
466+
sce, ok := ms.siacoinElement(ts, sci.ParentID)
467+
if !ok {
468+
panic("missing SiacoinElement")
469+
}
470+
ms.spendSiacoinElement(sce, txid)
467471
}
468472
for i, sco := range txn.SiacoinOutputs {
469473
ms.addSiacoinElement(txn.SiacoinOutputID(i), sco)
470474
}
471475
for _, sfi := range txn.SiafundInputs {
472-
sfe := ms.mustSiafundElement(ts, sfi.ParentID)
476+
sfe, ok := ms.siafundElement(ts, sfi.ParentID)
477+
if !ok {
478+
panic("missing SiafundElement")
479+
}
473480
claimPortion := ms.siafundPool.Sub(sfe.ClaimStart).Div64(ms.base.SiafundCount()).Mul64(sfe.SiafundOutput.Value)
474481
ms.spendSiafundElement(sfe, txid)
475482
ms.addImmatureSiacoinElement(sfi.ParentID.ClaimOutputID(), types.SiacoinOutput{Value: claimPortion, Address: sfi.ClaimAddress})
@@ -481,12 +488,19 @@ func (ms *MidState) ApplyTransaction(txn types.Transaction, ts V1TransactionSupp
481488
ms.addFileContractElement(txn.FileContractID(i), fc)
482489
}
483490
for _, fcr := range txn.FileContractRevisions {
484-
ms.reviseFileContractElement(ms.mustFileContractElement(ts, fcr.ParentID), fcr.FileContract)
491+
fce, ok := ms.fileContractElement(ts, fcr.ParentID)
492+
if !ok {
493+
panic("missing FileContractElement")
494+
}
495+
ms.reviseFileContractElement(fce, fcr.FileContract)
485496
}
486497
for _, sp := range txn.StorageProofs {
487-
fce := ms.mustFileContractElement(ts, sp.ParentID)
488-
ms.resolveFileContractElement(fce, true, txid)
489-
for i, sco := range fce.FileContract.ValidProofOutputs {
498+
sps, ok := ts.storageProof(sp.ParentID)
499+
if !ok {
500+
panic("missing V1StorageProofSupplement")
501+
}
502+
ms.resolveFileContractElement(sps.FileContract, true, txid)
503+
for i, sco := range sps.FileContract.FileContract.ValidProofOutputs {
490504
ms.addImmatureSiacoinElement(sp.ParentID.ValidOutputID(i), sco)
491505
}
492506
}
@@ -541,7 +555,7 @@ func (ms *MidState) ApplyV2Transaction(txn types.V2Transaction) {
541555
case *types.V2StorageProof:
542556
renter, host = fc.RenterOutput, fc.HostOutput
543557
case *types.V2FileContractFinalization:
544-
renter, host = r.RenterOutput, r.HostOutput
558+
renter, host = fc.RenterOutput, fc.HostOutput
545559
case *types.V2FileContractExpiration:
546560
renter, host = fc.RenterOutput, fc.MissedHostOutput()
547561
}
@@ -573,7 +587,7 @@ func (ms *MidState) ApplyBlock(b types.Block, bs V1BlockSupplement) {
573587
for i, sco := range b.MinerPayouts {
574588
ms.addImmatureSiacoinElement(bid.MinerOutputID(i), sco)
575589
}
576-
if subsidy := ms.base.FoundationSubsidy(); !subsidy.Value.IsZero() {
590+
if subsidy, ok := ms.base.FoundationSubsidy(); ok {
577591
ms.addImmatureSiacoinElement(bid.FoundationOutputID(), subsidy)
578592
}
579593
for _, fce := range bs.ExpiringFileContracts {

Diff for: consensus/update_test.go

+10-8
Original file line numberDiff line numberDiff line change
@@ -826,8 +826,8 @@ func TestApplyRevertBlockV1(t *testing.T) {
826826
}
827827
}
828828
addedSCEs = []types.SiacoinElement{
829-
{SiacoinOutput: txnB3.FileContracts[0].ValidProofOutputs[1], MaturityHeight: 148},
830-
{SiacoinOutput: txnB3.FileContracts[0].ValidProofOutputs[0], MaturityHeight: 148},
829+
{SiacoinOutput: txnB3.FileContracts[0].ValidProofOutputs[1], MaturityHeight: cs.MaturityHeight()},
830+
{SiacoinOutput: txnB3.FileContracts[0].ValidProofOutputs[0], MaturityHeight: cs.MaturityHeight()},
831831
{SiacoinOutput: b5.MinerPayouts[0], MaturityHeight: cs.MaturityHeight()},
832832
}
833833
spentSCEs = nil
@@ -836,8 +836,10 @@ func TestApplyRevertBlockV1(t *testing.T) {
836836

837837
// add block with storage proof
838838
bs = db.supplementTipBlock(b5)
839-
bs.Transactions[0].ValidFileContracts = append(bs.Transactions[0].ValidFileContracts, db.fces[txnB5.StorageProofs[0].ParentID])
840-
bs.Transactions[0].StorageProofBlockIDs = append(bs.Transactions[0].StorageProofBlockIDs, b3.ID())
839+
bs.Transactions[0].StorageProofs = append(bs.Transactions[0].StorageProofs, V1StorageProofSupplement{
840+
FileContract: db.fces[txnB5.StorageProofs[0].ParentID],
841+
WindowID: b3.ID(),
842+
})
841843
prev = cs
842844
if au, err := addBlock(&b5, bs); err != nil {
843845
t.Fatal(err)
@@ -911,8 +913,7 @@ func TestApplyRevertBlockV2(t *testing.T) {
911913
r.RenterSignature = renterPrivateKey.SignHash(cs.RenewalSigHash(*r))
912914
r.HostSignature = hostPrivateKey.SignHash(cs.RenewalSigHash(*r))
913915
case *types.V2FileContractFinalization:
914-
r.RenterSignature = renterPrivateKey.SignHash(cs.ContractSigHash(types.V2FileContract(*r)))
915-
r.HostSignature = hostPrivateKey.SignHash(cs.ContractSigHash(types.V2FileContract(*r)))
916+
*r = types.V2FileContractFinalization(renterPrivateKey.SignHash(cs.ContractSigHash(txn.FileContractResolutions[i].Parent.V2FileContract)))
916917
}
917918
}
918919
}
@@ -1095,6 +1096,7 @@ func TestApplyRevertBlockV2(t *testing.T) {
10951096
v1FC.Filesize = 65
10961097
v1FC.FileMerkleRoot = blake2b.SumPair((State{}).StorageProofLeafHash([]byte{1}), (State{}).StorageProofLeafHash([]byte{2}))
10971098
v2FC := types.V2FileContract{
1099+
Capacity: v1FC.Filesize,
10981100
Filesize: v1FC.Filesize,
10991101
FileMerkleRoot: v1FC.FileMerkleRoot,
11001102
ProofHeight: 20,
@@ -1252,8 +1254,8 @@ func TestApplyRevertBlockV2(t *testing.T) {
12521254
}
12531255

12541256
addedSCEs = []types.SiacoinElement{
1255-
{SiacoinOutput: txnB3.FileContracts[0].RenterOutput, MaturityHeight: 148},
1256-
{SiacoinOutput: txnB3.FileContracts[0].HostOutput, MaturityHeight: 148},
1257+
{SiacoinOutput: txnB3.FileContracts[0].RenterOutput, MaturityHeight: cs.MaturityHeight()},
1258+
{SiacoinOutput: txnB3.FileContracts[0].HostOutput, MaturityHeight: cs.MaturityHeight()},
12571259
{SiacoinOutput: b5.MinerPayouts[0], MaturityHeight: cs.MaturityHeight()},
12581260
}
12591261
spentSCEs = nil

0 commit comments

Comments
 (0)