fuel_core_interfaces/
db.rs1use crate::{
2 common::{
3 fuel_storage::Mappable,
4 fuel_tx::{
5 Receipt,
6 Transaction,
7 UtxoId,
8 },
9 fuel_types::{
10 Bytes32,
11 ContractId,
12 MessageId,
13 },
14 fuel_vm::prelude::InterpreterError,
15 },
16 model::{
17 Coin,
18 FuelBlockConsensus,
19 FuelBlockDb,
20 Message,
21 },
22};
23use std::io::ErrorKind;
24use thiserror::Error;
25
26pub use crate::common::fuel_vm::storage::{
27 ContractsAssets,
28 ContractsInfo,
29 ContractsRawCode,
30 ContractsState,
31};
32
33pub trait Transactional {
34 fn commit(self) -> Result<(), Error>;
36
37 fn commit_box(self: Box<Self>) -> Result<(), Error>;
41}
42
43pub trait DatabaseTransaction<Database>:
48 Transactional + core::fmt::Debug + Send + Sync
49{
50 fn database(&self) -> &Database;
54 fn database_mut(&mut self) -> &mut Database;
58}
59
60pub struct FuelBlocks;
63
64impl Mappable for FuelBlocks {
65 type Key = Bytes32;
67 type SetValue = FuelBlockDb;
68 type GetValue = Self::SetValue;
69}
70
71pub struct ContractsLatestUtxo;
75
76impl Mappable for ContractsLatestUtxo {
77 type Key = ContractId;
78 type SetValue = UtxoId;
80 type GetValue = Self::SetValue;
81}
82
83pub struct Receipts;
85
86impl Mappable for Receipts {
87 type Key = Bytes32;
89 type SetValue = [Receipt];
90 type GetValue = Vec<Receipt>;
91}
92
93pub struct SealedBlockConsensus;
95
96impl Mappable for SealedBlockConsensus {
97 type Key = Bytes32;
98 type SetValue = FuelBlockConsensus;
99 type GetValue = Self::SetValue;
100}
101
102pub struct Coins;
104
105impl Mappable for Coins {
106 type Key = UtxoId;
107 type SetValue = Coin;
108 type GetValue = Self::SetValue;
109}
110
111pub struct Messages;
113
114impl Mappable for Messages {
115 type Key = MessageId;
116 type SetValue = Message;
117 type GetValue = Self::SetValue;
118}
119
120pub struct Transactions;
122
123impl Mappable for Transactions {
124 type Key = Bytes32;
125 type SetValue = Transaction;
126 type GetValue = Self::SetValue;
127}
128
129#[derive(Error, Debug)]
133#[non_exhaustive]
134pub enum Error {
135 #[error("error performing binary serialization")]
136 Codec,
137 #[error("Failed to initialize chain")]
138 ChainAlreadyInitialized,
139 #[error("Chain is not yet initialized")]
140 ChainUninitialized,
141 #[error("Invalid database version")]
142 InvalidDatabaseVersion,
143 #[error("error occurred in the underlying datastore `{0}`")]
144 DatabaseError(Box<dyn std::error::Error + Send + Sync>),
145 #[error(transparent)]
146 Other(#[from] anyhow::Error),
147}
148
149impl From<Error> for std::io::Error {
150 fn from(e: Error) -> Self {
151 std::io::Error::new(ErrorKind::Other, e)
152 }
153}
154
155#[derive(Debug, Error)]
156pub enum KvStoreError {
157 #[error("generic error occurred")]
158 Error(Box<dyn std::error::Error + Send + Sync>),
159 #[error("resource of type `{0}` was not found at the: {1}")]
161 NotFound(&'static str, &'static str),
162}
163
164#[macro_export]
177macro_rules! not_found {
178 ($name: literal) => {
179 $crate::db::KvStoreError::NotFound($name, concat!(file!(), ":", line!()))
180 };
181 ($ty: path) => {
182 $crate::db::KvStoreError::NotFound(
183 ::core::any::type_name::<
184 <$ty as $crate::common::fuel_storage::Mappable>::GetValue,
185 >(),
186 concat!(file!(), ":", line!()),
187 )
188 };
189}
190
191impl From<Error> for KvStoreError {
192 fn from(e: Error) -> Self {
193 KvStoreError::Error(Box::new(e))
194 }
195}
196
197impl From<KvStoreError> for Error {
198 fn from(e: KvStoreError) -> Self {
199 Error::DatabaseError(Box::new(e))
200 }
201}
202
203impl From<KvStoreError> for std::io::Error {
204 fn from(e: KvStoreError) -> Self {
205 std::io::Error::new(ErrorKind::Other, e)
206 }
207}
208
209impl From<Error> for InterpreterError {
210 fn from(e: Error) -> Self {
211 InterpreterError::Io(std::io::Error::new(std::io::ErrorKind::Other, e))
212 }
213}
214
215impl From<KvStoreError> for InterpreterError {
216 fn from(e: KvStoreError) -> Self {
217 InterpreterError::Io(std::io::Error::new(std::io::ErrorKind::Other, e))
218 }
219}
220
221#[cfg(test)]
222mod test {
223 use super::*;
224
225 #[test]
226 fn not_found_output() {
227 #[rustfmt::skip]
228 assert_eq!(
229 format!("{}", not_found!("BlockId")),
230 format!("resource of type `BlockId` was not found at the: {}:{}", file!(), line!() - 1)
231 );
232 #[rustfmt::skip]
233 assert_eq!(
234 format!("{}", not_found!(Coins)),
235 format!("resource of type `fuel_core_interfaces::model::coin::Coin` was not found at the: {}:{}", file!(), line!() - 1)
236 );
237 }
238}