2023-04-26 09:05:33 +00:00
|
|
|
package container
|
|
|
|
|
|
|
|
import (
|
2024-10-21 09:21:01 +00:00
|
|
|
"context"
|
2023-04-26 09:05:33 +00:00
|
|
|
"crypto/ecdsa"
|
|
|
|
"encoding/hex"
|
|
|
|
"testing"
|
|
|
|
"time"
|
|
|
|
|
2023-11-20 14:03:19 +00:00
|
|
|
frostfsidclient "git.frostfs.info/TrueCloudLab/frostfs-contract/frostfsid/client"
|
2023-04-26 09:05:33 +00:00
|
|
|
containercore "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/core/container"
|
|
|
|
cntClient "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/morph/client/container"
|
|
|
|
containerEvent "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/morph/event/container"
|
|
|
|
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/util/logger/test"
|
|
|
|
apistatus "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/client/status"
|
|
|
|
containerSDK "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container"
|
|
|
|
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container/acl"
|
|
|
|
cid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container/id"
|
|
|
|
frostfscrypto "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/crypto"
|
|
|
|
frostfsecdsa "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/crypto/ecdsa"
|
|
|
|
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/netmap"
|
|
|
|
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/user"
|
2023-05-17 12:43:56 +00:00
|
|
|
"github.com/nspcc-dev/neo-go/pkg/core/transaction"
|
2023-04-26 09:05:33 +00:00
|
|
|
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
|
|
|
|
"github.com/nspcc-dev/neo-go/pkg/network/payload"
|
|
|
|
"github.com/nspcc-dev/neo-go/pkg/util"
|
|
|
|
"github.com/stretchr/testify/require"
|
|
|
|
)
|
|
|
|
|
|
|
|
func TestPutEvent(t *testing.T) {
|
|
|
|
t.Parallel()
|
|
|
|
nst := &testNetworkState{
|
|
|
|
homHashDisabled: true,
|
|
|
|
epoch: 100,
|
|
|
|
}
|
2023-05-17 12:43:56 +00:00
|
|
|
mc := &testMorphClient{}
|
2023-04-26 09:05:33 +00:00
|
|
|
|
|
|
|
proc, err := New(&Params{
|
2024-01-09 08:37:41 +00:00
|
|
|
Log: test.NewLogger(t),
|
2023-04-26 09:05:33 +00:00
|
|
|
PoolSize: 2,
|
|
|
|
AlphabetState: &testAlphabetState{isAlphabet: true},
|
|
|
|
NetworkState: nst,
|
2023-05-17 12:43:56 +00:00
|
|
|
ContainerClient: &testContainerClient{},
|
|
|
|
MorphClient: mc,
|
2023-11-20 14:03:19 +00:00
|
|
|
FrostFSIDClient: &testFrostFSIDClient{},
|
2023-04-26 09:05:33 +00:00
|
|
|
})
|
|
|
|
require.NoError(t, err, "failed to create processor")
|
|
|
|
|
|
|
|
p, err := keys.NewPrivateKey()
|
|
|
|
require.NoError(t, err)
|
|
|
|
var usr user.ID
|
|
|
|
user.IDFromKey(&usr, (ecdsa.PublicKey)(*p.PublicKey()))
|
|
|
|
|
|
|
|
var pp netmap.PlacementPolicy
|
|
|
|
pp.AddReplicas(netmap.ReplicaDescriptor{})
|
|
|
|
|
|
|
|
var cnr containerSDK.Container
|
|
|
|
cnr.Init()
|
|
|
|
cnr.SetOwner(usr)
|
|
|
|
cnr.SetPlacementPolicy(pp)
|
|
|
|
cnr.SetBasicACL(acl.Private)
|
|
|
|
containerSDK.DisableHomomorphicHashing(&cnr)
|
|
|
|
|
2023-05-17 12:43:56 +00:00
|
|
|
nr := &payload.P2PNotaryRequest{
|
|
|
|
MainTransaction: &transaction.Transaction{},
|
|
|
|
}
|
|
|
|
|
2023-04-26 09:05:33 +00:00
|
|
|
event := &testPutEvent{
|
|
|
|
cnr: &cnr,
|
|
|
|
pk: p,
|
|
|
|
st: nil,
|
2023-05-17 12:43:56 +00:00
|
|
|
nr: nr,
|
2023-04-26 09:05:33 +00:00
|
|
|
}
|
|
|
|
|
2024-10-21 09:21:01 +00:00
|
|
|
proc.handlePut(context.Background(), event)
|
2023-04-26 09:05:33 +00:00
|
|
|
|
|
|
|
for proc.pool.Running() > 0 {
|
|
|
|
time.Sleep(10 * time.Millisecond)
|
|
|
|
}
|
|
|
|
|
2023-05-17 12:43:56 +00:00
|
|
|
require.EqualValues(t, []*transaction.Transaction{nr.MainTransaction}, mc.transactions, "invalid notary requests")
|
2023-04-26 09:05:33 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func TestDeleteEvent(t *testing.T) {
|
|
|
|
t.Parallel()
|
|
|
|
nst := &testNetworkState{
|
|
|
|
homHashDisabled: true,
|
|
|
|
epoch: 100,
|
|
|
|
}
|
|
|
|
cc := &testContainerClient{
|
|
|
|
get: make(map[string]*containercore.Container),
|
|
|
|
}
|
|
|
|
|
|
|
|
p, err := keys.NewPrivateKey()
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
2023-05-17 12:43:56 +00:00
|
|
|
mc := &testMorphClient{}
|
2023-04-26 09:05:33 +00:00
|
|
|
|
|
|
|
proc, err := New(&Params{
|
2024-01-09 08:37:41 +00:00
|
|
|
Log: test.NewLogger(t),
|
2023-04-26 09:05:33 +00:00
|
|
|
PoolSize: 2,
|
|
|
|
AlphabetState: &testAlphabetState{isAlphabet: true},
|
|
|
|
NetworkState: nst,
|
|
|
|
ContainerClient: cc,
|
2023-05-17 12:43:56 +00:00
|
|
|
MorphClient: mc,
|
2023-11-20 14:03:19 +00:00
|
|
|
FrostFSIDClient: &testFrostFSIDClient{},
|
2023-04-26 09:05:33 +00:00
|
|
|
})
|
|
|
|
require.NoError(t, err, "failed to create processor")
|
|
|
|
|
|
|
|
var usr user.ID
|
|
|
|
user.IDFromKey(&usr, (ecdsa.PublicKey)(*p.PublicKey()))
|
|
|
|
|
|
|
|
var pp netmap.PlacementPolicy
|
|
|
|
pp.AddReplicas(netmap.ReplicaDescriptor{})
|
|
|
|
|
|
|
|
var cnr containerSDK.Container
|
|
|
|
cnr.Init()
|
|
|
|
cnr.SetOwner(usr)
|
|
|
|
cnr.SetPlacementPolicy(pp)
|
|
|
|
cnr.SetBasicACL(acl.Private)
|
|
|
|
containerSDK.DisableHomomorphicHashing(&cnr)
|
|
|
|
|
|
|
|
var cid cid.ID
|
|
|
|
containerSDK.CalculateID(&cid, cnr)
|
|
|
|
cidBin := make([]byte, 32)
|
|
|
|
cid.Encode(cidBin)
|
|
|
|
|
2023-05-17 12:43:56 +00:00
|
|
|
nr := &payload.P2PNotaryRequest{
|
|
|
|
MainTransaction: &transaction.Transaction{},
|
|
|
|
}
|
|
|
|
|
2023-04-26 09:05:33 +00:00
|
|
|
ev := containerEvent.Delete{
|
2023-05-17 12:43:56 +00:00
|
|
|
ContainerIDValue: cidBin,
|
|
|
|
SignatureValue: p.Sign(cidBin),
|
|
|
|
NotaryRequestValue: nr,
|
2023-11-20 11:32:26 +00:00
|
|
|
PublicKeyValue: p.PublicKey().Bytes(),
|
2023-04-26 09:05:33 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
var signature frostfscrypto.Signature
|
|
|
|
signer := frostfsecdsa.Signer(p.PrivateKey)
|
|
|
|
require.NoError(t, signature.Calculate(signer, ev.ContainerID()), "failed to calculate signature")
|
|
|
|
cc.get[hex.EncodeToString(ev.ContainerID())] = &containercore.Container{
|
|
|
|
Value: cnr,
|
|
|
|
Signature: signature,
|
|
|
|
}
|
|
|
|
|
2024-10-21 09:21:01 +00:00
|
|
|
proc.handleDelete(context.Background(), ev)
|
2023-04-26 09:05:33 +00:00
|
|
|
|
|
|
|
for proc.pool.Running() > 0 {
|
|
|
|
time.Sleep(10 * time.Millisecond)
|
|
|
|
}
|
|
|
|
|
|
|
|
var expectedDelete cntClient.DeletePrm
|
|
|
|
expectedDelete.SetCID(ev.ContainerID())
|
|
|
|
expectedDelete.SetSignature(ev.Signature())
|
|
|
|
|
2023-05-17 12:43:56 +00:00
|
|
|
require.EqualValues(t, []*transaction.Transaction{nr.MainTransaction}, mc.transactions, "invalid notary requests")
|
2023-04-26 09:05:33 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
type testAlphabetState struct {
|
|
|
|
isAlphabet bool
|
|
|
|
}
|
|
|
|
|
2024-10-21 13:27:28 +00:00
|
|
|
func (s *testAlphabetState) IsAlphabet(context.Context) bool {
|
2023-04-26 09:05:33 +00:00
|
|
|
return s.isAlphabet
|
|
|
|
}
|
|
|
|
|
|
|
|
type testNetworkState struct {
|
|
|
|
homHashDisabled bool
|
|
|
|
epoch uint64
|
|
|
|
}
|
|
|
|
|
|
|
|
func (s *testNetworkState) HomomorphicHashDisabled() (bool, error) {
|
|
|
|
return s.homHashDisabled, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (s *testNetworkState) Epoch() (uint64, error) {
|
|
|
|
return s.epoch, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
type testContainerClient struct {
|
|
|
|
contractAddress util.Uint160
|
|
|
|
get map[string]*containercore.Container
|
|
|
|
}
|
|
|
|
|
|
|
|
func (c *testContainerClient) ContractAddress() util.Uint160 {
|
|
|
|
return c.contractAddress
|
|
|
|
}
|
|
|
|
|
|
|
|
func (c *testContainerClient) Get(cid []byte) (*containercore.Container, error) {
|
|
|
|
key := hex.EncodeToString(cid)
|
|
|
|
if cont, found := c.get[key]; found {
|
|
|
|
return cont, nil
|
|
|
|
}
|
2023-08-04 11:14:07 +00:00
|
|
|
return nil, new(apistatus.ContainerNotFound)
|
2023-04-26 09:05:33 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
var _ putEvent = &testPutEvent{}
|
|
|
|
|
|
|
|
type testPutEvent struct {
|
|
|
|
cnr *containerSDK.Container
|
|
|
|
pk *keys.PrivateKey
|
|
|
|
st []byte
|
2023-05-17 12:43:56 +00:00
|
|
|
nr *payload.P2PNotaryRequest
|
2023-04-26 09:05:33 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func (e *testPutEvent) MorphEvent() {}
|
|
|
|
|
|
|
|
func (e *testPutEvent) Container() []byte {
|
|
|
|
return e.cnr.Marshal()
|
|
|
|
}
|
|
|
|
|
|
|
|
func (e *testPutEvent) PublicKey() []byte {
|
|
|
|
return e.pk.PublicKey().Bytes()
|
|
|
|
}
|
|
|
|
|
|
|
|
func (e *testPutEvent) Signature() []byte {
|
|
|
|
return e.pk.Sign(e.cnr.Marshal())
|
|
|
|
}
|
|
|
|
|
|
|
|
func (e *testPutEvent) SessionToken() []byte {
|
|
|
|
return e.st
|
|
|
|
}
|
2023-10-31 11:56:55 +00:00
|
|
|
|
2023-04-26 09:05:33 +00:00
|
|
|
func (e *testPutEvent) NotaryRequest() *payload.P2PNotaryRequest {
|
2023-05-17 12:43:56 +00:00
|
|
|
return e.nr
|
|
|
|
}
|
|
|
|
|
|
|
|
type testMorphClient struct {
|
|
|
|
transactions []*transaction.Transaction
|
|
|
|
}
|
|
|
|
|
|
|
|
func (c *testMorphClient) NotarySignAndInvokeTX(mainTx *transaction.Transaction) error {
|
|
|
|
c.transactions = append(c.transactions, mainTx)
|
2023-04-26 09:05:33 +00:00
|
|
|
return nil
|
|
|
|
}
|
2023-11-20 14:03:19 +00:00
|
|
|
|
|
|
|
type testFrostFSIDClient struct{}
|
|
|
|
|
|
|
|
func (c *testFrostFSIDClient) GetSubject(addr util.Uint160) (*frostfsidclient.Subject, error) {
|
2024-07-29 08:31:05 +00:00
|
|
|
return &frostfsidclient.Subject{}, nil
|
2023-11-20 14:03:19 +00:00
|
|
|
}
|