forked from TrueCloudLab/neoneo-go
core: optimize tx verification, only get references and results once
Getting references requires DB access and that is expensive.
This commit is contained in:
parent
fe4916f691
commit
baeaa3dbe6
1 changed files with 19 additions and 13 deletions
|
@ -1364,7 +1364,12 @@ func (bc *Blockchain) verifyTx(t *transaction.Transaction, block *block.Block) e
|
||||||
if err := bc.verifyOutputs(t); err != nil {
|
if err := bc.verifyOutputs(t); err != nil {
|
||||||
return errors.Wrap(err, "wrong outputs")
|
return errors.Wrap(err, "wrong outputs")
|
||||||
}
|
}
|
||||||
if err := bc.verifyResults(t); err != nil {
|
refs, err := bc.References(t)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
results := refsAndOutsToResults(refs, t.Outputs)
|
||||||
|
if err := bc.verifyResults(t, results); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1383,7 +1388,7 @@ func (bc *Blockchain) verifyTx(t *transaction.Transaction, block *block.Block) e
|
||||||
if bc.dao.IsDoubleClaim(claim) {
|
if bc.dao.IsDoubleClaim(claim) {
|
||||||
return errors.New("double claim")
|
return errors.New("double claim")
|
||||||
}
|
}
|
||||||
if err := bc.verifyClaims(t); err != nil {
|
if err := bc.verifyClaims(t, results); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
case transaction.InvocationType:
|
case transaction.InvocationType:
|
||||||
|
@ -1396,10 +1401,9 @@ func (bc *Blockchain) verifyTx(t *transaction.Transaction, block *block.Block) e
|
||||||
return bc.verifyTxWitnesses(t, block)
|
return bc.verifyTxWitnesses(t, block)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (bc *Blockchain) verifyClaims(tx *transaction.Transaction) (err error) {
|
func (bc *Blockchain) verifyClaims(tx *transaction.Transaction, results []*transaction.Result) (err error) {
|
||||||
t := tx.Data.(*transaction.ClaimTX)
|
t := tx.Data.(*transaction.ClaimTX)
|
||||||
var result *transaction.Result
|
var result *transaction.Result
|
||||||
results := bc.GetTransactionResults(tx)
|
|
||||||
for i := range results {
|
for i := range results {
|
||||||
if results[i].AssetID == UtilityTokenID() {
|
if results[i].AssetID == UtilityTokenID() {
|
||||||
result = results[i]
|
result = results[i]
|
||||||
|
@ -1581,11 +1585,7 @@ func (bc *Blockchain) verifyOutputs(t *transaction.Transaction) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (bc *Blockchain) verifyResults(t *transaction.Transaction) error {
|
func (bc *Blockchain) verifyResults(t *transaction.Transaction, results []*transaction.Result) error {
|
||||||
results := bc.GetTransactionResults(t)
|
|
||||||
if results == nil {
|
|
||||||
return errors.New("tx has no results")
|
|
||||||
}
|
|
||||||
var resultsDestroy []*transaction.Result
|
var resultsDestroy []*transaction.Result
|
||||||
var resultsIssue []*transaction.Result
|
var resultsIssue []*transaction.Result
|
||||||
for _, re := range results {
|
for _, re := range results {
|
||||||
|
@ -1641,18 +1641,24 @@ func (bc *Blockchain) verifyResults(t *transaction.Transaction) error {
|
||||||
// GetTransactionResults returns the transaction results aggregate by assetID.
|
// GetTransactionResults returns the transaction results aggregate by assetID.
|
||||||
// Golang of GetTransationResults method in C# (https://github.com/neo-project/neo/blob/master/neo/Network/P2P/Payloads/Transaction.cs#L207)
|
// Golang of GetTransationResults method in C# (https://github.com/neo-project/neo/blob/master/neo/Network/P2P/Payloads/Transaction.cs#L207)
|
||||||
func (bc *Blockchain) GetTransactionResults(t *transaction.Transaction) []*transaction.Result {
|
func (bc *Blockchain) GetTransactionResults(t *transaction.Transaction) []*transaction.Result {
|
||||||
var results []*transaction.Result
|
|
||||||
tempResult := make(map[util.Uint256]util.Fixed8)
|
|
||||||
|
|
||||||
references, err := bc.References(t)
|
references, err := bc.References(t)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
return refsAndOutsToResults(references, t.Outputs)
|
||||||
|
}
|
||||||
|
|
||||||
|
// mapReferencesToResults returns cumulative results of transaction based in its
|
||||||
|
// references and outputs.
|
||||||
|
func refsAndOutsToResults(references []transaction.InOut, outputs []transaction.Output) []*transaction.Result {
|
||||||
|
var results []*transaction.Result
|
||||||
|
tempResult := make(map[util.Uint256]util.Fixed8)
|
||||||
|
|
||||||
for _, inout := range references {
|
for _, inout := range references {
|
||||||
c := tempResult[inout.Out.AssetID]
|
c := tempResult[inout.Out.AssetID]
|
||||||
tempResult[inout.Out.AssetID] = c.Add(inout.Out.Amount)
|
tempResult[inout.Out.AssetID] = c.Add(inout.Out.Amount)
|
||||||
}
|
}
|
||||||
for _, output := range t.Outputs {
|
for _, output := range outputs {
|
||||||
c := tempResult[output.AssetID]
|
c := tempResult[output.AssetID]
|
||||||
tempResult[output.AssetID] = c.Sub(output.Amount)
|
tempResult[output.AssetID] = c.Sub(output.Amount)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue