mirror of https://github.com/poanetwork/gecko.git
73 lines
1.8 KiB
Go
73 lines
1.8 KiB
Go
// (c) 2019-2020, Ava Labs, Inc. All rights reserved.
|
|
// See the file LICENSE for licensing terms.
|
|
|
|
package avm
|
|
|
|
import (
|
|
"bytes"
|
|
"errors"
|
|
"sort"
|
|
|
|
"github.com/ava-labs/gecko/utils"
|
|
"github.com/ava-labs/gecko/vms/components/ava"
|
|
"github.com/ava-labs/gecko/vms/components/codec"
|
|
"github.com/ava-labs/gecko/vms/components/verify"
|
|
)
|
|
|
|
var (
|
|
errNilOperation = errors.New("nil operation is not valid")
|
|
errNilFxOperation = errors.New("nil fx operation is not valid")
|
|
errNotSortedAndUniqueUTXOIDs = errors.New("utxo IDs not sorted and unique")
|
|
)
|
|
|
|
// Operation ...
|
|
type Operation struct {
|
|
ava.Asset `serialize:"true"`
|
|
|
|
UTXOIDs []*ava.UTXOID `serialize:"true" json:"inputIDs"`
|
|
Op FxOperation `serialize:"true" json:"operation"`
|
|
}
|
|
|
|
// Verify implements the verify.Verifiable interface
|
|
func (op *Operation) Verify(c codec.Codec) error {
|
|
switch {
|
|
case op == nil:
|
|
return errNilOperation
|
|
case op.Op == nil:
|
|
return errNilFxOperation
|
|
case !ava.IsSortedAndUniqueUTXOIDs(op.UTXOIDs):
|
|
return errNotSortedAndUniqueUTXOIDs
|
|
default:
|
|
return verify.All(&op.Asset, op.Op)
|
|
}
|
|
}
|
|
|
|
type innerSortOperation struct {
|
|
ops []*Operation
|
|
codec codec.Codec
|
|
}
|
|
|
|
func (ops *innerSortOperation) Less(i, j int) bool {
|
|
iOp := ops.ops[i]
|
|
jOp := ops.ops[j]
|
|
|
|
iBytes, err := ops.codec.Marshal(iOp)
|
|
if err != nil {
|
|
return false
|
|
}
|
|
jBytes, err := ops.codec.Marshal(jOp)
|
|
if err != nil {
|
|
return false
|
|
}
|
|
return bytes.Compare(iBytes, jBytes) == -1
|
|
}
|
|
func (ops *innerSortOperation) Len() int { return len(ops.ops) }
|
|
func (ops *innerSortOperation) Swap(i, j int) { o := ops.ops; o[j], o[i] = o[i], o[j] }
|
|
|
|
func sortOperations(ops []*Operation, c codec.Codec) {
|
|
sort.Sort(&innerSortOperation{ops: ops, codec: c})
|
|
}
|
|
func isSortedAndUniqueOperations(ops []*Operation, c codec.Codec) bool {
|
|
return utils.IsSortedAndUnique(&innerSortOperation{ops: ops, codec: c})
|
|
}
|