frostfs-node/pkg/innerring/processors/alphabet/handlers_test.go
Dmitrii Stepanov e89fa7f69f [#280] ir: Add alphabet processor unit tests
Signed-off-by: Dmitrii Stepanov <d.stepanov@yadro.com>
2023-05-02 08:48:07 +00:00

282 lines
7.5 KiB
Go

package alphabet_test
import (
"testing"
"time"
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/innerring"
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/innerring/processors/alphabet"
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/innerring/timers"
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/util/logger/test"
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/netmap"
"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 TestProcessorEmitsGasToNetmapAndAlphabet(t *testing.T) {
t.Parallel()
var emission uint64 = 100_000
var index int = 5
var parsedWallets []util.Uint160 = []util.Uint160{{20}, {25}}
alphabetContracts := innerring.NewAlphabetContracts()
for i := 0; i <= index; i++ {
alphabetContracts[innerring.GlagoliticLetter(i)] = util.Uint160{uint8(i)}
}
morphClient := &testMorphClient{}
var node1 netmap.NodeInfo
key1, err := keys.NewPublicKeyFromString("038c862959e56b43e20f79187c4fe9e0bc7c8c66c1603e6cf0ec7f87ab6b08dc35")
require.NoError(t, err, "failed to parse key1")
node1.SetPublicKey(key1.Bytes())
var node2 netmap.NodeInfo
key2, err := keys.NewPublicKeyFromString("02ac920cd7df0b61b289072e6b946e2da4e1a31b9ab1c621bb475e30fa4ab102c3")
require.NoError(t, err, "failed to parse key2")
node2.SetPublicKey(key2.Bytes())
nodes := []netmap.NodeInfo{node1, node2}
network := &netmap.NetMap{}
network.SetNodes(nodes)
netmapClient := &testNetmapClient{
netmap: network,
}
params := &alphabet.Params{
ParsedWallets: parsedWallets,
Log: test.NewLogger(t, true),
PoolSize: 2,
StorageEmission: emission,
IRList: &testIndexer{index: index},
AlphabetContracts: alphabetContracts,
MorphClient: morphClient,
NetmapClient: netmapClient,
}
processor, err := alphabet.New(params)
require.NoError(t, err, "failed to create processor instance")
processor.HandleGasEmission(timers.NewAlphabetEmitTick{})
processor.WaitPoolRunning()
require.EqualValues(t, []invokedMethod{
{
contract: alphabetContracts[innerring.GlagoliticLetter(index)],
fee: 0,
method: "emit",
},
}, morphClient.invokedMethods, "invalid invoked morph methods")
require.EqualValues(t, []transferGas{
{
receiver: key1.GetScriptHash(),
amount: fixedn.Fixed8(25_000),
},
{
receiver: key2.GetScriptHash(),
amount: fixedn.Fixed8(25_000),
},
}, morphClient.transferedGas, "invalid transfered Gas")
require.EqualValues(t, []batchTransferGas{
{
receivers: parsedWallets,
amount: fixedn.Fixed8(25_000),
},
}, morphClient.batchTransferedGas, "invalid batch transfered Gas")
}
func TestProcessorEmitsGasToNetmapIfNoParsedWallets(t *testing.T) {
t.Parallel()
var emission uint64 = 100_000
var index int = 5
var parsedWallets []util.Uint160 = []util.Uint160{}
alphabetContracts := innerring.NewAlphabetContracts()
for i := 0; i <= index; i++ {
alphabetContracts[innerring.GlagoliticLetter(i)] = util.Uint160{uint8(i)}
}
morphClient := &testMorphClient{}
var node1 netmap.NodeInfo
key1, err := keys.NewPublicKeyFromString("038c862959e56b43e20f79187c4fe9e0bc7c8c66c1603e6cf0ec7f87ab6b08dc35")
require.NoError(t, err, "failed to parse key1")
node1.SetPublicKey(key1.Bytes())
var node2 netmap.NodeInfo
key2, err := keys.NewPublicKeyFromString("02ac920cd7df0b61b289072e6b946e2da4e1a31b9ab1c621bb475e30fa4ab102c3")
require.NoError(t, err, "failed to parse key2")
node2.SetPublicKey(key2.Bytes())
nodes := []netmap.NodeInfo{node1, node2}
network := &netmap.NetMap{}
network.SetNodes(nodes)
netmapClient := &testNetmapClient{
netmap: network,
}
params := &alphabet.Params{
ParsedWallets: parsedWallets,
Log: test.NewLogger(t, true),
PoolSize: 2,
StorageEmission: emission,
IRList: &testIndexer{index: index},
AlphabetContracts: alphabetContracts,
MorphClient: morphClient,
NetmapClient: netmapClient,
}
processor, err := alphabet.New(params)
require.NoError(t, err, "failed to create processor instance")
processor.HandleGasEmission(timers.NewAlphabetEmitTick{})
time.Sleep(time.Second)
require.EqualValues(t, []invokedMethod{
{
contract: alphabetContracts[innerring.GlagoliticLetter(index)],
fee: 0,
method: "emit",
},
}, morphClient.invokedMethods, "invalid invoked morph methods")
require.EqualValues(t, []transferGas{
{
receiver: key1.GetScriptHash(),
amount: fixedn.Fixed8(50_000),
},
{
receiver: key2.GetScriptHash(),
amount: fixedn.Fixed8(50_000),
},
}, morphClient.transferedGas, "invalid transfered Gas")
require.Equal(t, 0, len(morphClient.batchTransferedGas), "invalid batch transfered Gas")
}
func TestProcessorDoesntEmitGasIfNoNetmapOrParsedWallets(t *testing.T) {
t.Parallel()
var emission uint64 = 100_000
var index int = 5
var parsedWallets []util.Uint160 = []util.Uint160{}
alphabetContracts := innerring.NewAlphabetContracts()
for i := 0; i <= index; i++ {
alphabetContracts[innerring.GlagoliticLetter(i)] = util.Uint160{uint8(i)}
}
morphClient := &testMorphClient{}
nodes := []netmap.NodeInfo{}
network := &netmap.NetMap{}
network.SetNodes(nodes)
netmapClient := &testNetmapClient{
netmap: network,
}
params := &alphabet.Params{
ParsedWallets: parsedWallets,
Log: test.NewLogger(t, true),
PoolSize: 2,
StorageEmission: emission,
IRList: &testIndexer{index: index},
AlphabetContracts: alphabetContracts,
MorphClient: morphClient,
NetmapClient: netmapClient,
}
processor, err := alphabet.New(params)
require.NoError(t, err, "failed to create processor instance")
processor.HandleGasEmission(timers.NewAlphabetEmitTick{})
time.Sleep(time.Second)
require.EqualValues(t, []invokedMethod{
{
contract: alphabetContracts[innerring.GlagoliticLetter(index)],
fee: 0,
method: "emit",
},
}, morphClient.invokedMethods, "invalid invoked morph methods")
require.Equal(t, 0, len(morphClient.transferedGas), "invalid transfered Gas")
require.Equal(t, 0, len(morphClient.batchTransferedGas), "invalid batch transfered Gas")
}
type testIndexer struct {
index int
}
func (i *testIndexer) AlphabetIndex() int {
return i.index
}
type invokedMethod struct {
contract util.Uint160
fee fixedn.Fixed8
method string
args []any
}
type transferGas struct {
receiver util.Uint160
amount fixedn.Fixed8
}
type batchTransferGas struct {
receivers []util.Uint160
amount fixedn.Fixed8
}
type testMorphClient struct {
invokedMethods []invokedMethod
transferedGas []transferGas
batchTransferedGas []batchTransferGas
}
func (c *testMorphClient) Invoke(contract util.Uint160, fee fixedn.Fixed8, method string, args ...any) error {
c.invokedMethods = append(c.invokedMethods,
invokedMethod{
contract: contract,
fee: fee,
method: method,
args: args,
})
return nil
}
func (c *testMorphClient) TransferGas(receiver util.Uint160, amount fixedn.Fixed8) error {
c.transferedGas = append(c.transferedGas, transferGas{
receiver: receiver,
amount: amount,
})
return nil
}
func (c *testMorphClient) BatchTransferGas(receivers []util.Uint160, amount fixedn.Fixed8) error {
c.batchTransferedGas = append(c.batchTransferedGas, batchTransferGas{
receivers: receivers,
amount: amount,
})
return nil
}
type testNetmapClient struct {
netmap *netmap.NetMap
}
func (c *testNetmapClient) NetMap() (*netmap.NetMap, error) {
return c.netmap, nil
}