diff --git a/pkg/morph/event/reputation/put.go b/pkg/morph/event/reputation/put.go index ebfa3f945..fbc8f8ffb 100644 --- a/pkg/morph/event/reputation/put.go +++ b/pkg/morph/event/reputation/put.go @@ -3,6 +3,7 @@ package reputation import ( "fmt" + "github.com/nspcc-dev/neo-go/pkg/network/payload" "github.com/nspcc-dev/neo-go/pkg/vm/stackitem" "github.com/nspcc-dev/neofs-api-go/pkg/reputation" "github.com/nspcc-dev/neofs-node/pkg/morph/client" @@ -15,6 +16,10 @@ type Put struct { epoch uint64 peerID reputation.PeerID value reputation.GlobalTrust + + // For notary notifications only. + // Contains raw transactions of notary request. + notaryRequest *payload.P2PNotaryRequest } const peerIDLength = 33 // compressed public key @@ -37,6 +42,12 @@ func (p Put) Value() reputation.GlobalTrust { return p.value } +// NotaryRequest returns raw notary request if notification +// was received via notary service. Otherwise, returns nil. +func (p Put) NotaryRequest() *payload.P2PNotaryRequest { + return p.notaryRequest +} + // ParsePut from notification into reputation event structure. func ParsePut(prms []stackitem.Item) (event.Event, error) { var ( diff --git a/pkg/morph/event/reputation/put_notary.go b/pkg/morph/event/reputation/put_notary.go new file mode 100644 index 000000000..c06c92dae --- /dev/null +++ b/pkg/morph/event/reputation/put_notary.go @@ -0,0 +1,76 @@ +package reputation + +import ( + "fmt" + + "github.com/nspcc-dev/neofs-node/pkg/morph/event" +) + +func (p *Put) setEpoch(v uint64) { + p.epoch = v +} + +func (p *Put) setPeerID(v []byte) error { + if ln := len(v); ln != peerIDLength { + return fmt.Errorf("peer ID is %d byte long, expected %d", ln, peerIDLength) + } + + var publicKey [33]byte + copy(publicKey[:], v) + p.peerID.SetPublicKey(publicKey) + + return nil +} + +func (p *Put) setValue(v []byte) error { + return p.value.Unmarshal(v) +} + +var fieldSetters = []func(*Put, []byte) error{ + // order on stack is reversed + (*Put).setValue, + (*Put).setPeerID, +} + +const ( + // PutNotaryEvent is method name for reputation put operations + // in `Reputation` contract. Is used as identifier for notary + // put reputation requests. + PutNotaryEvent = "put" +) + +// ParsePutNotary from NotaryEvent into reputation event structure. +func ParsePutNotary(ne event.NotaryEvent) (event.Event, error) { + var ev Put + + fieldNum := 0 + + for _, op := range ne.Params() { + switch fieldNum { + case 0, 1: + data, err := event.BytesFromOpcode(op) + if err != nil { + return nil, err + } + + err = fieldSetters[fieldNum](&ev, data) + if err != nil { + return nil, fmt.Errorf("can't parse field num %d: %w", fieldNum, err) + } + case 2: + n, err := event.IntFromOpcode(op) + if err != nil { + return nil, err + } + + ev.setEpoch(uint64(n)) + default: + return nil, event.UnexpectedArgNumErr(PutNotaryEvent) + } + fieldNum++ + } + + ev.notaryRequest = ne.Raw() + + return ev, nil +}