rgbstd/persistence/
stash.rs

1// RGB standard library for working with smart contracts on Bitcoin & Lightning
2//
3// SPDX-License-Identifier: Apache-2.0
4//
5// Written in 2019-2023 by
6//     Dr Maxim Orlovsky <orlovsky@lnp-bp.org>
7//
8// Copyright (C) 2019-2023 LNP/BP Standards Association. All rights reserved.
9//
10// Licensed under the Apache License, Version 2.0 (the "License");
11// you may not use this file except in compliance with the License.
12// You may obtain a copy of the License at
13//
14//     http://www.apache.org/licenses/LICENSE-2.0
15//
16// Unless required by applicable law or agreed to in writing, software
17// distributed under the License is distributed on an "AS IS" BASIS,
18// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
19// See the License for the specific language governing permissions and
20// limitations under the License.
21
22//use crate::containers::{Consignment, Contract, Transfer};
23
24use std::collections::{BTreeMap, BTreeSet};
25use std::error::Error;
26
27use amplify::confinement::TinyOrdSet;
28use commit_verify::mpc;
29use rgb::{
30    Anchor, AnchorId, BundleId, ContractId, Extension, Genesis, OpId, SchemaId, TransitionBundle,
31};
32use strict_encoding::TypeName;
33
34use crate::interface::{ContractSuppl, Iface, IfaceId, SchemaIfaces};
35
36#[derive(Debug, Display, Error, From)]
37#[display(inner)]
38pub enum StashError<E: Error> {
39    /// Connectivity errors which may be recoverable and temporary.
40    Connectivity(E),
41
42    /// Permanent errors caused by bugs in the business logic of this library.
43    /// Must be reported to LNP/BP Standards Association.
44    #[from]
45    InternalInconsistency(StashInconsistency),
46}
47
48#[derive(Debug, Display, Error, From)]
49#[display(doc_comments)]
50pub enum StashInconsistency {
51    /// interfae {0} is unknown; you need to import it first.
52    IfaceNameAbsent(TypeName),
53
54    /// interfae {0} is unknown; you need to import it first.
55    IfaceAbsent(IfaceId),
56
57    /// contract {0} is unknown. Probably you haven't imported the contract yet.
58    ContractAbsent(ContractId),
59
60    /// schema {0} is unknown.
61    ///
62    /// It may happen due to RGB standard library bug, or indicate internal
63    /// stash inconsistency and compromised stash data storage.
64    SchemaAbsent(SchemaId),
65
66    /// interface {0::<0} is not implemented for the schema {1::<0}.
67    IfaceImplAbsent(IfaceId, SchemaId),
68
69    /// transition {0} is absent.
70    ///
71    /// It may happen due to RGB standard library bug, or indicate internal
72    /// stash inconsistency and compromised stash data storage.
73    OperationAbsent(OpId),
74
75    /// anchor for txid {0} is absent.
76    ///
77    /// It may happen due to RGB standard library bug, or indicate internal
78    /// stash inconsistency and compromised stash data storage.
79    AnchorAbsent(AnchorId),
80
81    /// bundle {0} is absent.
82    ///
83    /// It may happen due to RGB standard library bug, or indicate internal
84    /// stash inconsistency and compromised stash data storage.
85    BundleAbsent(BundleId),
86}
87
88pub trait Stash {
89    /// Error type which must indicate problems on data retrieval.
90    type Error: Error;
91
92    fn schema_ids(&self) -> Result<BTreeSet<SchemaId>, Self::Error>;
93
94    fn ifaces(&self) -> Result<BTreeMap<IfaceId, TypeName>, Self::Error>;
95
96    fn iface_by_name(&self, name: &TypeName) -> Result<&Iface, StashError<Self::Error>>;
97
98    fn iface_by_id(&self, id: IfaceId) -> Result<&Iface, StashError<Self::Error>>;
99
100    fn schema(&self, schema_id: SchemaId) -> Result<&SchemaIfaces, StashError<Self::Error>>;
101
102    fn contract_ids(&self) -> Result<BTreeSet<ContractId>, Self::Error>;
103
104    fn contract_ids_by_iface(&self, name: &TypeName) -> Result<BTreeSet<ContractId>, Self::Error>;
105
106    fn contract_schema(
107        &self,
108        contract_id: ContractId,
109    ) -> Result<&SchemaIfaces, StashError<Self::Error>> {
110        let genesis = self.genesis(contract_id)?;
111        self.schema(genesis.schema_id)
112    }
113
114    fn contract_suppl(&self, contract_id: ContractId) -> Option<&TinyOrdSet<ContractSuppl>>;
115
116    fn genesis(&self, contract_id: ContractId) -> Result<&Genesis, StashError<Self::Error>>;
117
118    fn bundle_ids(&self) -> Result<BTreeSet<BundleId>, Self::Error>;
119
120    fn bundle(&self, bundle_id: BundleId) -> Result<&TransitionBundle, StashError<Self::Error>>;
121
122    fn extension_ids(&self) -> Result<BTreeSet<OpId>, Self::Error>;
123
124    fn extension(&self, op_id: OpId) -> Result<&Extension, StashError<Self::Error>>;
125
126    fn anchor_ids(&self) -> Result<BTreeSet<AnchorId>, Self::Error>;
127
128    fn anchor(
129        &self,
130        anchor_id: AnchorId,
131    ) -> Result<&Anchor<mpc::MerkleBlock>, StashError<Self::Error>>;
132}