package alphabet import ( "crypto/elliptic" "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/morph/client/netmap" "github.com/nspcc-dev/neo-go/pkg/crypto/keys" "github.com/nspcc-dev/neo-go/pkg/encoding/fixedn" "go.uber.org/zap" ) const emitMethod = "emit" func (ap *Processor) processEmit() { index := ap.irList.AlphabetIndex() if index < 0 { ap.log.Info("non alphabet mode, ignore gas emission event") return } contract, ok := ap.alphabetContracts.GetByIndex(index) if !ok { ap.log.Debug("node is out of alphabet range, ignore gas emission event", zap.Int("index", index)) return } // there is no signature collecting, so we don't need extra fee err := ap.morphClient.Invoke(contract, 0, emitMethod) if err != nil { ap.log.Warn("can't invoke alphabet emit method", zap.String("error", err.Error())) return } if ap.storageEmission == 0 { ap.log.Info("storage node emission is off") return } networkMap, err := ap.netmapClient.NetMap() if err != nil { ap.log.Warn("can't get netmap snapshot to emit gas to storage nodes", zap.String("error", err.Error())) return } nmNodes := networkMap.Nodes() nmLen := len(nmNodes) extraLen := len(ap.parsedWallets) ap.log.Debug("gas emission", zap.Int("network_map", nmLen), zap.Int("extra_wallets", extraLen)) if nmLen+extraLen == 0 { return } gasPerNode := fixedn.Fixed8(ap.storageEmission / uint64(nmLen+extraLen)) ap.transferGasToNetmapNodes(nmNodes, gasPerNode) ap.transferGasToExtraNodes(extraLen, gasPerNode) } func (ap *Processor) transferGasToNetmapNodes(nmNodes []netmap.NodeInfo, gasPerNode fixedn.Fixed8) { for i := range nmNodes { keyBytes := nmNodes[i].PublicKey() key, err := keys.NewPublicKeyFromBytes(keyBytes, elliptic.P256()) if err != nil { ap.log.Warn("can't parse node public key", zap.String("error", err.Error())) continue } err = ap.morphClient.TransferGas(key.GetScriptHash(), gasPerNode) if err != nil { ap.log.Warn("can't transfer gas", zap.String("receiver", key.Address()), zap.Int64("amount", int64(gasPerNode)), zap.String("error", err.Error()), ) } } } func (ap *Processor) transferGasToExtraNodes(extraLen int, gasPerNode fixedn.Fixed8) { if extraLen != 0 { err := ap.morphClient.BatchTransferGas(ap.parsedWallets, gasPerNode) if err != nil { receiversLog := make([]string, extraLen) for i, addr := range ap.parsedWallets { receiversLog[i] = addr.StringLE() } ap.log.Warn("can't transfer gas to wallet", zap.Strings("receivers", receiversLog), zap.Int64("amount", int64(gasPerNode)), zap.String("error", err.Error()), ) } } }