Await tx in ape_manager.AddChain/RemoveChain #1587
6 changed files with 57 additions and 41 deletions
|
@ -19,6 +19,7 @@ func initAPEManagerService(c *cfg) {
|
||||||
c.cfgObject.cfgAccessPolicyEngine.policyContractHash)
|
c.cfgObject.cfgAccessPolicyEngine.policyContractHash)
|
||||||
|
|
||||||
execsvc := apemanager.New(c.cfgObject.cnrSource, contractStorage,
|
execsvc := apemanager.New(c.cfgObject.cnrSource, contractStorage,
|
||||||
|
c.cfgMorph.client,
|
||||||
apemanager.WithLogger(c.log))
|
apemanager.WithLogger(c.log))
|
||||||
sigsvc := apemanager.NewSignService(&c.key.PrivateKey, execsvc)
|
sigsvc := apemanager.NewSignService(&c.key.PrivateKey, execsvc)
|
||||||
auditSvc := apemanager.NewAuditService(sigsvc, c.log, c.audit)
|
auditSvc := apemanager.NewAuditService(sigsvc, c.log, c.audit)
|
||||||
|
|
|
@ -151,7 +151,7 @@ func makeNotaryDeposit(ctx context.Context, c *cfg) (util.Uint256, uint32, error
|
||||||
}
|
}
|
||||||
|
|
||||||
func waitNotaryDeposit(ctx context.Context, c *cfg, tx util.Uint256, vub uint32) error {
|
func waitNotaryDeposit(ctx context.Context, c *cfg, tx util.Uint256, vub uint32) error {
|
||||||
if err := c.cfgMorph.client.WaitTxHalt(ctx, client.InvokeRes{Hash: tx, VUB: vub}); err != nil {
|
if err := c.cfgMorph.client.WaitTxHalt(ctx, vub, tx); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -423,7 +423,7 @@ func (c *cfg) updateNetMapState(ctx context.Context, stateSetter func(*nmClient.
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return c.cfgNetmap.wrapper.Morph().WaitTxHalt(ctx, res)
|
return c.cfgNetmap.wrapper.Morph().WaitTxHalt(ctx, res.VUB, res.Hash)
|
||||||
}
|
}
|
||||||
|
|
||||||
type netInfo struct {
|
type netInfo struct {
|
||||||
|
|
|
@ -31,9 +31,7 @@ type RPCActorProvider interface {
|
||||||
type ProxyVerificationContractStorage struct {
|
type ProxyVerificationContractStorage struct {
|
||||||
rpcActorProvider RPCActorProvider
|
rpcActorProvider RPCActorProvider
|
||||||
|
|
||||||
acc *wallet.Account
|
cosigners []actor.SignerAccount
|
||||||
|
|
||||||
proxyScriptHash util.Uint160
|
|
||||||
|
|
||||||
policyScriptHash util.Uint160
|
policyScriptHash util.Uint160
|
||||||
}
|
}
|
||||||
|
@ -41,12 +39,27 @@ type ProxyVerificationContractStorage struct {
|
||||||
var _ ProxyAdaptedContractStorage = (*ProxyVerificationContractStorage)(nil)
|
var _ ProxyAdaptedContractStorage = (*ProxyVerificationContractStorage)(nil)
|
||||||
|
|
||||||
func NewProxyVerificationContractStorage(rpcActorProvider RPCActorProvider, key *keys.PrivateKey, proxyScriptHash, policyScriptHash util.Uint160) *ProxyVerificationContractStorage {
|
func NewProxyVerificationContractStorage(rpcActorProvider RPCActorProvider, key *keys.PrivateKey, proxyScriptHash, policyScriptHash util.Uint160) *ProxyVerificationContractStorage {
|
||||||
|
acc := wallet.NewAccountFromPrivateKey(key)
|
||||||
return &ProxyVerificationContractStorage{
|
return &ProxyVerificationContractStorage{
|
||||||
rpcActorProvider: rpcActorProvider,
|
rpcActorProvider: rpcActorProvider,
|
||||||
|
|
||||||
acc: wallet.NewAccountFromPrivateKey(key),
|
cosigners: []actor.SignerAccount{
|
||||||
|
{
|
||||||
proxyScriptHash: proxyScriptHash,
|
Signer: transaction.Signer{
|
||||||
|
Account: proxyScriptHash,
|
||||||
|
Scopes: transaction.CustomContracts,
|
||||||
|
AllowedContracts: []util.Uint160{policyScriptHash},
|
||||||
|
},
|
||||||
|
Account: notary.FakeContractAccount(proxyScriptHash),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Signer: transaction.Signer{
|
||||||
|
Account: acc.Contract.ScriptHash(),
|
||||||
|
Scopes: transaction.CalledByEntry,
|
||||||
|
},
|
||||||
|
Account: acc,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
policyScriptHash: policyScriptHash,
|
policyScriptHash: policyScriptHash,
|
||||||
}
|
}
|
||||||
|
@ -64,7 +77,7 @@ func (n *contractStorageActorAdapter) GetRPCInvoker() invoker.RPCInvoke {
|
||||||
|
|
||||||
func (contractStorage *ProxyVerificationContractStorage) newContractStorageActor() (policy_morph.ContractStorageActor, error) {
|
func (contractStorage *ProxyVerificationContractStorage) newContractStorageActor() (policy_morph.ContractStorageActor, error) {
|
||||||
rpcActor := contractStorage.rpcActorProvider.GetRPCActor()
|
rpcActor := contractStorage.rpcActorProvider.GetRPCActor()
|
||||||
act, err := actor.New(rpcActor, cosigners(contractStorage.acc, contractStorage.proxyScriptHash, contractStorage.policyScriptHash))
|
act, err := actor.New(rpcActor, contractStorage.cosigners)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -98,31 +111,16 @@ func (contractStorage *ProxyVerificationContractStorage) RemoveMorphRuleChain(na
|
||||||
|
|
||||||
// ListMorphRuleChains lists morph rule chains from Policy contract using both Proxy contract and storage account as consigners.
|
// ListMorphRuleChains lists morph rule chains from Policy contract using both Proxy contract and storage account as consigners.
|
||||||
func (contractStorage *ProxyVerificationContractStorage) ListMorphRuleChains(name chain.Name, target engine.Target) ([]*chain.Chain, error) {
|
func (contractStorage *ProxyVerificationContractStorage) ListMorphRuleChains(name chain.Name, target engine.Target) ([]*chain.Chain, error) {
|
||||||
// contractStorageActor is reconstructed per each method invocation because RPCActor's (that is, basically, WSClient) connection may get invalidated, but
|
rpcActor := contractStorage.rpcActorProvider.GetRPCActor()
|
||||||
// ProxyVerificationContractStorage does not manage reconnections.
|
inv := &invokerAdapter{Invoker: invoker.New(rpcActor, nil), rpcInvoker: rpcActor}
|
||||||
contractStorageActor, err := contractStorage.newContractStorageActor()
|
return policy_morph.NewContractStorageReader(inv, contractStorage.policyScriptHash).ListMorphRuleChains(name, target)
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return policy_morph.NewContractStorage(contractStorageActor, contractStorage.policyScriptHash).ListMorphRuleChains(name, target)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func cosigners(acc *wallet.Account, proxyScriptHash, policyScriptHash util.Uint160) []actor.SignerAccount {
|
type invokerAdapter struct {
|
||||||
return []actor.SignerAccount{
|
*invoker.Invoker
|
||||||
{
|
rpcInvoker invoker.RPCInvoke
|
||||||
Signer: transaction.Signer{
|
}
|
||||||
Account: proxyScriptHash,
|
|
||||||
Scopes: transaction.CustomContracts,
|
func (n *invokerAdapter) GetRPCInvoker() invoker.RPCInvoke {
|
||||||
AllowedContracts: []util.Uint160{policyScriptHash},
|
return n.rpcInvoker
|
||||||
},
|
|
||||||
Account: notary.FakeContractAccount(proxyScriptHash),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Signer: transaction.Signer{
|
|
||||||
Account: acc.Contract.ScriptHash(),
|
|
||||||
Scopes: transaction.CalledByEntry,
|
|
||||||
},
|
|
||||||
Account: acc,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,13 +33,13 @@ func (w *waiterClient) GetVersion() (*result.Version, error) {
|
||||||
|
|
||||||
// WaitTxHalt waits until transaction with the specified hash persists on the blockchain.
|
// WaitTxHalt waits until transaction with the specified hash persists on the blockchain.
|
||||||
// It also checks execution result to finish in HALT state.
|
// It also checks execution result to finish in HALT state.
|
||||||
func (c *Client) WaitTxHalt(ctx context.Context, p InvokeRes) error {
|
func (c *Client) WaitTxHalt(ctx context.Context, vub uint32, h util.Uint256) error {
|
||||||
w, err := waiter.NewPollingBased(&waiterClient{c: c})
|
w, err := waiter.NewPollingBased(&waiterClient{c: c})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("create tx waiter: %w", err)
|
return fmt.Errorf("create tx waiter: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
res, err := w.WaitAny(ctx, p.VUB, p.Hash)
|
res, err := w.WaitAny(ctx, vub, h)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("wait until tx persists: %w", err)
|
return fmt.Errorf("wait until tx persists: %w", err)
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,6 +22,7 @@ import (
|
||||||
policy_engine "git.frostfs.info/TrueCloudLab/policy-engine/pkg/engine"
|
policy_engine "git.frostfs.info/TrueCloudLab/policy-engine/pkg/engine"
|
||||||
"github.com/mr-tron/base58/base58"
|
"github.com/mr-tron/base58/base58"
|
||||||
"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"
|
||||||
"go.uber.org/zap"
|
"go.uber.org/zap"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -34,6 +35,8 @@ type cfg struct {
|
||||||
type Service struct {
|
type Service struct {
|
||||||
cfg
|
cfg
|
||||||
|
|
||||||
|
waiter Waiter
|
||||||
|
|
||||||
cnrSrc containercore.Source
|
cnrSrc containercore.Source
|
||||||
|
|
||||||
contractStorage ape_contract.ProxyAdaptedContractStorage
|
contractStorage ape_contract.ProxyAdaptedContractStorage
|
||||||
|
@ -41,11 +44,17 @@ type Service struct {
|
||||||
|
|
||||||
type Option func(*cfg)
|
type Option func(*cfg)
|
||||||
|
|
||||||
func New(cnrSrc containercore.Source, contractStorage ape_contract.ProxyAdaptedContractStorage, opts ...Option) *Service {
|
type Waiter interface {
|
||||||
|
WaitTxHalt(context.Context, uint32, util.Uint256) error
|
||||||
|
}
|
||||||
|
|
||||||
|
func New(cnrSrc containercore.Source, contractStorage ape_contract.ProxyAdaptedContractStorage, waiter Waiter, opts ...Option) *Service {
|
||||||
s := &Service{
|
s := &Service{
|
||||||
cnrSrc: cnrSrc,
|
cnrSrc: cnrSrc,
|
||||||
|
|
||||||
contractStorage: contractStorage,
|
contractStorage: contractStorage,
|
||||||
|
|
||||||
|
waiter: waiter,
|
||||||
}
|
}
|
||||||
|
|
||||||
for i := range opts {
|
for i := range opts {
|
||||||
|
@ -84,7 +93,7 @@ func (s *Service) validateContainerTargetRequest(cid string, pubKey *keys.Public
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Service) AddChain(_ context.Context, req *apemanagerV2.AddChainRequest) (*apemanagerV2.AddChainResponse, error) {
|
func (s *Service) AddChain(ctx context.Context, req *apemanagerV2.AddChainRequest) (*apemanagerV2.AddChainResponse, error) {
|
||||||
pub, err := getSignaturePublicKey(req.GetVerificationHeader())
|
pub, err := getSignaturePublicKey(req.GetVerificationHeader())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -116,7 +125,11 @@ func (s *Service) AddChain(_ context.Context, req *apemanagerV2.AddChainRequest)
|
||||||
return nil, fmt.Errorf("unsupported target type: %s", targetType)
|
return nil, fmt.Errorf("unsupported target type: %s", targetType)
|
||||||
}
|
}
|
||||||
|
|
||||||
if _, _, err = s.contractStorage.AddMorphRuleChain(apechain.Ingress, target, &chain); err != nil {
|
txHash, vub, err := s.contractStorage.AddMorphRuleChain(apechain.Ingress, target, &chain)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if err := s.waiter.WaitTxHalt(ctx, vub, txHash); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -129,7 +142,7 @@ func (s *Service) AddChain(_ context.Context, req *apemanagerV2.AddChainRequest)
|
||||||
return resp, nil
|
return resp, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Service) RemoveChain(_ context.Context, req *apemanagerV2.RemoveChainRequest) (*apemanagerV2.RemoveChainResponse, error) {
|
func (s *Service) RemoveChain(ctx context.Context, req *apemanagerV2.RemoveChainRequest) (*apemanagerV2.RemoveChainResponse, error) {
|
||||||
pub, err := getSignaturePublicKey(req.GetVerificationHeader())
|
pub, err := getSignaturePublicKey(req.GetVerificationHeader())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -148,7 +161,11 @@ func (s *Service) RemoveChain(_ context.Context, req *apemanagerV2.RemoveChainRe
|
||||||
return nil, fmt.Errorf("unsupported target type: %s", targetType)
|
return nil, fmt.Errorf("unsupported target type: %s", targetType)
|
||||||
}
|
}
|
||||||
|
|
||||||
if _, _, err = s.contractStorage.RemoveMorphRuleChain(apechain.Ingress, target, req.GetBody().GetChainID()); err != nil {
|
txHash, vub, err := s.contractStorage.RemoveMorphRuleChain(apechain.Ingress, target, req.GetBody().GetChainID())
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if err := s.waiter.WaitTxHalt(ctx, vub, txHash); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue