From 76c9f10af8db39c5d0704f88eacc554008507fe0 Mon Sep 17 00:00:00 2001 From: aarifullin Date: Mon, 26 Feb 2024 18:19:37 +0300 Subject: [PATCH 1/2] [#54] morph: Revise MorphRuleChainStorage interface * Split MorphRuleChainStorage interface by moving read-only methods to a separate interface MorphRuleChainStorageReader. Signed-off-by: Airat Arifullin --- pkg/engine/inmemory/morph_storage.go | 8 ++++++++ pkg/engine/interface.go | 16 +++++++++++++--- 2 files changed, 21 insertions(+), 3 deletions(-) diff --git a/pkg/engine/inmemory/morph_storage.go b/pkg/engine/inmemory/morph_storage.go index 72b5439..ea31136 100644 --- a/pkg/engine/inmemory/morph_storage.go +++ b/pkg/engine/inmemory/morph_storage.go @@ -52,3 +52,11 @@ func (s *inmemoryMorphRuleChainStorage) ListMorphRuleChains(name chain.Name, tar } return nil, engine.ErrUnknownTarget } + +func (s *inmemoryMorphRuleChainStorage) GetAdmin() (util.Uint160, error) { + panic("not implemented") +} + +func (s *inmemoryMorphRuleChainStorage) SetAdmin(_ util.Uint160) (util.Uint256, uint32, error) { + panic("not implemented") +} diff --git a/pkg/engine/interface.go b/pkg/engine/interface.go index 66afff1..fa38737 100644 --- a/pkg/engine/interface.go +++ b/pkg/engine/interface.go @@ -93,17 +93,27 @@ func ContainerTarget(container string) Target { } } -// MorphRuleChainStorage is the interface to manage chains from the chain storage. +// MorphRuleChainStorageReader is the interface that provides read-only methods to receive +// data like chains, target or admin from a chain storage. +type MorphRuleChainStorageReader interface { + // ListMorphRuleChains just lists deserialized chains. + ListMorphRuleChains(name chain.Name, target Target) ([]*chain.Chain, error) + + GetAdmin() (util.Uint160, error) +} + +// MorphRuleChainStorage is the interface to read and manage data within a chain storage. // Basically, this implies that the storage manages rules stored in policy contract. type MorphRuleChainStorage interface { + MorphRuleChainStorageReader + // AddMorphRuleChain adds a chain rule to the policy contract and returns transaction hash, VUB and error. AddMorphRuleChain(name chain.Name, target Target, c *chain.Chain) (util.Uint256, uint32, error) // RemoveMorphRuleChain removes a chain rule to the policy contract and returns transaction hash, VUB and error. RemoveMorphRuleChain(name chain.Name, target Target, chainID chain.ID) (util.Uint256, uint32, error) - // ListMorphRuleChains just lists deserialized chains. - ListMorphRuleChains(name chain.Name, target Target) ([]*chain.Chain, error) + SetAdmin(addr util.Uint160) (util.Uint256, uint32, error) } // Engine is the interface that provides methods to check request permissions checking -- 2.45.2 From 4154899cff47cf3a3fcb3a441d85806c894b74dc Mon Sep 17 00:00:00 2001 From: aarifullin Date: Mon, 26 Feb 2024 18:30:31 +0300 Subject: [PATCH 2/2] [#54] morph: Introduce ContractStorageReader * Implement MorphRuleChainStorageReader interface to make possible to read from Policy contract without wallets. Signed-off-by: Airat Arifullin --- pkg/engine/chain_router.go | 6 +-- pkg/morph/policy/policy_contract_storage.go | 46 ++++++++++++++++++++- 2 files changed, 48 insertions(+), 4 deletions(-) diff --git a/pkg/engine/chain_router.go b/pkg/engine/chain_router.go index 93775b8..830919f 100644 --- a/pkg/engine/chain_router.go +++ b/pkg/engine/chain_router.go @@ -6,18 +6,18 @@ import ( ) type defaultChainRouter struct { - morph MorphRuleChainStorage + morph MorphRuleChainStorageReader local LocalOverrideStorage } -func NewDefaultChainRouter(morph MorphRuleChainStorage) ChainRouter { +func NewDefaultChainRouter(morph MorphRuleChainStorageReader) ChainRouter { return &defaultChainRouter{ morph: morph, } } -func NewDefaultChainRouterWithLocalOverrides(morph MorphRuleChainStorage, local LocalOverrideStorage) ChainRouter { +func NewDefaultChainRouterWithLocalOverrides(morph MorphRuleChainStorageReader, local LocalOverrideStorage) ChainRouter { return &defaultChainRouter{ morph: morph, local: local, diff --git a/pkg/morph/policy/policy_contract_storage.go b/pkg/morph/policy/policy_contract_storage.go index 2eaa099..8dbda8b 100644 --- a/pkg/morph/policy/policy_contract_storage.go +++ b/pkg/morph/policy/policy_contract_storage.go @@ -22,13 +22,20 @@ var ( ErrEngineTargetTypeUnsupported = errors.New("this target type is not supported yet") ) -// ContractStorage is the interface to manage chain rules within the policy contract. +// ContractStorage is the interface to manage chain rules within Policy contract. type ContractStorage struct { contractInterface *client.Contract } var _ engine.MorphRuleChainStorage = (*ContractStorage)(nil) +// ContractStorageReader is the interface to read data from Policy contract. +type ContractStorageReader struct { + contractReaderInterface *client.ContractReader +} + +var _ engine.MorphRuleChainStorageReader = (*ContractStorageReader)(nil) + func NewContractStorage(actor client.Actor, contract util.Uint160) *ContractStorage { return &ContractStorage{ contractInterface: client.New(actor, contract), @@ -112,6 +119,43 @@ func (s *ContractStorage) SetAdmin(addr util.Uint160) (util.Uint256, uint32, err return s.contractInterface.SetAdmin(addr) } +func NewContractStorageReader(inv client.Invoker, contract util.Uint160) *ContractStorageReader { + return &ContractStorageReader{ + contractReaderInterface: client.NewReader(inv, contract), + } +} + +func (s *ContractStorageReader) ListMorphRuleChains(name chain.Name, target engine.Target) ([]*chain.Chain, error) { + kind, err := policyKind(target.Type) + if err != nil { + return nil, err + } + + items, err := s.contractReaderInterface.ListChainsByPrefix(big.NewInt(int64(kind)), target.Name, []byte(name)) + if err != nil { + return nil, err + } + + var chains []*chain.Chain + for _, item := range items { + serialized, err := bytesFromStackItem(item) + if err != nil { + return nil, err + } + c := new(chain.Chain) + if err := c.DecodeBytes(serialized); err != nil { + return nil, err + } + chains = append(chains, c) + } + + return chains, nil +} + +func (s *ContractStorageReader) GetAdmin() (util.Uint160, error) { + return s.contractReaderInterface.GetAdmin() +} + func bytesFromStackItem(param stackitem.Item) ([]byte, error) { switch param.Type() { case stackitem.BufferT, stackitem.ByteArrayT, stackitem.IntegerT: -- 2.45.2