/ node / bft / ledger-service / src / translucent.rs
translucent.rs
  1  // Copyright (c) 2025 ADnet Contributors
  2  // This file is part of the AlphaOS library.
  3  
  4  // Licensed under the Apache License, Version 2.0 (the "License");
  5  // you may not use this file except in compliance with the License.
  6  // You may obtain a copy of the License at:
  7  
  8  // http://www.apache.org/licenses/LICENSE-2.0
  9  
 10  // Unless required by applicable law or agreed to in writing, software
 11  // distributed under the License is distributed on an "AS IS" BASIS,
 12  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 13  // See the License for the specific language governing permissions and
 14  // limitations under the License.
 15  
 16  use crate::{CoreLedgerService, LedgerService};
 17  
 18  use alphaos_utilities::Stoppable;
 19  
 20  use alphavm::{
 21      ledger::{
 22          Block,
 23          Ledger,
 24          PendingBlock,
 25          Transaction,
 26          committee::Committee,
 27          narwhal::{Data, Subdag, Transmission, TransmissionID},
 28          puzzle::{Solution, SolutionID},
 29          store::ConsensusStorage,
 30      },
 31      prelude::{Address, ConsensusVersion, Field, Network, Result, narwhal::BatchCertificate},
 32  };
 33  
 34  use async_trait::async_trait;
 35  use indexmap::IndexMap;
 36  use std::{fmt, ops::Range, sync::Arc};
 37  
 38  pub struct TranslucentLedgerService<N: Network, C: ConsensusStorage<N>> {
 39      inner: CoreLedgerService<N, C>,
 40  }
 41  
 42  impl<N: Network, C: ConsensusStorage<N>> fmt::Debug for TranslucentLedgerService<N, C> {
 43      /// Implements a custom `fmt::Debug` for `TranslucentLedgerService`.
 44      fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
 45          f.debug_struct("TranslucentLedgerService").field("inner", &self.inner).finish()
 46      }
 47  }
 48  
 49  impl<N: Network, C: ConsensusStorage<N>> TranslucentLedgerService<N, C> {
 50      /// Initializes a new ledger service wrapper.
 51      pub fn new(ledger: Ledger<N, C>, stoppable: Arc<dyn Stoppable>) -> Self {
 52          Self { inner: CoreLedgerService::new(ledger, stoppable) }
 53      }
 54  }
 55  
 56  #[async_trait]
 57  impl<N: Network, C: ConsensusStorage<N>> LedgerService<N> for TranslucentLedgerService<N, C> {
 58      /// Returns the latest round in the ledger.
 59      fn latest_round(&self) -> u64 {
 60          self.inner.latest_round()
 61      }
 62  
 63      /// Returns the latest block height in the ledger.
 64      fn latest_block_height(&self) -> u32 {
 65          self.inner.latest_block_height()
 66      }
 67  
 68      /// Returns the latest block in the ledger.
 69      fn latest_block(&self) -> Block<N> {
 70          self.inner.latest_block()
 71      }
 72  
 73      /// Returns the latest restrictions ID in the ledger.
 74      fn latest_restrictions_id(&self) -> Field<N> {
 75          self.inner.latest_restrictions_id()
 76      }
 77  
 78      /// Returns the latest cached leader and its associated round.
 79      fn latest_leader(&self) -> Option<(u64, Address<N>)> {
 80          self.inner.latest_leader()
 81      }
 82  
 83      /// Updates the latest cached leader and its associated round.
 84      fn update_latest_leader(&self, round: u64, leader: Address<N>) {
 85          self.inner.update_latest_leader(round, leader);
 86      }
 87  
 88      /// Returns `true` if the given block height exists in the ledger.
 89      fn contains_block_height(&self, height: u32) -> bool {
 90          self.inner.contains_block_height(height)
 91      }
 92  
 93      /// Returns the block height for the given block hash, if it exists.
 94      fn get_block_height(&self, hash: &N::BlockHash) -> Result<u32> {
 95          self.inner.get_block_height(hash)
 96      }
 97  
 98      /// Returns the block hash for the given block height, if it exists.
 99      fn get_block_hash(&self, height: u32) -> Result<N::BlockHash> {
100          self.inner.get_block_hash(height)
101      }
102  
103      /// Returns the block round for the given block height, if it exists.
104      fn get_block_round(&self, height: u32) -> Result<u64> {
105          self.inner.get_block_round(height)
106      }
107  
108      /// Returns the block for the given block height.
109      fn get_block(&self, height: u32) -> Result<Block<N>> {
110          self.inner.get_block(height)
111      }
112  
113      /// Returns the blocks in the given block range.
114      /// The range is inclusive of the start and exclusive of the end.
115      fn get_blocks(&self, heights: Range<u32>) -> Result<Vec<Block<N>>> {
116          self.inner.get_blocks(heights)
117      }
118  
119      /// Returns the solution for the given solution ID.
120      fn get_solution(&self, solution_id: &SolutionID<N>) -> Result<Solution<N>> {
121          self.inner.get_solution(solution_id)
122      }
123  
124      /// Returns the unconfirmed transaction for the given transaction ID.
125      fn get_unconfirmed_transaction(&self, transaction_id: N::TransactionID) -> Result<Transaction<N>> {
126          self.inner.get_unconfirmed_transaction(transaction_id)
127      }
128  
129      /// Returns the batch certificate for the given batch certificate ID.
130      fn get_batch_certificate(&self, certificate_id: &Field<N>) -> Result<BatchCertificate<N>> {
131          self.inner.get_batch_certificate(certificate_id)
132      }
133  
134      /// Returns the current committee.
135      fn current_committee(&self) -> Result<Committee<N>> {
136          self.inner.current_committee()
137      }
138  
139      /// Returns the committee for the given round.
140      fn get_committee_for_round(&self, round: u64) -> Result<Committee<N>> {
141          self.inner.get_committee_for_round(round)
142      }
143  
144      /// Returns the committee lookback for the given round.
145      fn get_committee_lookback_for_round(&self, round: u64) -> Result<Committee<N>> {
146          self.inner.get_committee_lookback_for_round(round)
147      }
148  
149      /// Returns `true` if the ledger contains the given certificate ID in block history.
150      fn contains_certificate(&self, certificate_id: &Field<N>) -> Result<bool> {
151          self.inner.contains_certificate(certificate_id)
152      }
153  
154      /// Returns `true` if the transmission exists in the ledger.
155      fn contains_transmission(&self, transmission_id: &TransmissionID<N>) -> Result<bool> {
156          self.inner.contains_transmission(transmission_id)
157      }
158  
159      /// Always succeeds.
160      fn ensure_transmission_is_well_formed(
161          &self,
162          _transmission_id: TransmissionID<N>,
163          _transmission: &mut Transmission<N>,
164      ) -> Result<()> {
165          Ok(())
166      }
167  
168      /// Always succeeds.
169      async fn check_solution_basic(&self, _solution_id: SolutionID<N>, _solution: Data<Solution<N>>) -> Result<()> {
170          Ok(())
171      }
172  
173      /// Always succeeds.
174      async fn check_transaction_basic(
175          &self,
176          _transaction_id: N::TransactionID,
177          _transaction: Transaction<N>,
178      ) -> Result<()> {
179          Ok(())
180      }
181  
182      fn check_block_subdag(&self, _block: Block<N>, _prefix: &[PendingBlock<N>]) -> Result<PendingBlock<N>> {
183          unimplemented!();
184      }
185  
186      fn check_block_content(&self, _block: PendingBlock<N>) -> Result<Block<N>> {
187          unimplemented!();
188      }
189  
190      /// Always succeeds.
191      fn check_next_block(&self, _block: &Block<N>) -> Result<()> {
192          Ok(())
193      }
194  
195      /// Returns a candidate for the next block in the ledger, using a committed subdag and its transmissions.
196      fn prepare_advance_to_next_quorum_block(
197          &self,
198          subdag: Subdag<N>,
199          transmissions: IndexMap<TransmissionID<N>, Transmission<N>>,
200      ) -> Result<Block<N>> {
201          self.inner.prepare_advance_to_next_quorum_block(subdag, transmissions)
202      }
203  
204      /// Adds the given block as the next block in the ledger.
205      fn advance_to_next_block(&self, block: &Block<N>) -> Result<()> {
206          self.inner.advance_to_next_block(block)
207      }
208  
209      /// Returns the spent cost for a transaction in microcredits.
210      fn transaction_spend_in_microcredits(
211          &self,
212          transaction: &Transaction<N>,
213          consensus_version: ConsensusVersion,
214      ) -> Result<u64> {
215          self.inner.transaction_spend_in_microcredits(transaction, consensus_version)
216      }
217  }