package state
import (
- "errors"
-
"github.com/vapor/consensus"
"github.com/vapor/database/storage"
+ "github.com/vapor/errors"
"github.com/vapor/protocol/bc"
)
func (view *UtxoViewpoint) ApplyTransaction(block *bc.Block, tx *bc.Tx, statusFail bool) error {
for _, prevout := range tx.SpentOutputIDs {
- spentOutput, err := tx.Output(prevout)
+ assetID := bc.AssetID{}
+ entryOutput, err := tx.Entry(prevout)
if err != nil {
return err
}
- if statusFail && *spentOutput.Source.Value.AssetId != *consensus.BTMAssetID {
+
+ switch output := entryOutput.(type) {
+ case *bc.IntraChainOutput:
+ assetID = *output.Source.Value.AssetId
+ case *bc.VoteOutput:
+ assetID = *output.Source.Value.AssetId
+ default:
+ return errors.Wrapf(bc.ErrEntryType, "entry %x has unexpected type %T", prevout.Bytes(), entryOutput)
+ }
+
+ if statusFail && assetID != *consensus.BTMAssetID {
continue
}
}
for _, id := range tx.TxHeader.ResultIds {
- output, err := tx.Output(*id)
+ assetID := bc.AssetID{}
+ entryOutput, err := tx.Entry(*id)
if err != nil {
- // error due to it's a retirement, utxo doesn't care this output type so skip it
continue
}
- if statusFail && *output.Source.Value.AssetId != *consensus.BTMAssetID {
+
+ switch output := entryOutput.(type) {
+ case *bc.IntraChainOutput:
+ assetID = *output.Source.Value.AssetId
+ case *bc.VoteOutput:
+ assetID = *output.Source.Value.AssetId
+ default:
+ // due to it's a retirement, utxo doesn't care this output type so skip it
+ continue
+ }
+
+ if statusFail && assetID != *consensus.BTMAssetID {
continue
}
func (view *UtxoViewpoint) DetachTransaction(tx *bc.Tx, statusFail bool) error {
for _, prevout := range tx.SpentOutputIDs {
- spentOutput, err := tx.Output(prevout)
+ assetID := bc.AssetID{}
+ entryOutput, err := tx.Entry(prevout)
if err != nil {
return err
}
- if statusFail && *spentOutput.Source.Value.AssetId != *consensus.BTMAssetID {
+
+ switch output := entryOutput.(type) {
+ case *bc.IntraChainOutput:
+ assetID = *output.Source.Value.AssetId
+ case *bc.VoteOutput:
+ assetID = *output.Source.Value.AssetId
+ default:
+ return errors.Wrapf(bc.ErrEntryType, "entry %x has unexpected type %T", prevout.Bytes(), entryOutput)
+ }
+
+ if statusFail && assetID != *consensus.BTMAssetID {
continue
}
}
for _, id := range tx.TxHeader.ResultIds {
- output, err := tx.Output(*id)
+ assetID := bc.AssetID{}
+ entryOutput, err := tx.Entry(*id)
if err != nil {
- // error due to it's a retirement, utxo doesn't care this output type so skip it
continue
}
- if statusFail && *output.Source.Value.AssetId != *consensus.BTMAssetID {
+
+ switch output := entryOutput.(type) {
+ case *bc.IntraChainOutput:
+ assetID = *output.Source.Value.AssetId
+ case *bc.VoteOutput:
+ assetID = *output.Source.Value.AssetId
+ default:
+ // due to it's a retirement, utxo doesn't care this output type so skip it
+ continue
+ }
+
+ if statusFail && assetID != *consensus.BTMAssetID {
continue
}
}
func (view *UtxoViewpoint) DetachBlock(block *bc.Block, txStatus *bc.TransactionStatus) error {
- for i, tx := range block.Transactions {
+ for i := len(block.Transactions) - 1; i >= 0; i-- {
statusFail, err := txStatus.GetStatus(i)
if err != nil {
return err
}
- if err := view.DetachTransaction(tx, statusFail); err != nil {
+ if err := view.DetachTransaction(block.Transactions[i], statusFail); err != nil {
return err
}
}