Skip to content

Commit

Permalink
Merge pull request #195 from SiaFoundation/nate/fix-consensus-revisions
Browse files Browse the repository at this point in the history
Fix consensus revisions
  • Loading branch information
n8maninger authored Sep 1, 2024
2 parents a91ba45 + 44ed6f4 commit 55fcd20
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 1 deletion.
3 changes: 3 additions & 0 deletions consensus/state.go
Original file line number Diff line number Diff line change
Expand Up @@ -620,6 +620,9 @@ func (ms *MidState) siafundElement(ts V1TransactionSupplement, id types.SiafundO
}

func (ms *MidState) fileContractElement(ts V1TransactionSupplement, id types.FileContractID) (types.FileContractElement, bool) {
if rev, ok := ms.revs[types.Hash256(id)]; ok {
return *rev, true
}
if i, ok := ms.created[types.Hash256(id)]; ok {
return ms.fces[i], true
}
Expand Down
6 changes: 6 additions & 0 deletions consensus/validation.go
Original file line number Diff line number Diff line change
Expand Up @@ -238,11 +238,15 @@ func validateSiafunds(ms *MidState, txn types.Transaction, ts V1TransactionSuppl
}

func validateFileContracts(ms *MidState, txn types.Transaction, ts V1TransactionSupplement) error {
v2RequireHeight := ms.base.Network.HardforkV2.RequireHeight

for i, fc := range txn.FileContracts {
if fc.WindowStart < ms.base.childHeight() {
return fmt.Errorf("file contract %v has window that starts in the past", i)
} else if fc.WindowEnd <= fc.WindowStart {
return fmt.Errorf("file contract %v has window that ends before it begins", i)
} else if fc.WindowStart >= v2RequireHeight {
return fmt.Errorf("file contract %v has window that starts after v2 hardfork", i)
}
var validSum, missedSum types.Currency
for _, output := range fc.ValidProofOutputs {
Expand All @@ -265,6 +269,8 @@ func validateFileContracts(ms *MidState, txn types.Transaction, ts V1Transaction
return fmt.Errorf("file contract revision %v has window that starts in the past", i)
} else if fcr.FileContract.WindowEnd <= fcr.FileContract.WindowStart {
return fmt.Errorf("file contract revision %v has window that ends before it begins", i)
} else if fcr.WindowStart >= v2RequireHeight {
return fmt.Errorf("file contract %v has window that starts after v2 hardfork", i)
} else if txid, ok := ms.spent(types.Hash256(fcr.ParentID)); ok {
return fmt.Errorf("file contract revision %v conflicts with previous proof or revision (in %v)", i, txid)
}
Expand Down
38 changes: 37 additions & 1 deletion consensus/validation_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -365,6 +365,9 @@ func TestValidateBlock(t *testing.T) {
t.Fatal(err)
}

// clear signatures to avoid false positives
validBlock.Transactions[0].Signatures = nil

// tests with correct signatures
{
tests := []struct {
Expand Down Expand Up @@ -658,6 +661,32 @@ func TestValidateBlock(t *testing.T) {
txn.FileContractRevisions = append(txn.FileContractRevisions, newRevision)
},
},
{
"misordered revisions",
func(b *types.Block) {
newRevision := b.Transactions[0].FileContractRevisions[0]
newRevision.RevisionNumber = 99

b.Transactions = append(b.Transactions, types.Transaction{
FileContractRevisions: []types.FileContractRevision{newRevision},
})

// set the initial revision number to be higher than the new
// revision
b.Transactions[0].FileContractRevisions[0].RevisionNumber = 100
},
},
{
"duplicate revisions in same block",
func(b *types.Block) {
txn := &b.Transactions[0]
newRevision := txn.FileContractRevisions[0]

b.Transactions = append(b.Transactions, types.Transaction{
FileContractRevisions: []types.FileContractRevision{newRevision},
})
},
},
{
"double-spent siacoin input",
func(b *types.Block) {
Expand Down Expand Up @@ -685,11 +714,15 @@ func TestValidateBlock(t *testing.T) {
for _, test := range tests {
corruptBlock := deepCopyBlock(validBlock)
test.corrupt(&corruptBlock)
signTxn(&corruptBlock.Transactions[0])
for i := range corruptBlock.Transactions {
signTxn(&corruptBlock.Transactions[i])
}
findBlockNonce(cs, &corruptBlock)

if err := ValidateBlock(cs, corruptBlock, db.supplementTipBlock(corruptBlock)); err == nil {
t.Fatalf("accepted block with %v", test.desc)
} else {
t.Log(test.desc, err)
}
}
}
Expand Down Expand Up @@ -758,6 +791,9 @@ func TestValidateBlock(t *testing.T) {
}
for _, test := range tests {
corruptBlock := deepCopyBlock(validBlock)
for i := range corruptBlock.Transactions {
signTxn(&corruptBlock.Transactions[i])
}
test.corrupt(&corruptBlock)
findBlockNonce(cs, &corruptBlock)

Expand Down

0 comments on commit 55fcd20

Please sign in to comment.