frostfs-node/pkg/innerring/processors/neofs/process_bind.go
Leonard Lyubich ed80f704d0 [#556] innerring/neofs: Process Bind/Unbind events
Make IR processor of NeoFS contract to handle `Bind`/`Unbind` notification
events. The processor verifies the format of wallet script hash and public
keys, and call NeoFS ID client wrapper in order to approve adding/removing
keys from NeoFS account.

Signed-off-by: Leonard Lyubich <leonard@nspcc.ru>
2021-06-02 10:50:44 +03:00

110 lines
2 KiB
Go

package neofs
import (
"crypto/elliptic"
"fmt"
"github.com/mr-tron/base58"
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
"github.com/nspcc-dev/neo-go/pkg/encoding/address"
"github.com/nspcc-dev/neo-go/pkg/util"
"github.com/nspcc-dev/neofs-node/pkg/morph/event/neofs"
"go.uber.org/zap"
)
type bindCommon interface {
User() []byte
Keys() [][]byte
}
func (np *Processor) processBind(e bindCommon) {
if !np.alphabetState.IsAlphabet() {
np.log.Info("non alphabet mode, ignore bind")
return
}
c := &bindCommonContext{
bindCommon: e,
}
_, c.bind = e.(neofs.Bind)
err := np.checkBindCommon(c)
if err != nil {
np.log.Error("invalid manage key event",
zap.Bool("bind", c.bind),
zap.String("error", err.Error()),
)
return
}
np.approveBindCommon(c)
}
type bindCommonContext struct {
bindCommon
bind bool
scriptHash util.Uint160
}
func (np *Processor) checkBindCommon(e *bindCommonContext) error {
var err error
e.scriptHash, err = util.Uint160DecodeBytesBE(e.User())
if err != nil {
return err
}
curve := elliptic.P256()
for _, key := range e.Keys() {
_, err = keys.NewPublicKeyFromBytes(key, curve)
if err != nil {
return err
}
}
return nil
}
func (np *Processor) approveBindCommon(e *bindCommonContext) {
// calculate wallet address
// TODO: implement some utilities in API Go lib to do it
scriptHash := e.User()
u160, err := util.Uint160DecodeBytesBE(scriptHash)
if err != nil {
np.log.Error("could not decode script hash from bytes",
zap.String("error", err.Error()),
)
return
}
wallet, err := base58.Decode(address.Uint160ToString(u160))
if err != nil {
np.log.Error("could not decode wallet address",
zap.String("error", err.Error()),
)
return
}
err = np.neofsIDClient.ManageKeys(wallet, e.Keys(), e.bind)
if err != nil {
var typ string
if e.bind {
typ = "bind"
} else {
typ = "unbind"
}
np.log.Error(fmt.Sprintf("could not approve %s", typ),
zap.String("error", err.Error()),
)
}
}