github.com/nspcc-dev/neo-go@v0.105.2-0.20240517133400-6be757af3eba/pkg/core/transaction/witness_rule.go (about)

     1  package transaction
     2  
     3  import (
     4  	"encoding/json"
     5  	"errors"
     6  	"math/big"
     7  
     8  	"github.com/nspcc-dev/neo-go/pkg/io"
     9  	"github.com/nspcc-dev/neo-go/pkg/vm/stackitem"
    10  )
    11  
    12  //go:generate stringer -type=WitnessAction -linecomment
    13  
    14  // WitnessAction represents an action to perform in WitnessRule if
    15  // WitnessCondition matches.
    16  type WitnessAction byte
    17  
    18  const (
    19  	// WitnessDeny rejects current witness if condition is met.
    20  	WitnessDeny WitnessAction = 0 // Deny
    21  	// WitnessAllow approves current witness if condition is met.
    22  	WitnessAllow WitnessAction = 1 // Allow
    23  )
    24  
    25  // WitnessRule represents a single rule for Rules witness scope.
    26  type WitnessRule struct {
    27  	Action    WitnessAction    `json:"action"`
    28  	Condition WitnessCondition `json:"condition"`
    29  }
    30  
    31  type witnessRuleAux struct {
    32  	Action    string          `json:"action"`
    33  	Condition json.RawMessage `json:"condition"`
    34  }
    35  
    36  // EncodeBinary implements the Serializable interface.
    37  func (w *WitnessRule) EncodeBinary(bw *io.BinWriter) {
    38  	bw.WriteB(byte(w.Action))
    39  	w.Condition.EncodeBinary(bw)
    40  }
    41  
    42  // DecodeBinary implements the Serializable interface.
    43  func (w *WitnessRule) DecodeBinary(br *io.BinReader) {
    44  	w.Action = WitnessAction(br.ReadB())
    45  	if br.Err == nil && w.Action != WitnessDeny && w.Action != WitnessAllow {
    46  		br.Err = errors.New("unknown witness rule action")
    47  		return
    48  	}
    49  	w.Condition = DecodeBinaryCondition(br)
    50  }
    51  
    52  // UnmarshalJSON implements the json.Unmarshaler interface.
    53  func (w *WitnessRule) MarshalJSON() ([]byte, error) {
    54  	cond, err := w.Condition.MarshalJSON()
    55  	if err != nil {
    56  		return nil, err
    57  	}
    58  	aux := &witnessRuleAux{
    59  		Action:    w.Action.String(),
    60  		Condition: cond,
    61  	}
    62  	return json.Marshal(aux)
    63  }
    64  
    65  // UnmarshalJSON implements the json.Unmarshaler interface.
    66  func (w *WitnessRule) UnmarshalJSON(data []byte) error {
    67  	aux := &witnessRuleAux{}
    68  	err := json.Unmarshal(data, aux)
    69  	if err != nil {
    70  		return err
    71  	}
    72  	var action WitnessAction
    73  	switch aux.Action {
    74  	case WitnessDeny.String():
    75  		action = WitnessDeny
    76  	case WitnessAllow.String():
    77  		action = WitnessAllow
    78  	default:
    79  		return errors.New("unknown witness rule action")
    80  	}
    81  	cond, err := UnmarshalConditionJSON(aux.Condition)
    82  	if err != nil {
    83  		return err
    84  	}
    85  	w.Action = action
    86  	w.Condition = cond
    87  	return nil
    88  }
    89  
    90  // ToStackItem implements Convertible interface.
    91  func (w *WitnessRule) ToStackItem() stackitem.Item {
    92  	return stackitem.NewArray([]stackitem.Item{
    93  		stackitem.NewBigInteger(big.NewInt(int64(w.Action))),
    94  		w.Condition.ToStackItem(),
    95  	})
    96  }
    97  
    98  // Copy creates a deep copy of the WitnessRule.
    99  func (w *WitnessRule) Copy() *WitnessRule {
   100  	return &WitnessRule{
   101  		Action:    w.Action,
   102  		Condition: w.Condition.Copy(),
   103  	}
   104  }