package frostfs import ( "context" "testing" "time" "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/morph/client/balance" nmClient "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/morph/client/netmap" frostfsEvent "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/morph/event/frostfs" "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/util/logger/test" "github.com/nspcc-dev/neo-go/pkg/encoding/fixedn" "github.com/nspcc-dev/neo-go/pkg/util" "github.com/stretchr/testify/require" ) func TestHandleDeposit(t *testing.T) { t.Parallel() es := &testEpochState{ epochCounter: 100, } b := &testBalaceClient{} m := &testMorphClient{ balance: 150, } proc, err := newTestProc(t, func(p *Params) { p.EpochState = es p.BalanceClient = b p.MorphClient = m }) require.NoError(t, err, "failed to create processor") ev := frostfsEvent.Deposit{ IDValue: []byte{1, 2, 3, 4, 5}, FromValue: util.Uint160{100}, ToValue: util.Uint160{200}, AmountValue: 1000, } proc.handleDeposit(context.Background(), ev) for proc.pool.Running() > 0 { time.Sleep(10 * time.Millisecond) } var expMint balance.MintPrm expMint.SetAmount(ev.AmountValue) expMint.SetID(ev.IDValue) expMint.SetTo(ev.ToValue) require.EqualValues(t, []balance.MintPrm{expMint}, b.mint, "invalid mint value") require.EqualValues(t, []transferGas{ { receiver: ev.ToValue, amount: fixedn.Fixed8(50), }, }, m.transferGas, "invalid transfer gas") es.epochCounter = 109 proc.handleDeposit(context.Background(), ev) for proc.pool.Running() > 0 { time.Sleep(10 * time.Millisecond) } expMint.SetAmount(ev.AmountValue) expMint.SetID(ev.IDValue) expMint.SetTo(ev.ToValue) require.EqualValues(t, []balance.MintPrm{expMint, expMint}, b.mint, "invalid mint value") require.EqualValues(t, []transferGas{ { receiver: ev.ToValue, amount: fixedn.Fixed8(50), }, }, m.transferGas, "invalid transfer gas") } func TestHandleWithdraw(t *testing.T) { t.Parallel() es := &testEpochState{ epochCounter: 100, } b := &testBalaceClient{} m := &testMorphClient{ balance: 150, } proc, err := newTestProc(t, func(p *Params) { p.EpochState = es p.BalanceClient = b p.MorphClient = m }) require.NoError(t, err, "failed to create processor") ev := frostfsEvent.Withdraw{ IDValue: []byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20}, UserValue: util.Uint160{100}, AmountValue: 1000, } proc.handleWithdraw(context.Background(), ev) for proc.pool.Running() > 0 { time.Sleep(10 * time.Millisecond) } lock, err := util.Uint160DecodeBytesBE(ev.ID()[:util.Uint160Size]) require.NoError(t, err, "failed to decode ID") var expLock balance.LockPrm expLock.SetAmount(ev.AmountValue) expLock.SetID(ev.IDValue) expLock.SetDueEpoch(int64(es.epochCounter) + int64(lockAccountLifetime)) expLock.SetLock(lock) expLock.SetUser(ev.UserValue) require.EqualValues(t, []balance.LockPrm{expLock}, b.lock, "invalid lock value") } func TestHandleCheque(t *testing.T) { t.Parallel() es := &testEpochState{ epochCounter: 100, } b := &testBalaceClient{} m := &testMorphClient{ balance: 150, } proc, err := newTestProc(t, func(p *Params) { p.BalanceClient = b p.MorphClient = m p.EpochState = es }) require.NoError(t, err, "failed to create processor") ev := frostfsEvent.Cheque{ IDValue: []byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20}, UserValue: util.Uint160{100}, AmountValue: 1000, LockValue: util.Uint160{200}, } proc.handleCheque(context.Background(), ev) for proc.pool.Running() > 0 { time.Sleep(10 * time.Millisecond) } var expBurn balance.BurnPrm expBurn.SetAmount(ev.AmountValue) expBurn.SetID(ev.IDValue) expBurn.SetTo(util.Uint160{200}) require.EqualValues(t, []balance.BurnPrm{expBurn}, b.burn, "invalid burn value") } func TestHandleConfig(t *testing.T) { t.Parallel() es := &testEpochState{ epochCounter: 100, } nm := &testNetmapClient{} m := &testMorphClient{ balance: 150, } proc, err := newTestProc(t, func(p *Params) { p.NetmapClient = nm p.MorphClient = m p.EpochState = es }) require.NoError(t, err, "failed to create processor") ev := frostfsEvent.Config{ IDValue: []byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20}, KeyValue: []byte{1, 2, 3, 4, 5}, ValueValue: []byte{6, 7, 8, 9, 0}, TxHashValue: util.Uint256{100}, } proc.handleConfig(context.Background(), ev) for proc.pool.Running() > 0 { time.Sleep(10 * time.Millisecond) } var expConfig nmClient.SetConfigPrm expConfig.SetHash(ev.TxHashValue) expConfig.SetID(ev.IDValue) expConfig.SetKey(ev.KeyValue) expConfig.SetValue(ev.ValueValue) require.EqualValues(t, []nmClient.SetConfigPrm{expConfig}, nm.config, "invalid config value") } func newTestProc(t *testing.T, nonDefault func(p *Params)) (*Processor, error) { p := &Params{ Log: test.NewLogger(t), PoolSize: 1, FrostFSContract: util.Uint160{0}, BalanceClient: &testBalaceClient{}, NetmapClient: &testNetmapClient{}, MorphClient: &testMorphClient{}, EpochState: &testEpochState{}, AlphabetState: &testAlphabetState{isAlphabet: true}, Converter: &testPrecisionConverter{}, MintEmitCacheSize: 100, MintEmitThreshold: 10, MintEmitValue: fixedn.Fixed8(50), GasBalanceThreshold: 50, } nonDefault(p) return New(p) } type testEpochState struct { epochCounter uint64 } func (s *testEpochState) EpochCounter() uint64 { return s.epochCounter } type testAlphabetState struct { isAlphabet bool } func (s *testAlphabetState) IsAlphabet(context.Context) bool { return s.isAlphabet } type testPrecisionConverter struct{} func (c *testPrecisionConverter) ToBalancePrecision(v int64) int64 { return v } type testBalaceClient struct { mint []balance.MintPrm lock []balance.LockPrm burn []balance.BurnPrm } func (c *testBalaceClient) Mint(_ context.Context, p balance.MintPrm) error { c.mint = append(c.mint, p) return nil } func (c *testBalaceClient) Lock(_ context.Context, p balance.LockPrm) error { c.lock = append(c.lock, p) return nil } func (c *testBalaceClient) Burn(_ context.Context, p balance.BurnPrm) error { c.burn = append(c.burn, p) return nil } type testNetmapClient struct { config []nmClient.SetConfigPrm } func (c *testNetmapClient) SetConfig(_ context.Context, p nmClient.SetConfigPrm) error { c.config = append(c.config, p) return nil } type transferGas struct { receiver util.Uint160 amount fixedn.Fixed8 } type testMorphClient struct { balance int64 transferGas []transferGas } func (c *testMorphClient) GasBalance() (res int64, err error) { return c.balance, nil } func (c *testMorphClient) TransferGas(receiver util.Uint160, amount fixedn.Fixed8) error { c.transferGas = append(c.transferGas, transferGas{ receiver: receiver, amount: amount, }) return nil }