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 }