gecko/vms/avm/operation.go

73 lines
1.8 KiB
Go
Raw Normal View History

2020-03-10 12:20:34 -07:00
// (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"
2020-03-23 13:40:37 -07:00
"github.com/ava-labs/gecko/vms/components/ava"
2020-03-10 12:20:34 -07:00
"github.com/ava-labs/gecko/vms/components/codec"
2020-03-19 15:36:10 -07:00
"github.com/ava-labs/gecko/vms/components/verify"
2020-03-10 12:20:34 -07:00
)
var (
2020-03-29 22:08:45 -07:00
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")
2020-03-10 12:20:34 -07:00
)
// Operation ...
type Operation struct {
2020-03-23 13:40:37 -07:00
ava.Asset `serialize:"true"`
2020-03-10 12:20:34 -07:00
2020-03-29 22:08:45 -07:00
UTXOIDs []*ava.UTXOID `serialize:"true" json:"inputIDs"`
Op FxOperation `serialize:"true" json:"operation"`
2020-03-10 12:20:34 -07:00
}
// Verify implements the verify.Verifiable interface
func (op *Operation) Verify(c codec.Codec) error {
switch {
case op == nil:
return errNilOperation
2020-03-29 22:08:45 -07:00
case op.Op == nil:
return errNilFxOperation
case !ava.IsSortedAndUniqueUTXOIDs(op.UTXOIDs):
return errNotSortedAndUniqueUTXOIDs
default:
return verify.All(&op.Asset, op.Op)
2020-03-10 12:20:34 -07:00
}
}
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})
}