core: add double claim verification check
This commit is contained in:
parent
29586f2aa7
commit
7bea6e043e
2 changed files with 30 additions and 0 deletions
|
@ -1150,6 +1150,9 @@ func (bc *Blockchain) verifyTx(t *transaction.Transaction, block *block.Block) e
|
||||||
if transaction.HaveDuplicateInputs(claim.Claims) {
|
if transaction.HaveDuplicateInputs(claim.Claims) {
|
||||||
return errors.New("duplicate claims")
|
return errors.New("duplicate claims")
|
||||||
}
|
}
|
||||||
|
if bc.dao.IsDoubleClaim(claim) {
|
||||||
|
return errors.New("double claim")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return bc.verifyTxWitnesses(t, block)
|
return bc.verifyTxWitnesses(t, block)
|
||||||
|
@ -1171,6 +1174,12 @@ func (bc *Blockchain) isTxStillRelevant(t *transaction.Transaction) bool {
|
||||||
if bc.dao.IsDoubleSpend(t) {
|
if bc.dao.IsDoubleSpend(t) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
if t.Type == transaction.ClaimType {
|
||||||
|
claim := t.Data.(*transaction.ClaimTX)
|
||||||
|
if bc.dao.IsDoubleClaim(claim) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
for i := range t.Scripts {
|
for i := range t.Scripts {
|
||||||
if !vm.IsStandardContract(t.Scripts[i].VerificationScript) {
|
if !vm.IsStandardContract(t.Scripts[i].VerificationScript) {
|
||||||
recheckWitness = true
|
recheckWitness = true
|
||||||
|
|
|
@ -562,6 +562,27 @@ func (dao *dao) IsDoubleSpend(tx *transaction.Transaction) bool {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// IsDoubleClaim verifies that given claim inputs are not already claimed by another tx.
|
||||||
|
func (dao *dao) IsDoubleClaim(claim *transaction.ClaimTX) bool {
|
||||||
|
if len(claim.Claims) == 0 {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
for _, inputs := range transaction.GroupInputsByPrevHash(claim.Claims) {
|
||||||
|
prevHash := inputs[0].PrevHash
|
||||||
|
scs, err := dao.GetSpentCoinState(prevHash)
|
||||||
|
if err != nil {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
for _, input := range inputs {
|
||||||
|
_, ok := scs.items[input.PrevIndex]
|
||||||
|
if !ok {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
// Persist flushes all the changes made into the (supposedly) persistent
|
// Persist flushes all the changes made into the (supposedly) persistent
|
||||||
// underlying store.
|
// underlying store.
|
||||||
func (dao *dao) Persist() (int, error) {
|
func (dao *dao) Persist() (int, error) {
|
||||||
|
|
Loading…
Reference in a new issue