package frostfs import ( "testing" "time" "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/morph/client/balance" "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/morph/client/frostfsid" 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" "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/user" "github.com/nspcc-dev/neo-go/pkg/crypto/keys" "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(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(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(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(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(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 TestHandleUnbind(t *testing.T) { t.Parallel() es := &testEpochState{ epochCounter: 100, } m := &testMorphClient{ balance: 150, } id := &testIDClient{} proc, err := newTestProc(t, func(p *Params) { p.EpochState = es p.MorphClient = m p.FrostFSIDClient = id }) require.NoError(t, err, "failed to create processor") p, err := keys.NewPrivateKey() require.NoError(t, err) evUnbind := frostfsEvent.Unbind{ BindCommon: frostfsEvent.BindCommon{ UserValue: util.Uint160{49}.BytesBE(), KeysValue: [][]byte{ p.PublicKey().Bytes(), }, TxHashValue: util.Uint256{100}, }, } proc.handleUnbind(evUnbind) for proc.pool.Running() > 0 { time.Sleep(10 * time.Millisecond) } var userID user.ID userID.SetScriptHash(util.Uint160{49}) var expBind frostfsid.CommonBindPrm expBind.SetOwnerID(userID.WalletBytes()) expBind.SetKeys(evUnbind.BindCommon.KeysValue) expBind.SetHash(evUnbind.BindCommon.TxHashValue) var expNilSlice []frostfsid.CommonBindPrm require.EqualValues(t, []frostfsid.CommonBindPrm{expBind}, id.remove, "invalid remove keys value") require.EqualValues(t, expNilSlice, id.add, "invalid add keys value") evBind := frostfsEvent.Bind{ BindCommon: frostfsEvent.BindCommon{ UserValue: util.Uint160{49}.BytesBE(), KeysValue: [][]byte{ p.PublicKey().Bytes(), }, TxHashValue: util.Uint256{100}, }, } proc.handleBind(evBind) time.Sleep(time.Second) require.EqualValues(t, []frostfsid.CommonBindPrm{expBind}, id.remove, "invalid remove keys value") require.EqualValues(t, []frostfsid.CommonBindPrm{expBind}, id.add, "invalid add keys value") } func newTestProc(t *testing.T, nonDefault func(p *Params)) (*Processor, error) { p := &Params{ Log: test.NewLogger(t, true), PoolSize: 1, FrostFSContract: util.Uint160{0}, FrostFSIDClient: &testIDClient{}, 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() 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(p balance.MintPrm) error { c.mint = append(c.mint, p) return nil } func (c *testBalaceClient) Lock(p balance.LockPrm) error { c.lock = append(c.lock, p) return nil } func (c *testBalaceClient) Burn(p balance.BurnPrm) error { c.burn = append(c.burn, p) return nil } type testNetmapClient struct { config []nmClient.SetConfigPrm } func (c *testNetmapClient) SetConfig(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 } type testIDClient struct { add []frostfsid.CommonBindPrm remove []frostfsid.CommonBindPrm } func (c *testIDClient) AddKeys(p frostfsid.CommonBindPrm) error { c.add = append(c.add, p) return nil } func (c *testIDClient) RemoveKeys(args frostfsid.CommonBindPrm) error { c.remove = append(c.remove, args) return nil }