data_anchor_blober/
lib.rs1#![doc = include_str!("../README.md")]
2#![allow(unexpected_cfgs)]
3pub mod constants;
6pub mod error;
7pub mod instructions;
8pub mod state;
9#[cfg(test)]
10mod tests;
11
12use anchor_lang::{
13 prelude::*,
14 solana_program::hash::{self, HASH_BYTES},
15};
16pub use constants::*;
17pub use instructions::*;
18pub use state::*;
19
20declare_id!("anchorE4RzhiFx3TEFep6yRNK9igZBzMVWziqjbGHp2");
21
22#[program]
23pub mod blober {
24 use super::*;
25
26 pub fn initialize(ctx: Context<Initialize>, namespace: String, trusted: Pubkey) -> Result<()> {
27 initialize_handler(ctx, namespace, trusted)
28 }
29
30 pub fn declare_blob(ctx: Context<DeclareBlob>, timestamp: u64, blob_size: u32) -> Result<()> {
31 declare_blob_handler(ctx, timestamp, blob_size)
32 }
33
34 pub fn insert_chunk(ctx: Context<InsertChunk>, idx: u16, data: Vec<u8>) -> Result<()> {
35 insert_chunk_handler(ctx, idx, data)
36 }
37
38 pub fn finalize_blob(ctx: Context<FinalizeBlob>) -> Result<()> {
39 finalize_blob_handler(ctx)
40 }
41
42 pub fn discard_blob(ctx: Context<DiscardBlob>) -> Result<()> {
43 discard_blob_handler(ctx)
44 }
45
46 pub fn close(ctx: Context<Close>) -> Result<()> {
47 close_handler(ctx)
48 }
49
50 pub fn configure_checkpoint(
51 ctx: Context<ConfigureCheckpoint>,
52 authority: Pubkey,
53 ) -> Result<()> {
54 configure_checkpoint_handler(ctx, authority)
55 }
56
57 pub fn create_checkpoint(
58 ctx: Context<CreateCheckpoint>,
59 blober: Pubkey,
60 proof: [u8; GROTH16_PROOF_SIZE],
61 public_values: Vec<u8>,
62 verification_key: String,
63 slot: u64,
64 ) -> Result<()> {
65 create_checkpoint_handler(ctx, blober, proof, public_values, verification_key, slot)
66 }
67}
68
69pub fn hash_leaf(
71 previous_hash: [u8; HASH_BYTES],
72 chunk_index: u16,
73 chunk_data: &[u8],
74) -> [u8; HASH_BYTES] {
75 hash::hashv(&[&previous_hash, &chunk_index.to_le_bytes(), chunk_data]).to_bytes()
76}
77
78pub fn compute_blob_digest<A: AsRef<[u8]>>(chunks: &[(u16, A)]) -> [u8; HASH_BYTES] {
80 chunks
81 .iter()
82 .fold(initial_hash(), |hash, (chunk_index, chunk_data)| {
83 hash_leaf(hash, *chunk_index, chunk_data.as_ref())
84 })
85}
86
87pub fn find_blob_address(
89 program_id: Pubkey,
90 payer: Pubkey,
91 blober: Pubkey,
92 timestamp: u64,
93 blob_size: usize,
94) -> Pubkey {
95 Pubkey::find_program_address(
96 &[
97 SEED,
98 payer.as_ref(),
99 blober.as_ref(),
100 timestamp.to_le_bytes().as_ref(),
101 (blob_size as u32).to_le_bytes().as_ref(),
102 ],
103 &program_id,
104 )
105 .0
106}
107
108pub fn find_blober_address(program_id: Pubkey, payer: Pubkey, namespace: &str) -> Pubkey {
110 Pubkey::find_program_address(&[SEED, payer.as_ref(), namespace.as_bytes()], &program_id).0
111}
112
113pub fn find_checkpoint_address(program_id: Pubkey, blober: Pubkey) -> Pubkey {
115 Pubkey::find_program_address(&[SEED, CHECKPOINT_SEED, blober.as_ref()], &program_id).0
116}
117
118pub fn find_checkpoint_config_address(program_id: Pubkey, blober: Pubkey) -> Pubkey {
120 Pubkey::find_program_address(
121 &[
122 SEED,
123 CHECKPOINT_SEED,
124 CHECKPOINT_CONFIG_SEED,
125 blober.as_ref(),
126 ],
127 &program_id,
128 )
129 .0
130}
131
132pub fn find_checkpoint_signer_address(program_id: Pubkey, blober: Pubkey) -> Pubkey {
135 Pubkey::find_program_address(
136 &[
137 SEED,
138 CHECKPOINT_SEED,
139 CHECKPOINT_PDA_SIGNER_SEED,
140 blober.as_ref(),
141 ],
142 &program_id,
143 )
144 .0
145}
146
147pub fn hash_blob(key: &Pubkey, data: &[u8]) -> [u8; HASH_BYTES] {
149 hash::hashv(&[key.as_ref(), data]).to_bytes()
150}
151
152pub fn merge_hashes(current: &[u8; HASH_BYTES], new: &[u8; HASH_BYTES]) -> [u8; HASH_BYTES] {
155 hash::hashv(&[current, new]).to_bytes()
156}