neo-go/pkg/core/transaction/witness_rule.go
Roman Khimov 9875799893 transaction: add new Rules witness scope
See neo-project/neo#2622. The implementation is somewhat asymmetric (and not
very efficient) for binary/JSON encoding/decoding, but it should be
sufficient.
2021-11-12 15:29:28 +03:00

86 lines
2.1 KiB
Go

package transaction
import (
"encoding/json"
"errors"
"github.com/nspcc-dev/neo-go/pkg/io"
)
//go:generate stringer -type=WitnessAction -linecomment
// WitnessAction represents an action to perform in WitnessRule if
// WitnessCondition matches.
type WitnessAction byte
const (
// WitnessDeny rejects current witness if condition is met.
WitnessDeny WitnessAction = 0 // Deny
// WitnessAllow approves current witness if condition is met.
WitnessAllow WitnessAction = 1 // Allow
)
// WitnessRule represents a single rule for Rules witness scope.
type WitnessRule struct {
Action WitnessAction `json:"action"`
Condition WitnessCondition `json:"condition"`
}
type witnessRuleAux struct {
Action string `json:"action"`
Condition json.RawMessage `json:"condition"`
}
// EncodeBinary implements Serializable interface.
func (w *WitnessRule) EncodeBinary(bw *io.BinWriter) {
bw.WriteB(byte(w.Action))
w.Condition.EncodeBinary(bw)
}
// DecodeBinary implements Serializable interface.
func (w *WitnessRule) DecodeBinary(br *io.BinReader) {
w.Action = WitnessAction(br.ReadB())
if br.Err == nil && w.Action != WitnessDeny && w.Action != WitnessAllow {
br.Err = errors.New("unknown witness rule action")
return
}
w.Condition = DecodeBinaryCondition(br)
}
// UnmarshalJSON implements json.Unmarshaler interface.
func (w *WitnessRule) MarshalJSON() ([]byte, error) {
cond, err := w.Condition.MarshalJSON()
if err != nil {
return nil, err
}
aux := &witnessRuleAux{
Action: w.Action.String(),
Condition: cond,
}
return json.Marshal(aux)
}
// UnmarshalJSON implements json.Unmarshaler interface.
func (w *WitnessRule) UnmarshalJSON(data []byte) error {
aux := &witnessRuleAux{}
err := json.Unmarshal(data, aux)
if err != nil {
return err
}
var action WitnessAction
switch aux.Action {
case WitnessDeny.String():
action = WitnessDeny
case WitnessAllow.String():
action = WitnessAllow
default:
return errors.New("unknown witness rule action")
}
cond, err := UnmarshalConditionJSON(aux.Condition)
if err != nil {
return err
}
w.Action = action
w.Condition = cond
return nil
}