Compare commits
6 commits
master
...
fix/drop-n
Author | SHA1 | Date | |
---|---|---|---|
1af9cd3667 | |||
8289f0d991 | |||
aaaa02c64a | |||
441ab3549c | |||
6cd3d916d0 | |||
997dd04677 |
26 changed files with 309 additions and 731 deletions
|
@ -37,11 +37,6 @@ const (
|
||||||
dumpBalancesAlphabetFlag = "alphabet"
|
dumpBalancesAlphabetFlag = "alphabet"
|
||||||
dumpBalancesProxyFlag = "proxy"
|
dumpBalancesProxyFlag = "proxy"
|
||||||
dumpBalancesUseScriptHashFlag = "script-hash"
|
dumpBalancesUseScriptHashFlag = "script-hash"
|
||||||
|
|
||||||
// notaryEnabled signifies whether contracts were deployed in a notary-enabled environment.
|
|
||||||
// The setting is here to simplify testing and building the command for testnet (notary currently disabled).
|
|
||||||
// It will be removed eventually.
|
|
||||||
notaryEnabled = true
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func dumpBalances(cmd *cobra.Command, _ []string) error {
|
func dumpBalances(cmd *cobra.Command, _ []string) error {
|
||||||
|
@ -60,7 +55,7 @@ func dumpBalances(cmd *cobra.Command, _ []string) error {
|
||||||
|
|
||||||
inv := invoker.New(c, nil)
|
inv := invoker.New(c, nil)
|
||||||
|
|
||||||
if !notaryEnabled || dumpStorage || dumpAlphabet || dumpProxy {
|
if dumpStorage || dumpAlphabet || dumpProxy {
|
||||||
nnsCs, err = c.GetContractStateByID(1)
|
nnsCs, err = c.GetContractStateByID(1)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("can't get NNS contract info: %w", err)
|
return fmt.Errorf("can't get NNS contract info: %w", err)
|
||||||
|
@ -72,7 +67,7 @@ func dumpBalances(cmd *cobra.Command, _ []string) error {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
irList, err := fetchIRNodes(c, nmHash, rolemgmt.Hash)
|
irList, err := fetchIRNodes(c, rolemgmt.Hash)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -187,40 +182,22 @@ func printAlphabetContractBalances(cmd *cobra.Command, c Client, inv *invoker.In
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func fetchIRNodes(c Client, nmHash, desigHash util.Uint160) ([]accBalancePair, error) {
|
func fetchIRNodes(c Client, desigHash util.Uint160) ([]accBalancePair, error) {
|
||||||
var irList []accBalancePair
|
|
||||||
|
|
||||||
inv := invoker.New(c, nil)
|
inv := invoker.New(c, nil)
|
||||||
|
|
||||||
if notaryEnabled {
|
height, err := c.GetBlockCount()
|
||||||
height, err := c.GetBlockCount()
|
if err != nil {
|
||||||
if err != nil {
|
return nil, fmt.Errorf("can't get block height: %w", err)
|
||||||
return nil, fmt.Errorf("can't get block height: %w", err)
|
}
|
||||||
}
|
|
||||||
|
|
||||||
arr, err := getDesignatedByRole(inv, desigHash, noderoles.NeoFSAlphabet, height)
|
arr, err := getDesignatedByRole(inv, desigHash, noderoles.NeoFSAlphabet, height)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.New("can't fetch list of IR nodes from the netmap contract")
|
return nil, errors.New("can't fetch list of IR nodes from the netmap contract")
|
||||||
}
|
}
|
||||||
|
|
||||||
irList = make([]accBalancePair, len(arr))
|
irList := make([]accBalancePair, len(arr))
|
||||||
for i := range arr {
|
for i := range arr {
|
||||||
irList[i].scriptHash = arr[i].GetScriptHash()
|
irList[i].scriptHash = arr[i].GetScriptHash()
|
||||||
}
|
|
||||||
} else {
|
|
||||||
arr, err := unwrap.ArrayOfBytes(inv.Call(nmHash, "innerRingList"))
|
|
||||||
if err != nil {
|
|
||||||
return nil, errors.New("can't fetch list of IR nodes from the netmap contract")
|
|
||||||
}
|
|
||||||
|
|
||||||
irList = make([]accBalancePair, len(arr))
|
|
||||||
for i := range arr {
|
|
||||||
pub, err := keys.NewPublicKeyFromBytes(arr[i], elliptic.P256())
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("can't parse IR node public key: %w", err)
|
|
||||||
}
|
|
||||||
irList[i].scriptHash = pub.GetScriptHash()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return irList, nil
|
return irList, nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -51,9 +51,8 @@ func setControlDefaults(cfg *viper.Viper) {
|
||||||
|
|
||||||
func setFeeDefaults(cfg *viper.Viper) {
|
func setFeeDefaults(cfg *viper.Viper) {
|
||||||
// extra fee values for working mode without notary contract
|
// extra fee values for working mode without notary contract
|
||||||
cfg.SetDefault("fee.main_chain", 5000_0000) // 0.5 Fixed8
|
cfg.SetDefault("fee.main_chain", 5000_0000) // 0.5 Fixed8
|
||||||
cfg.SetDefault("fee.side_chain", 2_0000_0000) // 2.0 Fixed8
|
cfg.SetDefault("fee.side_chain", 2_0000_0000) // 2.0 Fixed8
|
||||||
cfg.SetDefault("fee.named_container_register", 25_0000_0000) // 25.0 Fixed8
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func setEmitDefaults(cfg *viper.Viper) {
|
func setEmitDefaults(cfg *viper.Viper) {
|
||||||
|
|
|
@ -28,7 +28,6 @@ FROSTFS_IR_LOCODE_DB_PATH=/path/to/locode.db
|
||||||
|
|
||||||
FROSTFS_IR_FEE_MAIN_CHAIN=50000000
|
FROSTFS_IR_FEE_MAIN_CHAIN=50000000
|
||||||
FROSTFS_IR_FEE_SIDE_CHAIN=200000000
|
FROSTFS_IR_FEE_SIDE_CHAIN=200000000
|
||||||
FROSTFS_IR_FEE_NAMED_CONTAINER_REGISTER=2500000000
|
|
||||||
|
|
||||||
FROSTFS_IR_TIMERS_EMIT=240
|
FROSTFS_IR_TIMERS_EMIT=240
|
||||||
FROSTFS_IR_TIMERS_STOP_ESTIMATION_MUL=1
|
FROSTFS_IR_TIMERS_STOP_ESTIMATION_MUL=1
|
||||||
|
|
|
@ -49,7 +49,6 @@ locode:
|
||||||
fee:
|
fee:
|
||||||
main_chain: 50000000 # Fixed8 value of extra GAS fee for mainchain contract invocation; ignore if notary is enabled in mainchain
|
main_chain: 50000000 # Fixed8 value of extra GAS fee for mainchain contract invocation; ignore if notary is enabled in mainchain
|
||||||
side_chain: 200000000 # Fixed8 value of extra GAS fee for sidechain contract invocation; ignore if notary is enabled in sidechain
|
side_chain: 200000000 # Fixed8 value of extra GAS fee for sidechain contract invocation; ignore if notary is enabled in sidechain
|
||||||
named_container_register: 2500000000 # Fixed8 value of extra GAS fee for named conatiner registration in container contract; ignore if notary is enabled in sidechain
|
|
||||||
|
|
||||||
timers:
|
timers:
|
||||||
emit: 240 # Number of sidechain blocks between GAS emission cycles; disabled by default
|
emit: 240 # Number of sidechain blocks between GAS emission cycles; disabled by default
|
||||||
|
|
|
@ -8,19 +8,15 @@ import (
|
||||||
// FeeConfig is an instance that returns extra fee values for contract
|
// FeeConfig is an instance that returns extra fee values for contract
|
||||||
// invocations without notary support.
|
// invocations without notary support.
|
||||||
type FeeConfig struct {
|
type FeeConfig struct {
|
||||||
registerNamedCnr,
|
|
||||||
mainchain,
|
mainchain,
|
||||||
sidechain fixedn.Fixed8
|
sidechain fixedn.Fixed8
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewFeeConfig constructs FeeConfig from viper.Viper instance. Latter must not be nil.
|
// NewFeeConfig constructs FeeConfig from viper.Viper instance. Latter must not be nil.
|
||||||
//
|
|
||||||
// Fee for named container registration is taken from "fee.named_container_register" value.
|
|
||||||
func NewFeeConfig(v *viper.Viper) *FeeConfig {
|
func NewFeeConfig(v *viper.Viper) *FeeConfig {
|
||||||
return &FeeConfig{
|
return &FeeConfig{
|
||||||
registerNamedCnr: fixedn.Fixed8(v.GetInt64("fee.named_container_register")),
|
mainchain: fixedn.Fixed8(v.GetInt64("fee.main_chain")),
|
||||||
mainchain: fixedn.Fixed8(v.GetInt64("fee.main_chain")),
|
sidechain: fixedn.Fixed8(v.GetInt64("fee.side_chain")),
|
||||||
sidechain: fixedn.Fixed8(v.GetInt64("fee.side_chain")),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -31,8 +27,3 @@ func (f FeeConfig) MainChainFee() fixedn.Fixed8 {
|
||||||
func (f FeeConfig) SideChainFee() fixedn.Fixed8 {
|
func (f FeeConfig) SideChainFee() fixedn.Fixed8 {
|
||||||
return f.sidechain
|
return f.sidechain
|
||||||
}
|
}
|
||||||
|
|
||||||
// NamedContainerRegistrationFee returns additional GAS fee for named container registration in FrostFS network.
|
|
||||||
func (f FeeConfig) NamedContainerRegistrationFee() fixedn.Fixed8 {
|
|
||||||
return f.registerNamedCnr
|
|
||||||
}
|
|
||||||
|
|
|
@ -18,7 +18,6 @@ func TestConfig(t *testing.T) {
|
||||||
fee:
|
fee:
|
||||||
main_chain: 50000000
|
main_chain: 50000000
|
||||||
side_chain: 200000000
|
side_chain: 200000000
|
||||||
named_container_register: 2500000000
|
|
||||||
`,
|
`,
|
||||||
)
|
)
|
||||||
v := viper.New()
|
v := viper.New()
|
||||||
|
@ -29,7 +28,6 @@ fee:
|
||||||
config := NewFeeConfig(v)
|
config := NewFeeConfig(v)
|
||||||
require.Equal(t, fixedn.Fixed8(50000000), config.MainChainFee(), "main chain fee invalid")
|
require.Equal(t, fixedn.Fixed8(50000000), config.MainChainFee(), "main chain fee invalid")
|
||||||
require.Equal(t, fixedn.Fixed8(200000000), config.SideChainFee(), "side chain fee invalid")
|
require.Equal(t, fixedn.Fixed8(200000000), config.SideChainFee(), "side chain fee invalid")
|
||||||
require.Equal(t, fixedn.Fixed8(2500000000), config.NamedContainerRegistrationFee(), "named container register fee invalid")
|
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("nothing set", func(t *testing.T) {
|
t.Run("nothing set", func(t *testing.T) {
|
||||||
|
@ -43,7 +41,6 @@ fee:
|
||||||
config := NewFeeConfig(v)
|
config := NewFeeConfig(v)
|
||||||
require.Equal(t, fixedn.Fixed8(0), config.MainChainFee(), "main chain fee invalid")
|
require.Equal(t, fixedn.Fixed8(0), config.MainChainFee(), "main chain fee invalid")
|
||||||
require.Equal(t, fixedn.Fixed8(0), config.SideChainFee(), "side chain fee invalid")
|
require.Equal(t, fixedn.Fixed8(0), config.SideChainFee(), "side chain fee invalid")
|
||||||
require.Equal(t, fixedn.Fixed8(0), config.NamedContainerRegistrationFee(), "named container register fee invalid")
|
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("partially set", func(t *testing.T) {
|
t.Run("partially set", func(t *testing.T) {
|
||||||
|
@ -62,7 +59,6 @@ fee:
|
||||||
config := NewFeeConfig(v)
|
config := NewFeeConfig(v)
|
||||||
require.Equal(t, fixedn.Fixed8(10), config.MainChainFee(), "main chain fee invalid")
|
require.Equal(t, fixedn.Fixed8(10), config.MainChainFee(), "main chain fee invalid")
|
||||||
require.Equal(t, fixedn.Fixed8(0), config.SideChainFee(), "side chain fee invalid")
|
require.Equal(t, fixedn.Fixed8(0), config.SideChainFee(), "side chain fee invalid")
|
||||||
require.Equal(t, fixedn.Fixed8(0), config.NamedContainerRegistrationFee(), "named container register fee invalid")
|
|
||||||
})
|
})
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,7 +22,7 @@ type contracts struct {
|
||||||
alphabet AlphabetContracts // in morph
|
alphabet AlphabetContracts // in morph
|
||||||
}
|
}
|
||||||
|
|
||||||
func parseContracts(cfg *viper.Viper, morph nnsResolver, withoutMainNet, withoutMainNotary, withoutSideNotary bool) (*contracts, error) {
|
func parseContracts(cfg *viper.Viper, morph nnsResolver, withoutMainNet, withoutMainNotary bool) (*contracts, error) {
|
||||||
var (
|
var (
|
||||||
result = new(contracts)
|
result = new(contracts)
|
||||||
err error
|
err error
|
||||||
|
@ -42,11 +42,9 @@ func parseContracts(cfg *viper.Viper, morph nnsResolver, withoutMainNet, without
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if !withoutSideNotary {
|
result.proxy, err = parseContract(cfg, morph, "contracts.proxy", client.NNSProxyContractName)
|
||||||
result.proxy, err = parseContract(cfg, morph, "contracts.proxy", client.NNSProxyContractName)
|
if err != nil {
|
||||||
if err != nil {
|
return nil, fmt.Errorf("can't get proxy script hash: %w", err)
|
||||||
return nil, fmt.Errorf("can't get proxy script hash: %w", err)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
targets := [...]struct {
|
targets := [...]struct {
|
||||||
|
|
|
@ -35,7 +35,7 @@ contracts:
|
||||||
|
|
||||||
t.Run("all enabled", func(t *testing.T) {
|
t.Run("all enabled", func(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
c, err := parseContracts(v, nil, false, false, false)
|
c, err := parseContracts(v, nil, false, false)
|
||||||
require.NoError(t, err, "failed to parse contracts")
|
require.NoError(t, err, "failed to parse contracts")
|
||||||
|
|
||||||
frostfsExp, _ := util.Uint160DecodeStringLE("ee3dee6d05dc79c24a5b8f6985e10d68b7cacc62")
|
frostfsExp, _ := util.Uint160DecodeStringLE("ee3dee6d05dc79c24a5b8f6985e10d68b7cacc62")
|
||||||
|
@ -70,7 +70,7 @@ contracts:
|
||||||
|
|
||||||
t.Run("all disabled", func(t *testing.T) {
|
t.Run("all disabled", func(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
c, err := parseContracts(v, nil, true, true, true)
|
c, err := parseContracts(v, nil, true, true)
|
||||||
require.NoError(t, err, "failed to parse contracts")
|
require.NoError(t, err, "failed to parse contracts")
|
||||||
|
|
||||||
require.Equal(t, util.Uint160{}, c.frostfs, "invalid frostfs")
|
require.Equal(t, util.Uint160{}, c.frostfs, "invalid frostfs")
|
||||||
|
@ -89,7 +89,8 @@ contracts:
|
||||||
netmapIDExp, _ := util.Uint160DecodeStringLE("83c600c81d47a1b1b7cf58eb49ae7ee7240dc742")
|
netmapIDExp, _ := util.Uint160DecodeStringLE("83c600c81d47a1b1b7cf58eb49ae7ee7240dc742")
|
||||||
require.Equal(t, netmapIDExp, c.netmap, "invalid netmap")
|
require.Equal(t, netmapIDExp, c.netmap, "invalid netmap")
|
||||||
|
|
||||||
require.Equal(t, util.Uint160{}, c.proxy, "invalid proxy")
|
proxyExp, _ := util.Uint160DecodeStringLE("abc8794bb40a21f2db5f21ae62741eb46c8cad1c")
|
||||||
|
require.Equal(t, proxyExp, c.proxy, "invalid proxy")
|
||||||
|
|
||||||
require.Equal(t, 2, len(c.alphabet), "invalid alphabet contracts length")
|
require.Equal(t, 2, len(c.alphabet), "invalid alphabet contracts length")
|
||||||
|
|
||||||
|
@ -100,9 +101,9 @@ contracts:
|
||||||
require.Equal(t, bukyExp, c.alphabet[buky], "invalid buky")
|
require.Equal(t, bukyExp, c.alphabet[buky], "invalid buky")
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("main notary & side notary disabled", func(t *testing.T) {
|
t.Run("main notary disabled", func(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
c, err := parseContracts(v, nil, false, true, true)
|
c, err := parseContracts(v, nil, false, true)
|
||||||
require.NoError(t, err, "failed to parse contracts")
|
require.NoError(t, err, "failed to parse contracts")
|
||||||
|
|
||||||
frostfsExp, _ := util.Uint160DecodeStringLE("ee3dee6d05dc79c24a5b8f6985e10d68b7cacc62")
|
frostfsExp, _ := util.Uint160DecodeStringLE("ee3dee6d05dc79c24a5b8f6985e10d68b7cacc62")
|
||||||
|
@ -122,7 +123,8 @@ contracts:
|
||||||
netmapIDExp, _ := util.Uint160DecodeStringLE("83c600c81d47a1b1b7cf58eb49ae7ee7240dc742")
|
netmapIDExp, _ := util.Uint160DecodeStringLE("83c600c81d47a1b1b7cf58eb49ae7ee7240dc742")
|
||||||
require.Equal(t, netmapIDExp, c.netmap, "invalid netmap")
|
require.Equal(t, netmapIDExp, c.netmap, "invalid netmap")
|
||||||
|
|
||||||
require.Equal(t, util.Uint160{}, c.proxy, "invalid proxy")
|
proxyExp, _ := util.Uint160DecodeStringLE("abc8794bb40a21f2db5f21ae62741eb46c8cad1c")
|
||||||
|
require.Equal(t, proxyExp, c.proxy, "invalid proxy")
|
||||||
|
|
||||||
require.Equal(t, 2, len(c.alphabet), "invalid alphabet contracts length")
|
require.Equal(t, 2, len(c.alphabet), "invalid alphabet contracts length")
|
||||||
|
|
||||||
|
@ -159,7 +161,7 @@ contracts:
|
||||||
err := v.ReadConfig(file)
|
err := v.ReadConfig(file)
|
||||||
require.NoError(t, err, "read config file failed")
|
require.NoError(t, err, "read config file failed")
|
||||||
|
|
||||||
_, err = parseContracts(v, nil, false, false, false)
|
_, err = parseContracts(v, nil, false, false)
|
||||||
require.Error(t, err, "unexpected success")
|
require.Error(t, err, "unexpected success")
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -196,7 +198,7 @@ contracts:
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err = parseContracts(v, morph, false, false, false)
|
_, err = parseContracts(v, morph, false, false)
|
||||||
require.ErrorContains(t, err, "could not read all contracts: required 3, read 2", "unexpected success")
|
require.ErrorContains(t, err, "could not read all contracts: required 3, read 2", "unexpected success")
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -71,7 +71,6 @@ func (s *Server) initNetmapProcessor(cfg *viper.Viper,
|
||||||
addrvalidator.New(),
|
addrvalidator.New(),
|
||||||
locodeValidator,
|
locodeValidator,
|
||||||
),
|
),
|
||||||
NotaryDisabled: s.sideNotaryConfig.disabled,
|
|
||||||
|
|
||||||
NodeStateSettings: netSettings,
|
NodeStateSettings: netSettings,
|
||||||
})
|
})
|
||||||
|
@ -117,18 +116,16 @@ func (s *Server) initMainnet(ctx context.Context, cfg *viper.Viper, morphChain *
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Server) enableNotarySupport() error {
|
func (s *Server) enableNotarySupport() error {
|
||||||
if !s.sideNotaryConfig.disabled {
|
// enable notary support in the side client
|
||||||
// enable notary support in the side client
|
err := s.morphClient.EnableNotarySupport(
|
||||||
err := s.morphClient.EnableNotarySupport(
|
client.WithProxyContract(s.contracts.proxy),
|
||||||
client.WithProxyContract(s.contracts.proxy),
|
)
|
||||||
)
|
if err != nil {
|
||||||
if err != nil {
|
return fmt.Errorf("could not enable side chain notary support: %w", err)
|
||||||
return fmt.Errorf("could not enable side chain notary support: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
s.morphListener.EnableNotarySupport(s.contracts.proxy, s.morphClient.Committee, s.morphClient)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
s.morphListener.EnableNotarySupport(s.contracts.proxy, s.morphClient.Committee, s.morphClient)
|
||||||
|
|
||||||
if !s.mainNotaryConfig.disabled {
|
if !s.mainNotaryConfig.disabled {
|
||||||
// enable notary support in the main client
|
// enable notary support in the main client
|
||||||
err := s.mainnetClient.EnableNotarySupport(
|
err := s.mainnetClient.EnableNotarySupport(
|
||||||
|
@ -144,13 +141,12 @@ func (s *Server) enableNotarySupport() error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Server) initNotaryConfig() {
|
func (s *Server) initNotaryConfig() {
|
||||||
s.mainNotaryConfig, s.sideNotaryConfig = notaryConfigs(
|
s.mainNotaryConfig = notaryConfigs(
|
||||||
s.morphClient.ProbeNotary(),
|
|
||||||
!s.withoutMainNet && s.mainnetClient.ProbeNotary(), // if mainnet disabled then notary flag must be disabled too
|
!s.withoutMainNet && s.mainnetClient.ProbeNotary(), // if mainnet disabled then notary flag must be disabled too
|
||||||
)
|
)
|
||||||
|
|
||||||
s.log.Info(logs.InnerringNotarySupport,
|
s.log.Info(logs.InnerringNotarySupport,
|
||||||
zap.Bool("sidechain_enabled", !s.sideNotaryConfig.disabled),
|
zap.Bool("sidechain_enabled", true),
|
||||||
zap.Bool("mainchain_enabled", !s.mainNotaryConfig.disabled),
|
zap.Bool("mainchain_enabled", !s.mainNotaryConfig.disabled),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -165,16 +161,15 @@ func (s *Server) createAlphaSync(cfg *viper.Viper, frostfsCli *frostfsClient.Cli
|
||||||
} else {
|
} else {
|
||||||
// create governance processor
|
// create governance processor
|
||||||
governanceProcessor, err := governance.New(&governance.Params{
|
governanceProcessor, err := governance.New(&governance.Params{
|
||||||
Log: s.log,
|
Log: s.log,
|
||||||
FrostFSClient: frostfsCli,
|
FrostFSClient: frostfsCli,
|
||||||
NetmapClient: s.netmapClient,
|
NetmapClient: s.netmapClient,
|
||||||
AlphabetState: s,
|
AlphabetState: s,
|
||||||
EpochState: s,
|
EpochState: s,
|
||||||
Voter: s,
|
Voter: s,
|
||||||
IRFetcher: irf,
|
IRFetcher: irf,
|
||||||
MorphClient: s.morphClient,
|
MorphClient: s.morphClient,
|
||||||
MainnetClient: s.mainnetClient,
|
MainnetClient: s.mainnetClient,
|
||||||
NotaryDisabled: s.sideNotaryConfig.disabled,
|
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -263,9 +258,9 @@ func (s *Server) initContainerProcessor(cfg *viper.Viper, cnrClient *container.C
|
||||||
PoolSize: cfg.GetInt("workers.container"),
|
PoolSize: cfg.GetInt("workers.container"),
|
||||||
AlphabetState: s,
|
AlphabetState: s,
|
||||||
ContainerClient: cnrClient,
|
ContainerClient: cnrClient,
|
||||||
|
MorphClient: cnrClient.Morph(),
|
||||||
FrostFSIDClient: frostfsIDClient,
|
FrostFSIDClient: frostfsIDClient,
|
||||||
NetworkState: s.netmapClient,
|
NetworkState: s.netmapClient,
|
||||||
NotaryDisabled: s.sideNotaryConfig.disabled,
|
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -388,14 +383,6 @@ func (s *Server) initClientsFromMorph() (*serverMorphClients, error) {
|
||||||
container.AsAlphabet(),
|
container.AsAlphabet(),
|
||||||
)
|
)
|
||||||
|
|
||||||
if s.sideNotaryConfig.disabled {
|
|
||||||
// in non-notary environments we customize fee for named container registration
|
|
||||||
// because it takes much more additional GAS than other operations.
|
|
||||||
morphCnrOpts = append(morphCnrOpts,
|
|
||||||
container.WithCustomFeeForNamedPut(s.feeConfig.NamedContainerRegistrationFee()),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
result.CnrClient, err = container.NewFromMorph(s.morphClient, s.contracts.container, fee, morphCnrOpts...)
|
result.CnrClient, err = container.NewFromMorph(s.morphClient, s.contracts.container, fee, morphCnrOpts...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -509,7 +496,6 @@ func (s *Server) initContracts(cfg *viper.Viper) error {
|
||||||
s.morphClient,
|
s.morphClient,
|
||||||
s.withoutMainNet,
|
s.withoutMainNet,
|
||||||
s.mainNotaryConfig.disabled,
|
s.mainNotaryConfig.disabled,
|
||||||
s.sideNotaryConfig.disabled,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
return err
|
return err
|
||||||
|
|
|
@ -63,7 +63,6 @@ type (
|
||||||
// notary configuration
|
// notary configuration
|
||||||
feeConfig *config.FeeConfig
|
feeConfig *config.FeeConfig
|
||||||
mainNotaryConfig *notaryConfig
|
mainNotaryConfig *notaryConfig
|
||||||
sideNotaryConfig *notaryConfig
|
|
||||||
|
|
||||||
// internal variables
|
// internal variables
|
||||||
key *keys.PrivateKey
|
key *keys.PrivateKey
|
||||||
|
@ -267,14 +266,11 @@ func (s *Server) initMainNotary(ctx context.Context) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Server) initSideNotary(ctx context.Context) error {
|
func (s *Server) initSideNotary(ctx context.Context) error {
|
||||||
if !s.sideNotaryConfig.disabled {
|
return s.initNotary(ctx,
|
||||||
return s.initNotary(ctx,
|
s.depositSideNotary,
|
||||||
s.depositSideNotary,
|
s.awaitSideNotaryDeposit,
|
||||||
s.awaitSideNotaryDeposit,
|
"waiting to accept side notary deposit",
|
||||||
"waiting to accept side notary deposit",
|
)
|
||||||
)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Server) tickInitialExpoch() {
|
func (s *Server) tickInitialExpoch() {
|
||||||
|
|
|
@ -57,11 +57,8 @@ func (s *Server) notaryHandler(_ event.Event) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if !s.sideNotaryConfig.disabled {
|
if _, err := s.depositSideNotary(); err != nil {
|
||||||
_, err := s.depositSideNotary()
|
s.log.Error(logs.InnerringCantMakeNotaryDepositInSideChain, zap.Error(err))
|
||||||
if err != nil {
|
|
||||||
s.log.Error(logs.InnerringCantMakeNotaryDepositInSideChain, zap.Error(err))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -115,16 +112,8 @@ func awaitNotaryDepositInClient(ctx context.Context, cli *client.Client, txHash
|
||||||
return errDepositTimeout
|
return errDepositTimeout
|
||||||
}
|
}
|
||||||
|
|
||||||
func notaryConfigs(withSideNotary, withMainNotary bool) (main, side *notaryConfig) {
|
func notaryConfigs(withMainNotary bool) (main *notaryConfig) {
|
||||||
main = new(notaryConfig)
|
main = new(notaryConfig)
|
||||||
side = new(notaryConfig)
|
|
||||||
|
|
||||||
if !withSideNotary {
|
|
||||||
main.disabled = true
|
|
||||||
side.disabled = true
|
|
||||||
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
main.disabled = !withMainNotary
|
main.disabled = !withMainNotary
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,6 @@ import (
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
containercore "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/core/container"
|
containercore "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/core/container"
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/morph/client"
|
|
||||||
cntClient "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/morph/client/container"
|
cntClient "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/morph/client/container"
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/morph/client/frostfsid"
|
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/morph/client/frostfsid"
|
||||||
containerEvent "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/morph/event/container"
|
containerEvent "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/morph/event/container"
|
||||||
|
@ -22,6 +21,7 @@ import (
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/netmap"
|
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/netmap"
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/user"
|
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/user"
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/version"
|
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/version"
|
||||||
|
"github.com/nspcc-dev/neo-go/pkg/core/transaction"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
|
"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/network/payload"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/util"
|
"github.com/nspcc-dev/neo-go/pkg/util"
|
||||||
|
@ -34,18 +34,16 @@ func TestPutEvent(t *testing.T) {
|
||||||
homHashDisabled: true,
|
homHashDisabled: true,
|
||||||
epoch: 100,
|
epoch: 100,
|
||||||
}
|
}
|
||||||
cc := &testContainerClient{
|
mc := &testMorphClient{}
|
||||||
get: make(map[string]*containercore.Container),
|
|
||||||
}
|
|
||||||
|
|
||||||
proc, err := New(&Params{
|
proc, err := New(&Params{
|
||||||
Log: test.NewLogger(t, true),
|
Log: test.NewLogger(t, true),
|
||||||
PoolSize: 2,
|
PoolSize: 2,
|
||||||
AlphabetState: &testAlphabetState{isAlphabet: true},
|
AlphabetState: &testAlphabetState{isAlphabet: true},
|
||||||
FrostFSIDClient: &testIDClient{},
|
FrostFSIDClient: &testIDClient{},
|
||||||
NotaryDisabled: true,
|
|
||||||
NetworkState: nst,
|
NetworkState: nst,
|
||||||
ContainerClient: cc,
|
ContainerClient: &testContainerClient{},
|
||||||
|
MorphClient: mc,
|
||||||
})
|
})
|
||||||
require.NoError(t, err, "failed to create processor")
|
require.NoError(t, err, "failed to create processor")
|
||||||
|
|
||||||
|
@ -64,10 +62,15 @@ func TestPutEvent(t *testing.T) {
|
||||||
cnr.SetBasicACL(acl.Private)
|
cnr.SetBasicACL(acl.Private)
|
||||||
containerSDK.DisableHomomorphicHashing(&cnr)
|
containerSDK.DisableHomomorphicHashing(&cnr)
|
||||||
|
|
||||||
|
nr := &payload.P2PNotaryRequest{
|
||||||
|
MainTransaction: &transaction.Transaction{},
|
||||||
|
}
|
||||||
|
|
||||||
event := &testPutEvent{
|
event := &testPutEvent{
|
||||||
cnr: &cnr,
|
cnr: &cnr,
|
||||||
pk: p,
|
pk: p,
|
||||||
st: nil,
|
st: nil,
|
||||||
|
nr: nr,
|
||||||
}
|
}
|
||||||
|
|
||||||
proc.handlePut(event)
|
proc.handlePut(event)
|
||||||
|
@ -76,13 +79,7 @@ func TestPutEvent(t *testing.T) {
|
||||||
time.Sleep(10 * time.Millisecond)
|
time.Sleep(10 * time.Millisecond)
|
||||||
}
|
}
|
||||||
|
|
||||||
var expectedPut cntClient.PutPrm
|
require.EqualValues(t, []*transaction.Transaction{nr.MainTransaction}, mc.transactions, "invalid notary requests")
|
||||||
expectedPut.SetContainer(cnr.Marshal())
|
|
||||||
expectedPut.SetKey(p.PublicKey().Bytes())
|
|
||||||
expectedPut.SetSignature(p.Sign(cnr.Marshal()))
|
|
||||||
expectedPut.SetZone("container")
|
|
||||||
|
|
||||||
require.EqualValues(t, []cntClient.PutPrm{expectedPut}, cc.put, "invalid put requests")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestDeleteEvent(t *testing.T) {
|
func TestDeleteEvent(t *testing.T) {
|
||||||
|
@ -103,15 +100,16 @@ func TestDeleteEvent(t *testing.T) {
|
||||||
p.PublicKey(),
|
p.PublicKey(),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
mc := &testMorphClient{}
|
||||||
|
|
||||||
proc, err := New(&Params{
|
proc, err := New(&Params{
|
||||||
Log: test.NewLogger(t, true),
|
Log: test.NewLogger(t, true),
|
||||||
PoolSize: 2,
|
PoolSize: 2,
|
||||||
AlphabetState: &testAlphabetState{isAlphabet: true},
|
AlphabetState: &testAlphabetState{isAlphabet: true},
|
||||||
FrostFSIDClient: idc,
|
FrostFSIDClient: idc,
|
||||||
NotaryDisabled: true,
|
|
||||||
NetworkState: nst,
|
NetworkState: nst,
|
||||||
ContainerClient: cc,
|
ContainerClient: cc,
|
||||||
|
MorphClient: mc,
|
||||||
})
|
})
|
||||||
require.NoError(t, err, "failed to create processor")
|
require.NoError(t, err, "failed to create processor")
|
||||||
|
|
||||||
|
@ -133,9 +131,14 @@ func TestDeleteEvent(t *testing.T) {
|
||||||
cidBin := make([]byte, 32)
|
cidBin := make([]byte, 32)
|
||||||
cid.Encode(cidBin)
|
cid.Encode(cidBin)
|
||||||
|
|
||||||
|
nr := &payload.P2PNotaryRequest{
|
||||||
|
MainTransaction: &transaction.Transaction{},
|
||||||
|
}
|
||||||
|
|
||||||
ev := containerEvent.Delete{
|
ev := containerEvent.Delete{
|
||||||
ContainerIDValue: cidBin,
|
ContainerIDValue: cidBin,
|
||||||
SignatureValue: p.Sign(cidBin),
|
SignatureValue: p.Sign(cidBin),
|
||||||
|
NotaryRequestValue: nr,
|
||||||
}
|
}
|
||||||
|
|
||||||
var signature frostfscrypto.Signature
|
var signature frostfscrypto.Signature
|
||||||
|
@ -156,7 +159,7 @@ func TestDeleteEvent(t *testing.T) {
|
||||||
expectedDelete.SetCID(ev.ContainerID())
|
expectedDelete.SetCID(ev.ContainerID())
|
||||||
expectedDelete.SetSignature(ev.Signature())
|
expectedDelete.SetSignature(ev.Signature())
|
||||||
|
|
||||||
require.EqualValues(t, []cntClient.DeletePrm{expectedDelete}, cc.delete, "invalid delete requests")
|
require.EqualValues(t, []*transaction.Transaction{nr.MainTransaction}, mc.transactions, "invalid notary requests")
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestSetEACLEvent(t *testing.T) {
|
func TestSetEACLEvent(t *testing.T) {
|
||||||
|
@ -168,15 +171,16 @@ func TestSetEACLEvent(t *testing.T) {
|
||||||
cc := &testContainerClient{
|
cc := &testContainerClient{
|
||||||
get: make(map[string]*containercore.Container),
|
get: make(map[string]*containercore.Container),
|
||||||
}
|
}
|
||||||
|
mc := &testMorphClient{}
|
||||||
|
|
||||||
proc, err := New(&Params{
|
proc, err := New(&Params{
|
||||||
Log: test.NewLogger(t, true),
|
Log: test.NewLogger(t, true),
|
||||||
PoolSize: 2,
|
PoolSize: 2,
|
||||||
AlphabetState: &testAlphabetState{isAlphabet: true},
|
AlphabetState: &testAlphabetState{isAlphabet: true},
|
||||||
FrostFSIDClient: &testIDClient{},
|
FrostFSIDClient: &testIDClient{},
|
||||||
NotaryDisabled: true,
|
|
||||||
NetworkState: nst,
|
NetworkState: nst,
|
||||||
ContainerClient: cc,
|
ContainerClient: cc,
|
||||||
|
MorphClient: mc,
|
||||||
})
|
})
|
||||||
require.NoError(t, err, "failed to create processor")
|
require.NoError(t, err, "failed to create processor")
|
||||||
|
|
||||||
|
@ -219,10 +223,14 @@ func TestSetEACLEvent(t *testing.T) {
|
||||||
|
|
||||||
table.AddRecord(r)
|
table.AddRecord(r)
|
||||||
|
|
||||||
|
nr := &payload.P2PNotaryRequest{
|
||||||
|
MainTransaction: &transaction.Transaction{},
|
||||||
|
}
|
||||||
event := containerEvent.SetEACL{
|
event := containerEvent.SetEACL{
|
||||||
TableValue: table.ToV2().StableMarshal(nil),
|
TableValue: table.ToV2().StableMarshal(nil),
|
||||||
PublicKeyValue: p.PublicKey().Bytes(),
|
PublicKeyValue: p.PublicKey().Bytes(),
|
||||||
SignatureValue: p.Sign(table.ToV2().StableMarshal(nil)),
|
SignatureValue: p.Sign(table.ToV2().StableMarshal(nil)),
|
||||||
|
NotaryRequestValue: nr,
|
||||||
}
|
}
|
||||||
|
|
||||||
proc.handleSetEACL(event)
|
proc.handleSetEACL(event)
|
||||||
|
@ -236,7 +244,7 @@ func TestSetEACLEvent(t *testing.T) {
|
||||||
expectedPutEACL.SetKey(p.PublicKey().Bytes())
|
expectedPutEACL.SetKey(p.PublicKey().Bytes())
|
||||||
expectedPutEACL.SetSignature(p.Sign(table.ToV2().StableMarshal(nil)))
|
expectedPutEACL.SetSignature(p.Sign(table.ToV2().StableMarshal(nil)))
|
||||||
|
|
||||||
require.EqualValues(t, []cntClient.PutEACLPrm{expectedPutEACL}, cc.putEACL, "invalid set EACL requests")
|
require.EqualValues(t, []*transaction.Transaction{nr.MainTransaction}, mc.transactions, "invalid notary requests")
|
||||||
}
|
}
|
||||||
|
|
||||||
type testAlphabetState struct {
|
type testAlphabetState struct {
|
||||||
|
@ -262,25 +270,13 @@ func (s *testNetworkState) Epoch() (uint64, error) {
|
||||||
|
|
||||||
type testContainerClient struct {
|
type testContainerClient struct {
|
||||||
contractAddress util.Uint160
|
contractAddress util.Uint160
|
||||||
put []cntClient.PutPrm
|
|
||||||
get map[string]*containercore.Container
|
get map[string]*containercore.Container
|
||||||
delete []cntClient.DeletePrm
|
|
||||||
putEACL []cntClient.PutEACLPrm
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *testContainerClient) ContractAddress() util.Uint160 {
|
func (c *testContainerClient) ContractAddress() util.Uint160 {
|
||||||
return c.contractAddress
|
return c.contractAddress
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *testContainerClient) Morph() *client.Client {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *testContainerClient) Put(p cntClient.PutPrm) error {
|
|
||||||
c.put = append(c.put, p)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *testContainerClient) Get(cid []byte) (*containercore.Container, error) {
|
func (c *testContainerClient) Get(cid []byte) (*containercore.Container, error) {
|
||||||
key := hex.EncodeToString(cid)
|
key := hex.EncodeToString(cid)
|
||||||
if cont, found := c.get[key]; found {
|
if cont, found := c.get[key]; found {
|
||||||
|
@ -289,16 +285,6 @@ func (c *testContainerClient) Get(cid []byte) (*containercore.Container, error)
|
||||||
return nil, apistatus.ContainerNotFound{}
|
return nil, apistatus.ContainerNotFound{}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *testContainerClient) Delete(p cntClient.DeletePrm) error {
|
|
||||||
c.delete = append(c.delete, p)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *testContainerClient) PutEACL(p cntClient.PutEACLPrm) error {
|
|
||||||
c.putEACL = append(c.putEACL, p)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
type testIDClient struct {
|
type testIDClient struct {
|
||||||
publicKeys keys.PublicKeys
|
publicKeys keys.PublicKeys
|
||||||
}
|
}
|
||||||
|
@ -313,6 +299,7 @@ type testPutEvent struct {
|
||||||
cnr *containerSDK.Container
|
cnr *containerSDK.Container
|
||||||
pk *keys.PrivateKey
|
pk *keys.PrivateKey
|
||||||
st []byte
|
st []byte
|
||||||
|
nr *payload.P2PNotaryRequest
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *testPutEvent) MorphEvent() {}
|
func (e *testPutEvent) MorphEvent() {}
|
||||||
|
@ -333,5 +320,14 @@ func (e *testPutEvent) SessionToken() []byte {
|
||||||
return e.st
|
return e.st
|
||||||
}
|
}
|
||||||
func (e *testPutEvent) NotaryRequest() *payload.P2PNotaryRequest {
|
func (e *testPutEvent) NotaryRequest() *payload.P2PNotaryRequest {
|
||||||
|
return e.nr
|
||||||
|
}
|
||||||
|
|
||||||
|
type testMorphClient struct {
|
||||||
|
transactions []*transaction.Transaction
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *testMorphClient) NotarySignAndInvokeTX(mainTx *transaction.Transaction) error {
|
||||||
|
c.transactions = append(c.transactions, mainTx)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,6 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-node/internal/logs"
|
"git.frostfs.info/TrueCloudLab/frostfs-node/internal/logs"
|
||||||
cntClient "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/morph/client/container"
|
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/morph/event"
|
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/morph/event"
|
||||||
containerEvent "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/morph/event/container"
|
containerEvent "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/morph/event/container"
|
||||||
containerSDK "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container"
|
containerSDK "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container"
|
||||||
|
@ -91,27 +90,7 @@ func (cp *Processor) checkPutContainer(ctx *putContainerContext) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cp *Processor) approvePutContainer(ctx *putContainerContext) {
|
func (cp *Processor) approvePutContainer(ctx *putContainerContext) {
|
||||||
e := ctx.e
|
if err := cp.morphClient.NotarySignAndInvokeTX(ctx.e.NotaryRequest().MainTransaction); err != nil {
|
||||||
|
|
||||||
var err error
|
|
||||||
|
|
||||||
prm := cntClient.PutPrm{}
|
|
||||||
|
|
||||||
prm.SetContainer(e.Container())
|
|
||||||
prm.SetKey(e.PublicKey())
|
|
||||||
prm.SetSignature(e.Signature())
|
|
||||||
prm.SetToken(e.SessionToken())
|
|
||||||
prm.SetName(ctx.d.Name())
|
|
||||||
prm.SetZone(ctx.d.Zone())
|
|
||||||
|
|
||||||
if nr := e.NotaryRequest(); nr != nil {
|
|
||||||
// put event was received via Notary service
|
|
||||||
err = cp.cnrClient.Morph().NotarySignAndInvokeTX(nr.MainTransaction)
|
|
||||||
} else {
|
|
||||||
// put event was received via notification service
|
|
||||||
err = cp.cnrClient.Put(prm)
|
|
||||||
}
|
|
||||||
if err != nil {
|
|
||||||
cp.log.Error(logs.ContainerCouldNotApprovePutContainer,
|
cp.log.Error(logs.ContainerCouldNotApprovePutContainer,
|
||||||
zap.String("error", err.Error()),
|
zap.String("error", err.Error()),
|
||||||
)
|
)
|
||||||
|
@ -171,22 +150,7 @@ func (cp *Processor) checkDeleteContainer(e containerEvent.Delete) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cp *Processor) approveDeleteContainer(e containerEvent.Delete) {
|
func (cp *Processor) approveDeleteContainer(e containerEvent.Delete) {
|
||||||
var err error
|
if err := cp.morphClient.NotarySignAndInvokeTX(e.NotaryRequest().MainTransaction); err != nil {
|
||||||
|
|
||||||
prm := cntClient.DeletePrm{}
|
|
||||||
|
|
||||||
prm.SetCID(e.ContainerID())
|
|
||||||
prm.SetSignature(e.Signature())
|
|
||||||
prm.SetToken(e.SessionToken())
|
|
||||||
|
|
||||||
if nr := e.NotaryRequest(); nr != nil {
|
|
||||||
// delete event was received via Notary service
|
|
||||||
err = cp.cnrClient.Morph().NotarySignAndInvokeTX(nr.MainTransaction)
|
|
||||||
} else {
|
|
||||||
// delete event was received via notification service
|
|
||||||
err = cp.cnrClient.Delete(prm)
|
|
||||||
}
|
|
||||||
if err != nil {
|
|
||||||
cp.log.Error(logs.ContainerCouldNotApproveDeleteContainer,
|
cp.log.Error(logs.ContainerCouldNotApproveDeleteContainer,
|
||||||
zap.String("error", err.Error()),
|
zap.String("error", err.Error()),
|
||||||
)
|
)
|
||||||
|
|
|
@ -75,23 +75,7 @@ func (cp *Processor) checkSetEACL(e containerEvent.SetEACL) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cp *Processor) approveSetEACL(e containerEvent.SetEACL) {
|
func (cp *Processor) approveSetEACL(e containerEvent.SetEACL) {
|
||||||
var err error
|
if err := cp.morphClient.NotarySignAndInvokeTX(e.NotaryRequest().MainTransaction); err != nil {
|
||||||
|
|
||||||
prm := cntClient.PutEACLPrm{}
|
|
||||||
|
|
||||||
prm.SetTable(e.Table())
|
|
||||||
prm.SetKey(e.PublicKey())
|
|
||||||
prm.SetSignature(e.Signature())
|
|
||||||
prm.SetToken(e.SessionToken())
|
|
||||||
|
|
||||||
if nr := e.NotaryRequest(); nr != nil {
|
|
||||||
// setEACL event was received via Notary service
|
|
||||||
err = cp.cnrClient.Morph().NotarySignAndInvokeTX(nr.MainTransaction)
|
|
||||||
} else {
|
|
||||||
// setEACL event was received via notification service
|
|
||||||
err = cp.cnrClient.PutEACL(prm)
|
|
||||||
}
|
|
||||||
if err != nil {
|
|
||||||
cp.log.Error(logs.ContainerCouldNotApproveSetEACL,
|
cp.log.Error(logs.ContainerCouldNotApproveSetEACL,
|
||||||
zap.String("error", err.Error()),
|
zap.String("error", err.Error()),
|
||||||
)
|
)
|
||||||
|
|
|
@ -6,13 +6,12 @@ import (
|
||||||
|
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-node/internal/logs"
|
"git.frostfs.info/TrueCloudLab/frostfs-node/internal/logs"
|
||||||
containercore "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/core/container"
|
containercore "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/core/container"
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/morph/client"
|
|
||||||
cntClient "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/morph/client/container"
|
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/morph/client/frostfsid"
|
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/morph/client/frostfsid"
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/morph/event"
|
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/morph/event"
|
||||||
containerEvent "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/morph/event/container"
|
containerEvent "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/morph/event/container"
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/util/logger"
|
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/util/logger"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/core/mempoolevent"
|
"github.com/nspcc-dev/neo-go/pkg/core/mempoolevent"
|
||||||
|
"github.com/nspcc-dev/neo-go/pkg/core/transaction"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
|
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/util"
|
"github.com/nspcc-dev/neo-go/pkg/util"
|
||||||
"github.com/panjf2000/ants/v2"
|
"github.com/panjf2000/ants/v2"
|
||||||
|
@ -27,11 +26,11 @@ type (
|
||||||
|
|
||||||
ContClient interface {
|
ContClient interface {
|
||||||
ContractAddress() util.Uint160
|
ContractAddress() util.Uint160
|
||||||
Morph() *client.Client
|
|
||||||
Put(p cntClient.PutPrm) error
|
|
||||||
Get(cid []byte) (*containercore.Container, error)
|
Get(cid []byte) (*containercore.Container, error)
|
||||||
Delete(p cntClient.DeletePrm) error
|
}
|
||||||
PutEACL(p cntClient.PutEACLPrm) error
|
|
||||||
|
MorphClient interface {
|
||||||
|
NotarySignAndInvokeTX(mainTx *transaction.Transaction) error
|
||||||
}
|
}
|
||||||
|
|
||||||
IDClient interface {
|
IDClient interface {
|
||||||
|
@ -40,13 +39,13 @@ type (
|
||||||
|
|
||||||
// Processor of events produced by container contract in the sidechain.
|
// Processor of events produced by container contract in the sidechain.
|
||||||
Processor struct {
|
Processor struct {
|
||||||
log *logger.Logger
|
log *logger.Logger
|
||||||
pool *ants.Pool
|
pool *ants.Pool
|
||||||
alphabetState AlphabetState
|
alphabetState AlphabetState
|
||||||
cnrClient ContClient // notary must be enabled
|
cnrClient ContClient // notary must be enabled
|
||||||
idClient IDClient
|
morphClient MorphClient
|
||||||
netState NetworkState
|
idClient IDClient
|
||||||
notaryDisabled bool
|
netState NetworkState
|
||||||
}
|
}
|
||||||
|
|
||||||
// Params of the processor constructor.
|
// Params of the processor constructor.
|
||||||
|
@ -55,9 +54,9 @@ type (
|
||||||
PoolSize int
|
PoolSize int
|
||||||
AlphabetState AlphabetState
|
AlphabetState AlphabetState
|
||||||
ContainerClient ContClient
|
ContainerClient ContClient
|
||||||
|
MorphClient MorphClient
|
||||||
FrostFSIDClient IDClient
|
FrostFSIDClient IDClient
|
||||||
NetworkState NetworkState
|
NetworkState NetworkState
|
||||||
NotaryDisabled bool
|
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -88,6 +87,8 @@ func New(p *Params) (*Processor, error) {
|
||||||
return nil, errors.New("ir/container: global state is not set")
|
return nil, errors.New("ir/container: global state is not set")
|
||||||
case p.ContainerClient == nil:
|
case p.ContainerClient == nil:
|
||||||
return nil, errors.New("ir/container: Container client is not set")
|
return nil, errors.New("ir/container: Container client is not set")
|
||||||
|
case p.MorphClient == nil:
|
||||||
|
return nil, errors.New("ir/container: Morph client is not set")
|
||||||
case p.FrostFSIDClient == nil:
|
case p.FrostFSIDClient == nil:
|
||||||
return nil, errors.New("ir/container: FrostFS ID client is not set")
|
return nil, errors.New("ir/container: FrostFS ID client is not set")
|
||||||
case p.NetworkState == nil:
|
case p.NetworkState == nil:
|
||||||
|
@ -102,13 +103,13 @@ func New(p *Params) (*Processor, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
return &Processor{
|
return &Processor{
|
||||||
log: p.Log,
|
log: p.Log,
|
||||||
pool: pool,
|
pool: pool,
|
||||||
alphabetState: p.AlphabetState,
|
alphabetState: p.AlphabetState,
|
||||||
cnrClient: p.ContainerClient,
|
cnrClient: p.ContainerClient,
|
||||||
idClient: p.FrostFSIDClient,
|
idClient: p.FrostFSIDClient,
|
||||||
netState: p.NetworkState,
|
netState: p.NetworkState,
|
||||||
notaryDisabled: p.NotaryDisabled,
|
morphClient: p.MorphClient,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -42,16 +42,15 @@ func TestHandleAlphabetSyncEvent(t *testing.T) {
|
||||||
|
|
||||||
proc, err := New(
|
proc, err := New(
|
||||||
&Params{
|
&Params{
|
||||||
Log: test.NewLogger(t, true),
|
Log: test.NewLogger(t, true),
|
||||||
EpochState: es,
|
EpochState: es,
|
||||||
AlphabetState: as,
|
AlphabetState: as,
|
||||||
Voter: v,
|
Voter: v,
|
||||||
IRFetcher: irf,
|
IRFetcher: irf,
|
||||||
NotaryDisabled: true,
|
MorphClient: m,
|
||||||
MorphClient: m,
|
MainnetClient: mn,
|
||||||
MainnetClient: mn,
|
FrostFSClient: f,
|
||||||
FrostFSClient: f,
|
NetmapClient: nm,
|
||||||
NetmapClient: nm,
|
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -74,17 +73,19 @@ func TestHandleAlphabetSyncEvent(t *testing.T) {
|
||||||
},
|
},
|
||||||
}, v.votes, "invalid vote calls")
|
}, v.votes, "invalid vote calls")
|
||||||
|
|
||||||
var irUpdateExp nmClient.UpdateIRPrm
|
var irUpdateExp []nmClient.UpdateIRPrm
|
||||||
irUpdateExp.SetKeys(testKeys.newInnerRingExp)
|
|
||||||
irUpdateExp.SetHash(ev.txHash)
|
|
||||||
|
|
||||||
require.EqualValues(t, []nmClient.UpdateIRPrm{irUpdateExp}, nm.updates, "invalid IR updates")
|
require.EqualValues(t, irUpdateExp, nm.updates, "invalid IR updates")
|
||||||
|
|
||||||
var expAlphabetUpdates []client.UpdateAlphabetListPrm
|
var expAlphabetUpdate client.UpdateAlphabetListPrm
|
||||||
require.EqualValues(t, expAlphabetUpdates, m.alphabetUpdates, "invalid alphabet updates")
|
expAlphabetUpdate.SetHash(ev.txHash)
|
||||||
|
expAlphabetUpdate.SetList(testKeys.newInnerRingExp)
|
||||||
|
require.EqualValues(t, []client.UpdateAlphabetListPrm{expAlphabetUpdate}, m.alphabetUpdates, "invalid alphabet updates")
|
||||||
|
|
||||||
var expNotaryUpdates []client.UpdateNotaryListPrm
|
var expNotaryUpdate client.UpdateNotaryListPrm
|
||||||
require.EqualValues(t, expNotaryUpdates, m.notaryUpdates, "invalid notary list updates")
|
expNotaryUpdate.SetHash(ev.txHash)
|
||||||
|
expNotaryUpdate.SetList(testKeys.newAlphabetExp)
|
||||||
|
require.EqualValues(t, []client.UpdateNotaryListPrm{expNotaryUpdate}, m.notaryUpdates, "invalid notary list updates")
|
||||||
|
|
||||||
buf := make([]byte, 8)
|
buf := make([]byte, 8)
|
||||||
binary.LittleEndian.PutUint64(buf, es.epoch)
|
binary.LittleEndian.PutUint64(buf, es.epoch)
|
||||||
|
@ -122,16 +123,15 @@ func TestHandleAlphabetDesignateEvent(t *testing.T) {
|
||||||
|
|
||||||
proc, err := New(
|
proc, err := New(
|
||||||
&Params{
|
&Params{
|
||||||
Log: test.NewLogger(t, true),
|
Log: test.NewLogger(t, true),
|
||||||
EpochState: es,
|
EpochState: es,
|
||||||
AlphabetState: as,
|
AlphabetState: as,
|
||||||
Voter: v,
|
Voter: v,
|
||||||
IRFetcher: irf,
|
IRFetcher: irf,
|
||||||
NotaryDisabled: false,
|
MorphClient: m,
|
||||||
MorphClient: m,
|
MainnetClient: mn,
|
||||||
MainnetClient: mn,
|
FrostFSClient: f,
|
||||||
FrostFSClient: f,
|
NetmapClient: nm,
|
||||||
NetmapClient: nm,
|
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -9,7 +9,6 @@ import (
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-node/internal/logs"
|
"git.frostfs.info/TrueCloudLab/frostfs-node/internal/logs"
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/morph/client"
|
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/morph/client"
|
||||||
frostfscontract "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/morph/client/frostfs"
|
frostfscontract "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/morph/client/frostfs"
|
||||||
nmClient "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/morph/client/netmap"
|
|
||||||
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
|
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/util"
|
"github.com/nspcc-dev/neo-go/pkg/util"
|
||||||
"go.uber.org/zap"
|
"go.uber.org/zap"
|
||||||
|
@ -114,33 +113,17 @@ func (gp *Processor) updateNeoFSAlphabetRoleInSidechain(sidechainAlphabet, newAl
|
||||||
zap.String("after", prettyKeys(newInnerRing)),
|
zap.String("after", prettyKeys(newInnerRing)),
|
||||||
)
|
)
|
||||||
|
|
||||||
if gp.notaryDisabled {
|
updPrm := client.UpdateAlphabetListPrm{}
|
||||||
updPrm := nmClient.UpdateIRPrm{}
|
updPrm.SetList(newInnerRing)
|
||||||
|
updPrm.SetHash(txHash)
|
||||||
|
|
||||||
updPrm.SetKeys(newInnerRing)
|
if err = gp.morphClient.UpdateNeoFSAlphabetList(updPrm); err != nil {
|
||||||
updPrm.SetHash(txHash)
|
|
||||||
|
|
||||||
err = gp.netmapClient.UpdateInnerRing(updPrm)
|
|
||||||
} else {
|
|
||||||
updPrm := client.UpdateAlphabetListPrm{}
|
|
||||||
|
|
||||||
updPrm.SetList(newInnerRing)
|
|
||||||
updPrm.SetHash(txHash)
|
|
||||||
|
|
||||||
err = gp.morphClient.UpdateNeoFSAlphabetList(updPrm)
|
|
||||||
}
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
gp.log.Error(logs.GovernanceCantUpdateInnerRingListWithNewAlphabetKeys,
|
gp.log.Error(logs.GovernanceCantUpdateInnerRingListWithNewAlphabetKeys,
|
||||||
zap.String("error", err.Error()))
|
zap.String("error", err.Error()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (gp *Processor) updateNotaryRoleInSidechain(newAlphabet keys.PublicKeys, txHash util.Uint256) {
|
func (gp *Processor) updateNotaryRoleInSidechain(newAlphabet keys.PublicKeys, txHash util.Uint256) {
|
||||||
if gp.notaryDisabled {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
updPrm := client.UpdateNotaryListPrm{}
|
updPrm := client.UpdateNotaryListPrm{}
|
||||||
|
|
||||||
updPrm.SetList(newAlphabet)
|
updPrm.SetList(newAlphabet)
|
||||||
|
|
|
@ -87,8 +87,6 @@ type (
|
||||||
mainnetClient MainnetClient
|
mainnetClient MainnetClient
|
||||||
morphClient MorphClient
|
morphClient MorphClient
|
||||||
|
|
||||||
notaryDisabled bool
|
|
||||||
|
|
||||||
designate util.Uint160
|
designate util.Uint160
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -105,8 +103,6 @@ type (
|
||||||
MainnetClient MainnetClient
|
MainnetClient MainnetClient
|
||||||
FrostFSClient FrostFSClient
|
FrostFSClient FrostFSClient
|
||||||
NetmapClient NetmapClient
|
NetmapClient NetmapClient
|
||||||
|
|
||||||
NotaryDisabled bool
|
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -138,18 +134,17 @@ func New(p *Params) (*Processor, error) {
|
||||||
designate := p.MainnetClient.GetDesignateHash()
|
designate := p.MainnetClient.GetDesignateHash()
|
||||||
|
|
||||||
return &Processor{
|
return &Processor{
|
||||||
log: p.Log,
|
log: p.Log,
|
||||||
pool: pool,
|
pool: pool,
|
||||||
frostfsClient: p.FrostFSClient,
|
frostfsClient: p.FrostFSClient,
|
||||||
netmapClient: p.NetmapClient,
|
netmapClient: p.NetmapClient,
|
||||||
alphabetState: p.AlphabetState,
|
alphabetState: p.AlphabetState,
|
||||||
epochState: p.EpochState,
|
epochState: p.EpochState,
|
||||||
voter: p.Voter,
|
voter: p.Voter,
|
||||||
irFetcher: p.IRFetcher,
|
irFetcher: p.IRFetcher,
|
||||||
mainnetClient: p.MainnetClient,
|
mainnetClient: p.MainnetClient,
|
||||||
morphClient: p.MorphClient,
|
morphClient: p.MorphClient,
|
||||||
notaryDisabled: p.NotaryDisabled,
|
designate: designate,
|
||||||
designate: designate,
|
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -31,7 +31,6 @@ func TestNewEpochTick(t *testing.T) {
|
||||||
nc := &testNetmapClient{}
|
nc := &testNetmapClient{}
|
||||||
|
|
||||||
proc, err := newTestProc(t, func(p *Params) {
|
proc, err := newTestProc(t, func(p *Params) {
|
||||||
p.NotaryDisabled = true
|
|
||||||
p.CleanupEnabled = true
|
p.CleanupEnabled = true
|
||||||
p.EpochState = es
|
p.EpochState = es
|
||||||
p.NetmapClient = nc
|
p.NetmapClient = nc
|
||||||
|
@ -80,7 +79,6 @@ func TestNewEpoch(t *testing.T) {
|
||||||
eh := &testEventHandler{}
|
eh := &testEventHandler{}
|
||||||
|
|
||||||
proc, err := newTestProc(t, func(p *Params) {
|
proc, err := newTestProc(t, func(p *Params) {
|
||||||
p.NotaryDisabled = true
|
|
||||||
p.NotaryDepositHandler = eh.Handle
|
p.NotaryDepositHandler = eh.Handle
|
||||||
p.AlphabetSyncHandler = eh.Handle
|
p.AlphabetSyncHandler = eh.Handle
|
||||||
p.NetmapClient = nc
|
p.NetmapClient = nc
|
||||||
|
@ -119,276 +117,139 @@ func TestNewEpoch(t *testing.T) {
|
||||||
func TestAddPeer(t *testing.T) {
|
func TestAddPeer(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
t.Run("with notary", func(t *testing.T) {
|
nc := &testNetmapClient{
|
||||||
t.Parallel()
|
contractAddress: util.Uint160{47},
|
||||||
nc := &testNetmapClient{
|
}
|
||||||
contractAddress: util.Uint160{47},
|
|
||||||
}
|
|
||||||
|
|
||||||
proc, err := newTestProc(t, func(p *Params) {
|
proc, err := newTestProc(t, func(p *Params) {
|
||||||
p.NotaryDisabled = true
|
p.NetmapClient = nc
|
||||||
p.NetmapClient = nc
|
|
||||||
})
|
|
||||||
|
|
||||||
require.NoError(t, err, "failed to create processor")
|
|
||||||
|
|
||||||
var node netmap.NodeInfo
|
|
||||||
key, err := keys.NewPublicKeyFromString("038c862959e56b43e20f79187c4fe9e0bc7c8c66c1603e6cf0ec7f87ab6b08dc35")
|
|
||||||
require.NoError(t, err, "failed to parse key1")
|
|
||||||
node.SetPublicKey(key.Bytes())
|
|
||||||
|
|
||||||
ev := netmapEvent.AddPeer{
|
|
||||||
NodeBytes: node.Marshal(),
|
|
||||||
Request: &payload.P2PNotaryRequest{
|
|
||||||
MainTransaction: &transaction.Transaction{
|
|
||||||
Nonce: 100,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
proc.handleAddPeer(ev)
|
|
||||||
|
|
||||||
for proc.pool.Running() > 0 {
|
|
||||||
time.Sleep(10 * time.Millisecond)
|
|
||||||
}
|
|
||||||
|
|
||||||
require.EqualValues(t, []notaryInvoke{
|
|
||||||
{
|
|
||||||
contract: nc.contractAddress,
|
|
||||||
fee: 0,
|
|
||||||
nonce: ev.Request.MainTransaction.Nonce,
|
|
||||||
vub: nil,
|
|
||||||
method: "addPeerIR",
|
|
||||||
args: []any{ev.Node()},
|
|
||||||
},
|
|
||||||
}, nc.notaryInvokes, "invalid notary invokes")
|
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("without notary", func(t *testing.T) {
|
require.NoError(t, err, "failed to create processor")
|
||||||
t.Parallel()
|
|
||||||
|
|
||||||
nc := &testNetmapClient{
|
var node netmap.NodeInfo
|
||||||
contractAddress: util.Uint160{47},
|
key, err := keys.NewPublicKeyFromString("038c862959e56b43e20f79187c4fe9e0bc7c8c66c1603e6cf0ec7f87ab6b08dc35")
|
||||||
}
|
require.NoError(t, err, "failed to parse key")
|
||||||
|
node.SetPublicKey(key.Bytes())
|
||||||
|
|
||||||
proc, err := newTestProc(t, func(p *Params) {
|
ev := netmapEvent.AddPeer{
|
||||||
p.NotaryDisabled = true
|
NodeBytes: node.Marshal(),
|
||||||
p.NetmapClient = nc
|
Request: &payload.P2PNotaryRequest{
|
||||||
})
|
MainTransaction: &transaction.Transaction{},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
proc.handleAddPeer(ev)
|
||||||
|
|
||||||
require.NoError(t, err, "failed to create processor")
|
for proc.pool.Running() > 0 {
|
||||||
|
time.Sleep(10 * time.Millisecond)
|
||||||
|
}
|
||||||
|
|
||||||
var node netmap.NodeInfo
|
require.EqualValues(t, []notaryInvoke{
|
||||||
key, err := keys.NewPublicKeyFromString("038c862959e56b43e20f79187c4fe9e0bc7c8c66c1603e6cf0ec7f87ab6b08dc35")
|
{
|
||||||
require.NoError(t, err, "failed to parse key")
|
contract: nc.contractAddress,
|
||||||
node.SetPublicKey(key.Bytes())
|
fee: 0,
|
||||||
|
nonce: ev.NotaryRequest().MainTransaction.Nonce,
|
||||||
ev := netmapEvent.AddPeer{
|
vub: nil,
|
||||||
NodeBytes: node.Marshal(),
|
method: "addPeerIR",
|
||||||
}
|
args: []any{node.Marshal()},
|
||||||
proc.handleAddPeer(ev)
|
},
|
||||||
|
}, nc.notaryInvokes, "invalid notary invokes")
|
||||||
for proc.pool.Running() > 0 {
|
|
||||||
time.Sleep(10 * time.Millisecond)
|
|
||||||
}
|
|
||||||
|
|
||||||
var addPeerExp netmapclient.AddPeerPrm
|
|
||||||
addPeerExp.SetNodeInfo(node)
|
|
||||||
require.EqualValues(t, []netmapclient.AddPeerPrm{addPeerExp}, nc.addPeers, "invalid peers")
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestUpdateState(t *testing.T) {
|
func TestUpdateState(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
t.Run("with notary", func(t *testing.T) {
|
ns := &testNodeStateSettings{
|
||||||
t.Parallel()
|
maintAllowed: true,
|
||||||
ns := &testNodeStateSettings{
|
}
|
||||||
maintAllowed: true,
|
nc := &testNetmapClient{}
|
||||||
}
|
|
||||||
nc := &testNetmapClient{}
|
|
||||||
|
|
||||||
proc, err := newTestProc(t, func(p *Params) {
|
proc, err := newTestProc(t, func(p *Params) {
|
||||||
p.NotaryDisabled = true
|
p.NetmapClient = nc
|
||||||
p.NodeStateSettings = ns
|
p.NodeStateSettings = ns
|
||||||
p.NetmapClient = nc
|
|
||||||
})
|
|
||||||
|
|
||||||
require.NoError(t, err, "failed to create processor")
|
|
||||||
|
|
||||||
key, err := keys.NewPublicKeyFromString("038c862959e56b43e20f79187c4fe9e0bc7c8c66c1603e6cf0ec7f87ab6b08dc35")
|
|
||||||
require.NoError(t, err, "failed to parse key")
|
|
||||||
|
|
||||||
ev := netmapEvent.UpdatePeer{
|
|
||||||
State: netmapContract.NodeStateOnline,
|
|
||||||
PubKey: key,
|
|
||||||
Request: &payload.P2PNotaryRequest{
|
|
||||||
MainTransaction: &transaction.Transaction{
|
|
||||||
Nonce: 100,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
proc.handleUpdateState(ev)
|
|
||||||
|
|
||||||
for proc.pool.Running() > 0 {
|
|
||||||
time.Sleep(10 * time.Millisecond)
|
|
||||||
}
|
|
||||||
|
|
||||||
require.EqualValues(t, []*transaction.Transaction{
|
|
||||||
ev.Request.MainTransaction,
|
|
||||||
}, nc.invokedTxs, "invalid invoked transactions")
|
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("without notary", func(t *testing.T) {
|
require.NoError(t, err, "failed to create processor")
|
||||||
t.Parallel()
|
|
||||||
ns := &testNodeStateSettings{
|
|
||||||
maintAllowed: true,
|
|
||||||
}
|
|
||||||
nc := &testNetmapClient{}
|
|
||||||
|
|
||||||
proc, err := newTestProc(t, func(p *Params) {
|
key, err := keys.NewPublicKeyFromString("038c862959e56b43e20f79187c4fe9e0bc7c8c66c1603e6cf0ec7f87ab6b08dc35")
|
||||||
p.NetmapClient = nc
|
require.NoError(t, err, "failed to parse key")
|
||||||
p.NodeStateSettings = ns
|
|
||||||
})
|
|
||||||
|
|
||||||
require.NoError(t, err, "failed to create processor")
|
ev := netmapEvent.UpdatePeer{
|
||||||
|
State: netmapContract.NodeStateOnline,
|
||||||
|
PubKey: key,
|
||||||
|
Request: &payload.P2PNotaryRequest{
|
||||||
|
MainTransaction: &transaction.Transaction{},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
proc.handleUpdateState(ev)
|
||||||
|
|
||||||
key, err := keys.NewPublicKeyFromString("038c862959e56b43e20f79187c4fe9e0bc7c8c66c1603e6cf0ec7f87ab6b08dc35")
|
for proc.pool.Running() > 0 {
|
||||||
require.NoError(t, err, "failed to parse key")
|
time.Sleep(10 * time.Millisecond)
|
||||||
|
}
|
||||||
|
|
||||||
ev := netmapEvent.UpdatePeer{
|
require.EqualValues(t, []*transaction.Transaction{ev.Request.MainTransaction}, nc.invokedTxs, "invalid transactions")
|
||||||
State: netmapContract.NodeStateOnline,
|
|
||||||
PubKey: key,
|
|
||||||
}
|
|
||||||
proc.handleUpdateState(ev)
|
|
||||||
|
|
||||||
for proc.pool.Running() > 0 {
|
|
||||||
time.Sleep(10 * time.Millisecond)
|
|
||||||
}
|
|
||||||
|
|
||||||
var expUpdPeer netmapclient.UpdatePeerPrm
|
|
||||||
expUpdPeer.SetMaintenance()
|
|
||||||
expUpdPeer.SetOnline()
|
|
||||||
expUpdPeer.SetKey(ev.PubKey.Bytes())
|
|
||||||
|
|
||||||
require.EqualValues(t, []netmapclient.UpdatePeerPrm{expUpdPeer}, nc.peerStateUpdates, "invalid peer state updates")
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestCleanupTick(t *testing.T) {
|
func TestCleanupTick(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
t.Run("notary disabled", func(t *testing.T) {
|
nc := &testNetmapClient{
|
||||||
t.Parallel()
|
contractAddress: util.Uint160{111},
|
||||||
|
}
|
||||||
nc := &testNetmapClient{}
|
proc, err := newTestProc(t,
|
||||||
|
func(p *Params) {
|
||||||
proc, err := newTestProc(t, func(p *Params) {
|
|
||||||
p.NetmapClient = nc
|
p.NetmapClient = nc
|
||||||
p.NotaryDisabled = true
|
|
||||||
p.CleanupEnabled = true
|
p.CleanupEnabled = true
|
||||||
})
|
},
|
||||||
|
)
|
||||||
|
|
||||||
require.NoError(t, err, "failed to create processor")
|
require.NoError(t, err, "failed to create processor")
|
||||||
|
|
||||||
key1Str := "038c862959e56b43e20f79187c4fe9e0bc7c8c66c1603e6cf0ec7f87ab6b08dc35"
|
key1Str := "038c862959e56b43e20f79187c4fe9e0bc7c8c66c1603e6cf0ec7f87ab6b08dc35"
|
||||||
proc.netmapSnapshot.lastAccess[key1Str] = epochStampWithNodeInfo{
|
proc.netmapSnapshot.lastAccess[key1Str] = epochStampWithNodeInfo{
|
||||||
epochStamp: epochStamp{
|
epochStamp: epochStamp{
|
||||||
epoch: 95,
|
epoch: 95,
|
||||||
removeFlag: false,
|
removeFlag: false,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
key2Str := "02ac920cd7df0b61b289072e6b946e2da4e1a31b9ab1c621bb475e30fa4ab102c3"
|
key2Str := "02ac920cd7df0b61b289072e6b946e2da4e1a31b9ab1c621bb475e30fa4ab102c3"
|
||||||
proc.netmapSnapshot.lastAccess[key2Str] = epochStampWithNodeInfo{
|
proc.netmapSnapshot.lastAccess[key2Str] = epochStampWithNodeInfo{
|
||||||
epochStamp: epochStamp{
|
epochStamp: epochStamp{
|
||||||
epoch: 98,
|
epoch: 98,
|
||||||
removeFlag: false,
|
removeFlag: false,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
ev := netmapCleanupTick{
|
ev := netmapCleanupTick{
|
||||||
epoch: 100,
|
epoch: 100,
|
||||||
txHash: util.Uint256{123},
|
txHash: util.Uint256{123},
|
||||||
}
|
}
|
||||||
|
|
||||||
proc.handleCleanupTick(ev)
|
proc.handleCleanupTick(ev)
|
||||||
|
|
||||||
for proc.pool.Running() > 0 {
|
for proc.pool.Running() > 0 {
|
||||||
time.Sleep(10 * time.Millisecond)
|
time.Sleep(10 * time.Millisecond)
|
||||||
}
|
}
|
||||||
|
|
||||||
keyExp, err := keys.NewPublicKeyFromString(key1Str)
|
keyExp, err := keys.NewPublicKeyFromString(key1Str)
|
||||||
require.NoError(t, err, "failed to parse expired key")
|
require.NoError(t, err, "failed to parse expired key")
|
||||||
|
|
||||||
updExp := netmapclient.UpdatePeerPrm{}
|
updExp := netmapclient.UpdatePeerPrm{}
|
||||||
updExp.SetKey(keyExp.Bytes())
|
updExp.SetKey(keyExp.Bytes())
|
||||||
updExp.SetHash(ev.TxHash())
|
updExp.SetHash(ev.TxHash())
|
||||||
|
|
||||||
require.EqualValues(t, []netmapclient.UpdatePeerPrm{updExp}, nc.peerStateUpdates, "invalid peer updates")
|
require.EqualValues(t, []notaryInvoke{
|
||||||
require.True(t, proc.netmapSnapshot.lastAccess[key1Str].removeFlag, "invalid expired removed flag")
|
{
|
||||||
require.False(t, proc.netmapSnapshot.lastAccess[key2Str].removeFlag, "invalid non expired removed flag")
|
contract: nc.contractAddress,
|
||||||
})
|
fee: 0,
|
||||||
|
nonce: uint32(ev.epoch),
|
||||||
t.Run("notary enabled", func(t *testing.T) {
|
vub: nil,
|
||||||
t.Parallel()
|
method: "updateStateIR",
|
||||||
|
args: []any{int64(v2netmap.Offline), keyExp.Bytes()},
|
||||||
nc := &testNetmapClient{
|
},
|
||||||
contractAddress: util.Uint160{111},
|
}, nc.notaryInvokes, "invalid notary invokes")
|
||||||
}
|
require.True(t, proc.netmapSnapshot.lastAccess[key1Str].removeFlag, "invalid expired removed flag")
|
||||||
proc, err := newTestProc(t,
|
require.False(t, proc.netmapSnapshot.lastAccess[key2Str].removeFlag, "invalid non expired removed flag")
|
||||||
func(p *Params) {
|
|
||||||
p.NetmapClient = nc
|
|
||||||
p.CleanupEnabled = true
|
|
||||||
},
|
|
||||||
)
|
|
||||||
|
|
||||||
require.NoError(t, err, "failed to create processor")
|
|
||||||
|
|
||||||
key1Str := "038c862959e56b43e20f79187c4fe9e0bc7c8c66c1603e6cf0ec7f87ab6b08dc35"
|
|
||||||
proc.netmapSnapshot.lastAccess[key1Str] = epochStampWithNodeInfo{
|
|
||||||
epochStamp: epochStamp{
|
|
||||||
epoch: 95,
|
|
||||||
removeFlag: false,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
key2Str := "02ac920cd7df0b61b289072e6b946e2da4e1a31b9ab1c621bb475e30fa4ab102c3"
|
|
||||||
proc.netmapSnapshot.lastAccess[key2Str] = epochStampWithNodeInfo{
|
|
||||||
epochStamp: epochStamp{
|
|
||||||
epoch: 98,
|
|
||||||
removeFlag: false,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
ev := netmapCleanupTick{
|
|
||||||
epoch: 100,
|
|
||||||
txHash: util.Uint256{123},
|
|
||||||
}
|
|
||||||
|
|
||||||
proc.handleCleanupTick(ev)
|
|
||||||
|
|
||||||
for proc.pool.Running() > 0 {
|
|
||||||
time.Sleep(10 * time.Millisecond)
|
|
||||||
}
|
|
||||||
|
|
||||||
keyExp, err := keys.NewPublicKeyFromString(key1Str)
|
|
||||||
require.NoError(t, err, "failed to parse expired key")
|
|
||||||
|
|
||||||
updExp := netmapclient.UpdatePeerPrm{}
|
|
||||||
updExp.SetKey(keyExp.Bytes())
|
|
||||||
updExp.SetHash(ev.TxHash())
|
|
||||||
|
|
||||||
require.EqualValues(t, []notaryInvoke{
|
|
||||||
{
|
|
||||||
contract: nc.contractAddress,
|
|
||||||
fee: 0,
|
|
||||||
nonce: uint32(ev.epoch),
|
|
||||||
vub: nil,
|
|
||||||
method: "updateStateIR",
|
|
||||||
args: []any{int64(v2netmap.Offline), keyExp.Bytes()},
|
|
||||||
},
|
|
||||||
}, nc.notaryInvokes, "invalid notary invokes")
|
|
||||||
require.True(t, proc.netmapSnapshot.lastAccess[key1Str].removeFlag, "invalid expired removed flag")
|
|
||||||
require.False(t, proc.netmapSnapshot.lastAccess[key2Str].removeFlag, "invalid non expired removed flag")
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func newTestProc(t *testing.T, nonDefault func(p *Params)) (*Processor, error) {
|
func newTestProc(t *testing.T, nonDefault func(p *Params)) (*Processor, error) {
|
||||||
|
@ -407,7 +268,6 @@ func newTestProc(t *testing.T, nonDefault func(p *Params)) (*Processor, error) {
|
||||||
PoolSize: 1,
|
PoolSize: 1,
|
||||||
CleanupEnabled: false,
|
CleanupEnabled: false,
|
||||||
CleanupThreshold: 3,
|
CleanupThreshold: 3,
|
||||||
NotaryDisabled: false,
|
|
||||||
NodeStateSettings: ns,
|
NodeStateSettings: ns,
|
||||||
NodeValidator: &testValidator{},
|
NodeValidator: &testValidator{},
|
||||||
EpochState: es,
|
EpochState: es,
|
||||||
|
@ -500,17 +360,11 @@ type testNetmapClient struct {
|
||||||
netmap *netmap.NetMap
|
netmap *netmap.NetMap
|
||||||
txHeights map[util.Uint256]uint32
|
txHeights map[util.Uint256]uint32
|
||||||
|
|
||||||
peerStateUpdates []netmapclient.UpdatePeerPrm
|
notaryInvokes []notaryInvoke
|
||||||
notaryInvokes []notaryInvoke
|
newEpochs []uint64
|
||||||
newEpochs []uint64
|
invokedTxs []*transaction.Transaction
|
||||||
addPeers []netmapclient.AddPeerPrm
|
|
||||||
invokedTxs []*transaction.Transaction
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *testNetmapClient) UpdatePeerState(p netmapclient.UpdatePeerPrm) error {
|
|
||||||
c.peerStateUpdates = append(c.peerStateUpdates, p)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
func (c *testNetmapClient) MorphNotaryInvoke(contract util.Uint160, fee fixedn.Fixed8, nonce uint32, vub *uint32, method string, args ...any) error {
|
func (c *testNetmapClient) MorphNotaryInvoke(contract util.Uint160, fee fixedn.Fixed8, nonce uint32, vub *uint32, method string, args ...any) error {
|
||||||
c.notaryInvokes = append(c.notaryInvokes, notaryInvoke{
|
c.notaryInvokes = append(c.notaryInvokes, notaryInvoke{
|
||||||
contract: contract,
|
contract: contract,
|
||||||
|
@ -522,32 +376,35 @@ func (c *testNetmapClient) MorphNotaryInvoke(contract util.Uint160, fee fixedn.F
|
||||||
})
|
})
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *testNetmapClient) ContractAddress() util.Uint160 {
|
func (c *testNetmapClient) ContractAddress() util.Uint160 {
|
||||||
return c.contractAddress
|
return c.contractAddress
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *testNetmapClient) EpochDuration() (uint64, error) {
|
func (c *testNetmapClient) EpochDuration() (uint64, error) {
|
||||||
return c.epochDuration, nil
|
return c.epochDuration, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *testNetmapClient) MorphTxHeight(h util.Uint256) (uint32, error) {
|
func (c *testNetmapClient) MorphTxHeight(h util.Uint256) (uint32, error) {
|
||||||
if res, found := c.txHeights[h]; found {
|
if res, found := c.txHeights[h]; found {
|
||||||
return res, nil
|
return res, nil
|
||||||
}
|
}
|
||||||
return 0, fmt.Errorf("not found")
|
return 0, fmt.Errorf("not found")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *testNetmapClient) NetMap() (*netmap.NetMap, error) {
|
func (c *testNetmapClient) NetMap() (*netmap.NetMap, error) {
|
||||||
return c.netmap, nil
|
return c.netmap, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *testNetmapClient) NewEpoch(epoch uint64, force bool) error {
|
func (c *testNetmapClient) NewEpoch(epoch uint64, force bool) error {
|
||||||
c.newEpochs = append(c.newEpochs, epoch)
|
c.newEpochs = append(c.newEpochs, epoch)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *testNetmapClient) MorphIsValidScript(script []byte, signers []transaction.Signer) (valid bool, err error) {
|
func (c *testNetmapClient) MorphIsValidScript(script []byte, signers []transaction.Signer) (valid bool, err error) {
|
||||||
return true, nil
|
return true, nil
|
||||||
}
|
}
|
||||||
func (c *testNetmapClient) AddPeer(p netmapclient.AddPeerPrm) error {
|
|
||||||
c.addPeers = append(c.addPeers, p)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
func (c *testNetmapClient) MorphNotarySignAndInvokeTX(mainTx *transaction.Transaction) error {
|
func (c *testNetmapClient) MorphNotarySignAndInvokeTX(mainTx *transaction.Transaction) error {
|
||||||
c.invokedTxs = append(c.invokedTxs, mainTx)
|
c.invokedTxs = append(c.invokedTxs, mainTx)
|
||||||
return nil
|
return nil
|
||||||
|
|
|
@ -3,7 +3,6 @@ package netmap
|
||||||
import (
|
import (
|
||||||
v2netmap "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/netmap"
|
v2netmap "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/netmap"
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-node/internal/logs"
|
"git.frostfs.info/TrueCloudLab/frostfs-node/internal/logs"
|
||||||
netmapclient "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/morph/client/netmap"
|
|
||||||
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
|
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
|
||||||
"go.uber.org/zap"
|
"go.uber.org/zap"
|
||||||
)
|
)
|
||||||
|
@ -31,23 +30,14 @@ func (np *Processor) processNetmapCleanupTick(ev netmapCleanupTick) {
|
||||||
// See https://github.com/nspcc-dev/frostfs-contract/issues/225
|
// See https://github.com/nspcc-dev/frostfs-contract/issues/225
|
||||||
const methodUpdateStateNotary = "updateStateIR"
|
const methodUpdateStateNotary = "updateStateIR"
|
||||||
|
|
||||||
if np.notaryDisabled {
|
err = np.netmapClient.MorphNotaryInvoke(
|
||||||
prm := netmapclient.UpdatePeerPrm{}
|
np.netmapClient.ContractAddress(),
|
||||||
|
0,
|
||||||
prm.SetKey(key.Bytes())
|
uint32(ev.epoch),
|
||||||
prm.SetHash(ev.TxHash())
|
nil,
|
||||||
|
methodUpdateStateNotary,
|
||||||
err = np.netmapClient.UpdatePeerState(prm)
|
int64(v2netmap.Offline), key.Bytes(),
|
||||||
} else {
|
)
|
||||||
err = np.netmapClient.MorphNotaryInvoke(
|
|
||||||
np.netmapClient.ContractAddress(),
|
|
||||||
0,
|
|
||||||
uint32(ev.epoch),
|
|
||||||
nil,
|
|
||||||
methodUpdateStateNotary,
|
|
||||||
int64(v2netmap.Offline), key.Bytes(),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
np.log.Error(logs.NetmapCantInvokeNetmapUpdateState, zap.Error(err))
|
np.log.Error(logs.NetmapCantInvokeNetmapUpdateState, zap.Error(err))
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,16 +19,14 @@ func (np *Processor) processAddPeer(ev netmapEvent.AddPeer) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// check if notary transaction is valid, see #976
|
// check if notary transaction is valid, see #976
|
||||||
if originalRequest := ev.NotaryRequest(); originalRequest != nil {
|
tx := ev.NotaryRequest().MainTransaction
|
||||||
tx := originalRequest.MainTransaction
|
ok, err := np.netmapClient.MorphIsValidScript(tx.Script, tx.Signers)
|
||||||
ok, err := np.netmapClient.MorphIsValidScript(tx.Script, tx.Signers)
|
if err != nil || !ok {
|
||||||
if err != nil || !ok {
|
np.log.Warn(logs.NetmapNonhaltNotaryTransaction,
|
||||||
np.log.Warn(logs.NetmapNonhaltNotaryTransaction,
|
zap.String("method", "netmap.AddPeer"),
|
||||||
zap.String("method", "netmap.AddPeer"),
|
zap.String("hash", tx.Hash().StringLE()),
|
||||||
zap.String("hash", tx.Hash().StringLE()),
|
zap.Error(err))
|
||||||
zap.Error(err))
|
return
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// unmarshal node info
|
// unmarshal node info
|
||||||
|
@ -40,7 +38,7 @@ func (np *Processor) processAddPeer(ev netmapEvent.AddPeer) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// validate and update node info
|
// validate and update node info
|
||||||
err := np.nodeValidator.VerifyAndUpdate(&nodeInfo)
|
err = np.nodeValidator.VerifyAndUpdate(&nodeInfo)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
np.log.Warn(logs.NetmapCouldNotVerifyAndUpdateInformationAboutNetworkMapCandidate,
|
np.log.Warn(logs.NetmapCouldNotVerifyAndUpdateInformationAboutNetworkMapCandidate,
|
||||||
zap.String("error", err.Error()),
|
zap.String("error", err.Error()),
|
||||||
|
@ -71,20 +69,15 @@ func (np *Processor) processAddPeer(ev netmapEvent.AddPeer) {
|
||||||
// See https://github.com/nspcc-dev/frostfs-contract/issues/154.
|
// See https://github.com/nspcc-dev/frostfs-contract/issues/154.
|
||||||
const methodAddPeerNotary = "addPeerIR"
|
const methodAddPeerNotary = "addPeerIR"
|
||||||
|
|
||||||
if nr := ev.NotaryRequest(); nr != nil {
|
// create new notary request with the original nonce
|
||||||
// create new notary request with the original nonce
|
err = np.netmapClient.MorphNotaryInvoke(
|
||||||
err = np.netmapClient.MorphNotaryInvoke(
|
np.netmapClient.ContractAddress(),
|
||||||
np.netmapClient.ContractAddress(),
|
0,
|
||||||
0,
|
ev.NotaryRequest().MainTransaction.Nonce,
|
||||||
nr.MainTransaction.Nonce,
|
nil,
|
||||||
nil,
|
methodAddPeerNotary,
|
||||||
methodAddPeerNotary,
|
nodeInfoBinary,
|
||||||
nodeInfoBinary,
|
)
|
||||||
)
|
|
||||||
} else {
|
|
||||||
// notification event case
|
|
||||||
err = np.netmapClient.AddPeer(prm)
|
|
||||||
}
|
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
np.log.Error(logs.NetmapCantInvokeNetmapAddPeer, zap.Error(err))
|
np.log.Error(logs.NetmapCantInvokeNetmapAddPeer, zap.Error(err))
|
||||||
|
@ -116,23 +109,7 @@ func (np *Processor) processUpdatePeer(ev netmapEvent.UpdatePeer) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if nr := ev.NotaryRequest(); nr != nil {
|
if err = np.netmapClient.MorphNotarySignAndInvokeTX(ev.NotaryRequest().MainTransaction); err != nil {
|
||||||
err = np.netmapClient.MorphNotarySignAndInvokeTX(nr.MainTransaction)
|
|
||||||
} else {
|
|
||||||
prm := netmapclient.UpdatePeerPrm{}
|
|
||||||
|
|
||||||
switch {
|
|
||||||
case ev.Online():
|
|
||||||
prm.SetOnline()
|
|
||||||
case ev.Maintenance():
|
|
||||||
prm.SetMaintenance()
|
|
||||||
}
|
|
||||||
|
|
||||||
prm.SetKey(ev.PublicKey().Bytes())
|
|
||||||
|
|
||||||
err = np.netmapClient.UpdatePeerState(prm)
|
|
||||||
}
|
|
||||||
if err != nil {
|
|
||||||
np.log.Error(logs.NetmapCantInvokeNetmapUpdatePeer, zap.Error(err))
|
np.log.Error(logs.NetmapCantInvokeNetmapUpdatePeer, zap.Error(err))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,6 @@ import (
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-node/internal/logs"
|
"git.frostfs.info/TrueCloudLab/frostfs-node/internal/logs"
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/innerring/processors/netmap/nodevalidation/state"
|
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/innerring/processors/netmap/nodevalidation/state"
|
||||||
cntClient "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/morph/client/container"
|
cntClient "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/morph/client/container"
|
||||||
netmapclient "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/morph/client/netmap"
|
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/morph/event"
|
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/morph/event"
|
||||||
netmapEvent "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/morph/event/netmap"
|
netmapEvent "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/morph/event/netmap"
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/util/logger"
|
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/util/logger"
|
||||||
|
@ -55,7 +54,6 @@ type (
|
||||||
}
|
}
|
||||||
|
|
||||||
Client interface {
|
Client interface {
|
||||||
UpdatePeerState(p netmapclient.UpdatePeerPrm) error
|
|
||||||
MorphNotaryInvoke(contract util.Uint160, fee fixedn.Fixed8, nonce uint32, vub *uint32, method string, args ...any) error
|
MorphNotaryInvoke(contract util.Uint160, fee fixedn.Fixed8, nonce uint32, vub *uint32, method string, args ...any) error
|
||||||
ContractAddress() util.Uint160
|
ContractAddress() util.Uint160
|
||||||
EpochDuration() (uint64, error)
|
EpochDuration() (uint64, error)
|
||||||
|
@ -63,7 +61,6 @@ type (
|
||||||
NetMap() (*netmap.NetMap, error)
|
NetMap() (*netmap.NetMap, error)
|
||||||
NewEpoch(epoch uint64, force bool) error
|
NewEpoch(epoch uint64, force bool) error
|
||||||
MorphIsValidScript(script []byte, signers []transaction.Signer) (valid bool, err error)
|
MorphIsValidScript(script []byte, signers []transaction.Signer) (valid bool, err error)
|
||||||
AddPeer(p netmapclient.AddPeerPrm) error
|
|
||||||
MorphNotarySignAndInvokeTX(mainTx *transaction.Transaction) error
|
MorphNotarySignAndInvokeTX(mainTx *transaction.Transaction) error
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -90,8 +87,6 @@ type (
|
||||||
|
|
||||||
nodeValidator NodeValidator
|
nodeValidator NodeValidator
|
||||||
|
|
||||||
notaryDisabled bool
|
|
||||||
|
|
||||||
nodeStateSettings state.NetworkSettings
|
nodeStateSettings state.NetworkSettings
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -112,8 +107,6 @@ type (
|
||||||
|
|
||||||
NodeValidator NodeValidator
|
NodeValidator NodeValidator
|
||||||
|
|
||||||
NotaryDisabled bool
|
|
||||||
|
|
||||||
NodeStateSettings state.NetworkSettings
|
NodeStateSettings state.NetworkSettings
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
@ -168,8 +161,6 @@ func New(p *Params) (*Processor, error) {
|
||||||
|
|
||||||
nodeValidator: p.NodeValidator,
|
nodeValidator: p.NodeValidator,
|
||||||
|
|
||||||
notaryDisabled: p.NotaryDisabled,
|
|
||||||
|
|
||||||
nodeStateSettings: p.NodeStateSettings,
|
nodeStateSettings: p.NodeStateSettings,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -56,10 +56,6 @@ func NewFromMorph(cli *client.Client, contract util.Uint160, fee fixedn.Fixed8,
|
||||||
opts[i](o)
|
opts[i](o)
|
||||||
}
|
}
|
||||||
|
|
||||||
if o.feePutNamedSet {
|
|
||||||
o.staticOpts = append(o.staticOpts, client.WithCustomFee(putNamedMethod, o.feePutNamed))
|
|
||||||
}
|
|
||||||
|
|
||||||
sc, err := client.NewStatic(cli, contract, fee, o.staticOpts...)
|
sc, err := client.NewStatic(cli, contract, fee, o.staticOpts...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("can't create container static client: %w", err)
|
return nil, fmt.Errorf("can't create container static client: %w", err)
|
||||||
|
@ -83,9 +79,6 @@ func (c Client) ContractAddress() util.Uint160 {
|
||||||
type Option func(*opts)
|
type Option func(*opts)
|
||||||
|
|
||||||
type opts struct {
|
type opts struct {
|
||||||
feePutNamedSet bool
|
|
||||||
feePutNamed fixedn.Fixed8
|
|
||||||
|
|
||||||
staticOpts []client.StaticClientOption
|
staticOpts []client.StaticClientOption
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -111,11 +104,3 @@ func AsAlphabet() Option {
|
||||||
o.staticOpts = append(o.staticOpts, client.AsAlphabet())
|
o.staticOpts = append(o.staticOpts, client.AsAlphabet())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// WithCustomFeeForNamedPut returns option to specify custom fee for each Put operation with named container.
|
|
||||||
func WithCustomFeeForNamedPut(fee fixedn.Fixed8) Option {
|
|
||||||
return func(o *opts) {
|
|
||||||
o.feePutNamed = fee
|
|
||||||
o.feePutNamedSet = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,35 +0,0 @@
|
||||||
package client
|
|
||||||
|
|
||||||
import "github.com/nspcc-dev/neo-go/pkg/encoding/fixedn"
|
|
||||||
|
|
||||||
// setFeeForMethod sets fee for the operation executed using specified contract method.
|
|
||||||
func (x *fees) setFeeForMethod(method string, fee fixedn.Fixed8) {
|
|
||||||
if x.customFees == nil {
|
|
||||||
x.customFees = make(map[string]fixedn.Fixed8, 1)
|
|
||||||
}
|
|
||||||
|
|
||||||
x.customFees[method] = fee
|
|
||||||
}
|
|
||||||
|
|
||||||
// fees represents source of per-operation fees.
|
|
||||||
// Can be initialized using var declaration.
|
|
||||||
//
|
|
||||||
// Instances are not thread-safe, so they mean initially filling, and then only reading.
|
|
||||||
type fees struct {
|
|
||||||
defaultFee fixedn.Fixed8
|
|
||||||
|
|
||||||
// customFees represents source of customized per-operation fees.
|
|
||||||
customFees map[string]fixedn.Fixed8
|
|
||||||
}
|
|
||||||
|
|
||||||
// returns fee for the operation executed using specified contract method.
|
|
||||||
// Returns customized value if it is set. Otherwise, returns default value.
|
|
||||||
func (x fees) feeForMethod(method string) fixedn.Fixed8 {
|
|
||||||
if x.customFees != nil {
|
|
||||||
if fee, ok := x.customFees[method]; ok {
|
|
||||||
return fee
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return x.defaultFee
|
|
||||||
}
|
|
|
@ -1,32 +0,0 @@
|
||||||
package client
|
|
||||||
|
|
||||||
import (
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/nspcc-dev/neo-go/pkg/encoding/fixedn"
|
|
||||||
"github.com/stretchr/testify/require"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestFees(t *testing.T) {
|
|
||||||
var v fees
|
|
||||||
|
|
||||||
const method = "some method"
|
|
||||||
|
|
||||||
var (
|
|
||||||
fee fixedn.Fixed8
|
|
||||||
def = fixedn.Fixed8(13)
|
|
||||||
)
|
|
||||||
|
|
||||||
v.defaultFee = def
|
|
||||||
|
|
||||||
fee = v.feeForMethod(method)
|
|
||||||
require.True(t, fee.Equal(def))
|
|
||||||
|
|
||||||
const customFee = fixedn.Fixed8(10)
|
|
||||||
|
|
||||||
v.setFeeForMethod(method, customFee)
|
|
||||||
|
|
||||||
fee = v.feeForMethod(method)
|
|
||||||
|
|
||||||
require.Equal(t, customFee, fee)
|
|
||||||
}
|
|
|
@ -27,7 +27,7 @@ type staticOpts struct {
|
||||||
tryNotary bool
|
tryNotary bool
|
||||||
alpha bool // use client's key to sign notary request's main TX
|
alpha bool // use client's key to sign notary request's main TX
|
||||||
|
|
||||||
fees fees
|
fee fixedn.Fixed8
|
||||||
}
|
}
|
||||||
|
|
||||||
// WithNotary returns notary status of the client.
|
// WithNotary returns notary status of the client.
|
||||||
|
@ -63,7 +63,7 @@ func NewStatic(client *Client, scriptHash util.Uint160, fee fixedn.Fixed8, opts
|
||||||
scScriptHash: scriptHash,
|
scScriptHash: scriptHash,
|
||||||
}
|
}
|
||||||
|
|
||||||
c.fees.defaultFee = fee
|
c.fee = fee
|
||||||
|
|
||||||
for i := range opts {
|
for i := range opts {
|
||||||
opts[i](&c.staticOpts)
|
opts[i](&c.staticOpts)
|
||||||
|
@ -125,8 +125,6 @@ func (i *InvokePrmOptional) SetControlTX(b bool) {
|
||||||
// If fee for the operation executed using specified method is customized, then StaticClient uses it.
|
// If fee for the operation executed using specified method is customized, then StaticClient uses it.
|
||||||
// Otherwise, default fee is used.
|
// Otherwise, default fee is used.
|
||||||
func (s StaticClient) Invoke(prm InvokePrm) error {
|
func (s StaticClient) Invoke(prm InvokePrm) error {
|
||||||
fee := s.fees.feeForMethod(prm.method)
|
|
||||||
|
|
||||||
if s.tryNotary {
|
if s.tryNotary {
|
||||||
if s.alpha {
|
if s.alpha {
|
||||||
var (
|
var (
|
||||||
|
@ -149,15 +147,15 @@ func (s StaticClient) Invoke(prm InvokePrm) error {
|
||||||
vubP = &vub
|
vubP = &vub
|
||||||
}
|
}
|
||||||
|
|
||||||
return s.client.NotaryInvoke(s.scScriptHash, fee, nonce, vubP, prm.method, prm.args...)
|
return s.client.NotaryInvoke(s.scScriptHash, s.fee, nonce, vubP, prm.method, prm.args...)
|
||||||
}
|
}
|
||||||
|
|
||||||
return s.client.NotaryInvokeNotAlpha(s.scScriptHash, fee, prm.method, prm.args...)
|
return s.client.NotaryInvokeNotAlpha(s.scScriptHash, s.fee, prm.method, prm.args...)
|
||||||
}
|
}
|
||||||
|
|
||||||
return s.client.Invoke(
|
return s.client.Invoke(
|
||||||
s.scScriptHash,
|
s.scScriptHash,
|
||||||
fee,
|
s.fee,
|
||||||
prm.method,
|
prm.method,
|
||||||
prm.args...,
|
prm.args...,
|
||||||
)
|
)
|
||||||
|
@ -211,11 +209,3 @@ func AsAlphabet() StaticClientOption {
|
||||||
o.alpha = true
|
o.alpha = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// WithCustomFee returns option to specify custom fee for the operation executed using
|
|
||||||
// specified contract method.
|
|
||||||
func WithCustomFee(method string, fee fixedn.Fixed8) StaticClientOption {
|
|
||||||
return func(o *staticOpts) {
|
|
||||||
o.fees.setFeeForMethod(method, fee)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue