frostfs-node/pkg/innerring/processors/neofs/process_assets.go

125 lines
3.6 KiB
Go
Raw Normal View History

2020-07-24 13:54:03 +00:00
package neofs
import (
"github.com/nspcc-dev/neo-go/pkg/util"
neofsEvent "github.com/nspcc-dev/neofs-node/pkg/morph/event/neofs"
"go.uber.org/zap"
)
const (
// lockAccountLifeTime defines amount of epochs when lock account is valid.
lockAccountLifetime uint64 = 20
burnMethod = "burn"
lockMethod = "lock"
mintMethod = "mint"
2020-07-24 13:54:03 +00:00
)
// Process deposit event by invoking balance contract and sending native
// gas in morph chain.
func (np *Processor) processDeposit(deposit *neofsEvent.Deposit) {
if !np.alphabetState.IsAlphabet() {
np.log.Info("non alphabet mode, ignore deposit")
2020-07-24 13:54:03 +00:00
return
}
// send transferX to balance contract
err := np.morphClient.NotaryInvoke(np.balanceContract, np.feeProvider.SideChainFee(), mintMethod,
deposit.To().BytesBE(),
np.converter.ToBalancePrecision(deposit.Amount()),
deposit.ID())
2020-07-24 13:54:03 +00:00
if err != nil {
np.log.Error("can't transfer assets to balance contract", zap.Error(err))
}
curEpoch := np.epochState.EpochCounter()
receiver := deposit.To()
// check if receiver already received some mint GAS emissions
// we should lock there even though LRU cache is already thread save
// we lock there because GAS transfer AND cache update must be atomic
np.mintEmitLock.Lock()
defer np.mintEmitLock.Unlock()
val, ok := np.mintEmitCache.Get(receiver.String())
if ok && val.(uint64)+np.mintEmitThreshold >= curEpoch {
np.log.Warn("double mint emission declined",
zap.String("receiver", receiver.String()),
zap.Uint64("last_emission", val.(uint64)),
zap.Uint64("current_epoch", curEpoch))
return
}
// get gas balance of the node
// before gas transfer check if the balance is greater than threshold
balance, err := np.morphClient.GasBalance()
if err != nil {
np.log.Error("can't get gas balance of the node", zap.Error(err))
return
}
if balance < np.gasBalanceThreshold {
np.log.Warn("gas balance threshold has been reached",
zap.Int64("balance", balance),
zap.Int64("threshold", np.gasBalanceThreshold))
return
}
err = np.morphClient.TransferGas(receiver, np.mintEmitValue)
2020-07-24 13:54:03 +00:00
if err != nil {
np.log.Error("can't transfer native gas to receiver",
zap.String("error", err.Error()))
return
2020-07-24 13:54:03 +00:00
}
np.mintEmitCache.Add(receiver.String(), curEpoch)
2020-07-24 13:54:03 +00:00
}
// Process withdraw event by locking assets in balance account.
func (np *Processor) processWithdraw(withdraw *neofsEvent.Withdraw) {
if !np.alphabetState.IsAlphabet() {
np.log.Info("non alphabet mode, ignore withdraw")
2020-07-24 13:54:03 +00:00
return
}
// create lock account
// fixme: check collision there, consider reversed script hash
2020-07-24 13:54:03 +00:00
lock, err := util.Uint160DecodeBytesBE(withdraw.ID()[:util.Uint160Size])
if err != nil {
np.log.Error("can't create lock account", zap.Error(err))
return
}
curEpoch := np.epochState.EpochCounter()
err = np.morphClient.NotaryInvoke(np.balanceContract, np.feeProvider.SideChainFee(), lockMethod,
withdraw.ID(),
withdraw.User(),
lock,
np.converter.ToBalancePrecision(withdraw.Amount()),
int64(curEpoch+lockAccountLifetime))
2020-07-24 13:54:03 +00:00
if err != nil {
np.log.Error("can't lock assets for withdraw", zap.Error(err))
}
}
// Process cheque event by transferring assets from lock account back to
// reserve account.
func (np *Processor) processCheque(cheque *neofsEvent.Cheque) {
if !np.alphabetState.IsAlphabet() {
np.log.Info("non alphabet mode, ignore cheque")
2020-07-24 13:54:03 +00:00
return
}
err := np.morphClient.NotaryInvoke(np.balanceContract, np.feeProvider.SideChainFee(), burnMethod,
cheque.LockAccount().BytesBE(),
np.converter.ToBalancePrecision(cheque.Amount()),
cheque.ID())
2020-07-24 13:54:03 +00:00
if err != nil {
np.log.Error("can't transfer assets to fed contract", zap.Error(err))
}
}