Revise MorphRuleChainStorage interface and introduce ContractStorageReader #54

Merged
fyrchik merged 2 commits from aarifullin/policy-engine:feat/contract_storage_reader into master 2024-03-01 08:05:26 +00:00
4 changed files with 69 additions and 7 deletions

View file

@ -6,18 +6,18 @@ import (
) )
type defaultChainRouter struct { type defaultChainRouter struct {
morph MorphRuleChainStorage morph MorphRuleChainStorageReader
local LocalOverrideStorage local LocalOverrideStorage
} }
func NewDefaultChainRouter(morph MorphRuleChainStorage) ChainRouter { func NewDefaultChainRouter(morph MorphRuleChainStorageReader) ChainRouter {
return &defaultChainRouter{ return &defaultChainRouter{
morph: morph, morph: morph,
} }
} }
func NewDefaultChainRouterWithLocalOverrides(morph MorphRuleChainStorage, local LocalOverrideStorage) ChainRouter { func NewDefaultChainRouterWithLocalOverrides(morph MorphRuleChainStorageReader, local LocalOverrideStorage) ChainRouter {
return &defaultChainRouter{ return &defaultChainRouter{
morph: morph, morph: morph,
local: local, local: local,

View file

@ -52,3 +52,11 @@ func (s *inmemoryMorphRuleChainStorage) ListMorphRuleChains(name chain.Name, tar
} }
return nil, engine.ErrUnknownTarget 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")
}

View file

@ -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. // Basically, this implies that the storage manages rules stored in policy contract.
type MorphRuleChainStorage interface { type MorphRuleChainStorage interface {
MorphRuleChainStorageReader
// AddMorphRuleChain adds a chain rule to the policy contract and returns transaction hash, VUB and error. // 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) 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 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) RemoveMorphRuleChain(name chain.Name, target Target, chainID chain.ID) (util.Uint256, uint32, error)
// ListMorphRuleChains just lists deserialized chains. SetAdmin(addr util.Uint160) (util.Uint256, uint32, error)
ListMorphRuleChains(name chain.Name, target Target) ([]*chain.Chain, error)
} }
// Engine is the interface that provides methods to check request permissions checking // Engine is the interface that provides methods to check request permissions checking

View file

@ -22,13 +22,20 @@ var (
ErrEngineTargetTypeUnsupported = errors.New("this target type is not supported yet") 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 { type ContractStorage struct {
contractInterface *client.Contract contractInterface *client.Contract
} }
var _ engine.MorphRuleChainStorage = (*ContractStorage)(nil) 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 { func NewContractStorage(actor client.Actor, contract util.Uint160) *ContractStorage {
return &ContractStorage{ return &ContractStorage{
contractInterface: client.New(actor, contract), 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) 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) { func bytesFromStackItem(param stackitem.Item) ([]byte, error) {
switch param.Type() { switch param.Type() {
case stackitem.BufferT, stackitem.ByteArrayT, stackitem.IntegerT: case stackitem.BufferT, stackitem.ByteArrayT, stackitem.IntegerT: