mirror of https://github.com/poanetwork/gecko.git
117 lines
3.1 KiB
Go
117 lines
3.1 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/codec"
|
|
"github.com/ava-labs/gecko/vms/components/verify"
|
|
)
|
|
|
|
var (
|
|
errNilOperableOutput = errors.New("nil operable output is not valid")
|
|
errNilOperableFxOutput = errors.New("nil operable feature extension output is not valid")
|
|
|
|
errNilOperableInput = errors.New("nil operable input is not valid")
|
|
errNilOperableFxInput = errors.New("nil operable feature extension input is not valid")
|
|
)
|
|
|
|
// OperableOutput ...
|
|
type OperableOutput struct {
|
|
Out verify.Verifiable `serialize:"true"`
|
|
}
|
|
|
|
// Output returns the feature extension output that this Output is using.
|
|
func (out *OperableOutput) Output() verify.Verifiable { return out.Out }
|
|
|
|
// Verify implements the verify.Verifiable interface
|
|
func (out *OperableOutput) Verify() error {
|
|
switch {
|
|
case out == nil:
|
|
return errNilOperableOutput
|
|
case out.Out == nil:
|
|
return errNilOperableFxOutput
|
|
default:
|
|
return out.Out.Verify()
|
|
}
|
|
}
|
|
|
|
type innerSortOperableOutputs struct {
|
|
outs []*OperableOutput
|
|
codec codec.Codec
|
|
}
|
|
|
|
func (outs *innerSortOperableOutputs) Less(i, j int) bool {
|
|
iOut := outs.outs[i]
|
|
jOut := outs.outs[j]
|
|
|
|
iBytes, err := outs.codec.Marshal(&iOut.Out)
|
|
if err != nil {
|
|
return false
|
|
}
|
|
jBytes, err := outs.codec.Marshal(&jOut.Out)
|
|
if err != nil {
|
|
return false
|
|
}
|
|
return bytes.Compare(iBytes, jBytes) == -1
|
|
}
|
|
func (outs *innerSortOperableOutputs) Len() int { return len(outs.outs) }
|
|
func (outs *innerSortOperableOutputs) Swap(i, j int) { o := outs.outs; o[j], o[i] = o[i], o[j] }
|
|
|
|
func sortOperableOutputs(outs []*OperableOutput, c codec.Codec) {
|
|
sort.Sort(&innerSortOperableOutputs{outs: outs, codec: c})
|
|
}
|
|
func isSortedOperableOutputs(outs []*OperableOutput, c codec.Codec) bool {
|
|
return sort.IsSorted(&innerSortOperableOutputs{outs: outs, codec: c})
|
|
}
|
|
|
|
// OperableInput ...
|
|
type OperableInput struct {
|
|
UTXOID `serialize:"true"`
|
|
|
|
In verify.Verifiable `serialize:"true"`
|
|
}
|
|
|
|
// Input returns the feature extension input that this Input is using.
|
|
func (in *OperableInput) Input() verify.Verifiable { return in.In }
|
|
|
|
// Verify implements the verify.Verifiable interface
|
|
func (in *OperableInput) Verify() error {
|
|
switch {
|
|
case in == nil:
|
|
return errNilOperableInput
|
|
case in.In == nil:
|
|
return errNilOperableFxInput
|
|
default:
|
|
return verify.All(&in.UTXOID, in.In)
|
|
}
|
|
}
|
|
|
|
type innerSortOperableInputs []*OperableInput
|
|
|
|
func (ins innerSortOperableInputs) Less(i, j int) bool {
|
|
iID, iIndex := ins[i].InputSource()
|
|
jID, jIndex := ins[j].InputSource()
|
|
|
|
switch bytes.Compare(iID.Bytes(), jID.Bytes()) {
|
|
case -1:
|
|
return true
|
|
case 0:
|
|
return iIndex < jIndex
|
|
default:
|
|
return false
|
|
}
|
|
}
|
|
func (ins innerSortOperableInputs) Len() int { return len(ins) }
|
|
func (ins innerSortOperableInputs) Swap(i, j int) { ins[j], ins[i] = ins[i], ins[j] }
|
|
|
|
func sortOperableInputs(ins []*OperableInput) { sort.Sort(innerSortOperableInputs(ins)) }
|
|
func isSortedAndUniqueOperableInputs(ins []*OperableInput) bool {
|
|
return utils.IsSortedAndUnique(innerSortOperableInputs(ins))
|
|
}
|