Merge pull request #510 from logos-blockchain/Pravdyvy/programs-elfs-deployments

Pravdyvy/programs elfs deployments
This commit is contained in:
Pravdyvy 2026-06-17 16:59:18 +03:00 committed by GitHub
commit 62d9ba10f8
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
19 changed files with 9238 additions and 472 deletions

View File

@ -59,6 +59,8 @@ allow-git = [
"https://github.com/EspressoSystems/jellyfish.git",
"https://github.com/logos-blockchain/logos-blockchain.git",
"https://github.com/logos-blockchain/logos-blockchain-circuits.git",
"https://github.com/logos-blockchain/logos-blockchain-rust-rapidsnark.git",
"https://github.com/arkworks-rs/spongefish.git"
]
unknown-git = "deny"
unknown-registry = "deny"

View File

@ -16,4 +16,4 @@ runs:
env:
GITHUB_TOKEN: ${{ inputs.github-token }}
run: |
curl -sSL https://raw.githubusercontent.com/logos-blockchain/logos-blockchain/6ac348bea4160ca708b70a86b3964e9f1ce82fff/scripts/setup-logos-blockchain-circuits.sh | bash
curl -sSL https://raw.githubusercontent.com/logos-blockchain/logos-blockchain/6ac348bea4160ca708b70a86b3964e9f1ce82fff/scripts/setup-logos-blockchain-circuits.sh | bash

View File

@ -87,10 +87,6 @@ jobs:
- uses: ./.github/actions/install-risc0
- uses: ./.github/actions/install-logos-blockchain-circuits
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
- name: Install active toolchain
run: rustup install
@ -122,10 +118,6 @@ jobs:
- uses: ./.github/actions/install-risc0
- uses: ./.github/actions/install-logos-blockchain-circuits
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
- name: Install active toolchain
run: rustup install
@ -157,10 +149,6 @@ jobs:
- uses: ./.github/actions/install-risc0
- uses: ./.github/actions/install-logos-blockchain-circuits
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
- name: Install active toolchain
run: rustup install
@ -221,10 +209,6 @@ jobs:
- uses: ./.github/actions/install-risc0
- uses: ./.github/actions/install-logos-blockchain-circuits
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
- name: Install active toolchain
run: rustup install
@ -254,10 +238,6 @@ jobs:
- uses: ./.github/actions/install-risc0
- uses: ./.github/actions/install-logos-blockchain-circuits
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
- name: Install active toolchain
run: rustup install

542
Cargo.lock generated

File diff suppressed because it is too large Load Diff

View File

@ -139,13 +139,13 @@ tokio-retry = "0.3.0"
schemars = "1.2"
async-stream = "0.3.6"
logos-blockchain-common-http-client = { git = "https://github.com/logos-blockchain/logos-blockchain.git", rev = "db9a8d821c1b20f29b03d02072817150cf969b8e" }
logos-blockchain-key-management-system-service = { git = "https://github.com/logos-blockchain/logos-blockchain.git", rev = "db9a8d821c1b20f29b03d02072817150cf969b8e" }
logos-blockchain-core = { git = "https://github.com/logos-blockchain/logos-blockchain.git", rev = "db9a8d821c1b20f29b03d02072817150cf969b8e" }
logos-blockchain-chain-broadcast-service = { git = "https://github.com/logos-blockchain/logos-blockchain.git", rev = "db9a8d821c1b20f29b03d02072817150cf969b8e" }
logos-blockchain-chain-service = { git = "https://github.com/logos-blockchain/logos-blockchain.git", rev = "db9a8d821c1b20f29b03d02072817150cf969b8e" }
logos-blockchain-zone-sdk = { git = "https://github.com/logos-blockchain/logos-blockchain.git", rev = "db9a8d821c1b20f29b03d02072817150cf969b8e" }
logos-blockchain-http-api-common = { git = "https://github.com/logos-blockchain/logos-blockchain.git", rev = "db9a8d821c1b20f29b03d02072817150cf969b8e" }
logos-blockchain-common-http-client = { git = "https://github.com/logos-blockchain/logos-blockchain.git", rev = "d8711bbc3d43d3ef9755ef9b73af32fd0f703160" }
logos-blockchain-key-management-system-service = { git = "https://github.com/logos-blockchain/logos-blockchain.git", rev = "d8711bbc3d43d3ef9755ef9b73af32fd0f703160" }
logos-blockchain-core = { git = "https://github.com/logos-blockchain/logos-blockchain.git", rev = "d8711bbc3d43d3ef9755ef9b73af32fd0f703160" }
logos-blockchain-chain-broadcast-service = { git = "https://github.com/logos-blockchain/logos-blockchain.git", rev = "d8711bbc3d43d3ef9755ef9b73af32fd0f703160" }
logos-blockchain-chain-service = { git = "https://github.com/logos-blockchain/logos-blockchain.git", rev = "d8711bbc3d43d3ef9755ef9b73af32fd0f703160" }
logos-blockchain-zone-sdk = { git = "https://github.com/logos-blockchain/logos-blockchain.git", rev = "d8711bbc3d43d3ef9755ef9b73af32fd0f703160" }
logos-blockchain-http-api-common = { git = "https://github.com/logos-blockchain/logos-blockchain.git", rev = "d8711bbc3d43d3ef9755ef9b73af32fd0f703160" }
rocksdb = { version = "0.24.0", default-features = false, features = [
"snappy",

View File

@ -147,8 +147,6 @@ The sequencer and logos blockchain node can be run locally:
1. On one terminal go to the `logos-blockchain/logos-blockchain` repo and run a local logos blockchain node:
- `git checkout master; git pull`
- `cargo clean`
- `rm -r ~/.logos-blockchain-circuits`
- `./scripts/setup-logos-blockchain-circuits.sh`
- `cargo build --all-features`
- `./target/debug/logos-blockchain-node --deployment nodes/node/standalone-deployment-config.yaml nodes/node/standalone-node-config.yaml`

View File

@ -8,7 +8,6 @@ blend:
scheduler:
cover:
message_frequency_per_round: 1.0
intervals_for_safety_buffer: 100
delayer:
maximum_release_delay_in_rounds: 3
minimum_messages_coefficient: 1
@ -31,10 +30,9 @@ cryptarchia:
sdp_config:
service_params:
BN:
lock_period: 10
inactivity_period: 1
retention_period: 1
timestamp: 0
epoch: 0
min_stake:
threshold: 1
timestamp: 0
@ -72,13 +70,10 @@ cryptarchia:
inscription: '0c000000000000006c6f676f732d6465766e65742c046269000000000000000000000000000000000000000000000000000000000000000000000000'
parent: '0000000000000000000000000000000000000000000000000000000000000000'
signer: '0000000000000000000000000000000000000000000000000000000000000000'
execution_gas_price: 0
storage_gas_price: 0
ops_proofs:
- !Ed25519Sig '00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000'
- !Ed25519Sig '00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000'
time:
slot_duration: '1.0'
chain_start_time: PLACEHOLDER_CHAIN_START_TIME
mempool:
pubsub_topic: mantle_e2e_tests

View File

@ -1,7 +1,7 @@
services:
logos-blockchain-node-0:
image: ghcr.io/logos-blockchain/logos-blockchain@sha256:f160cfbf898a06554451cc066d84cfd0f8ab62d59bd3e62d9cde3bd5582c12ab
image: ghcr.io/logos-blockchain/logos-blockchain@sha256:91d6c5bf07e07fcfba5e7cf07d21ee686a6bc4b9f6210f2d28bffbcad9a3729f
ports:
- "${PORT:-8080}:18080/tcp"
volumes:

8570
flake.lock generated

File diff suppressed because it is too large Load Diff

View File

@ -13,8 +13,14 @@
crane.url = "github:ipetkov/crane";
# Must stay in sync with the lbc-* tags in logos-blockchain/Cargo.lock.
logos-blockchain-circuits = {
url = "github:logos-blockchain/logos-blockchain-circuits";
url = "github:logos-blockchain/logos-blockchain-circuits/2846ee7a4cfa24458bb8063412ab2e753b344d2f";
};
# Must stay in sync with the rust-rapidsnark rev in Cargo.lock.
rust-rapidsnark = {
url = "github:logos-blockchain/logos-blockchain-rust-rapidsnark/e91187f8ccb5bbfc7bb00dac88169112428da78f";
};
};
@ -25,6 +31,7 @@
rust-overlay,
crane,
logos-blockchain-circuits,
rust-rapidsnark,
...
}:
let
@ -53,6 +60,7 @@
craneLib = (crane.mkLib pkgs).overrideToolchain rustToolchain;
src = ./.;
cargoLock = builtins.fromTOML (builtins.readFile ./Cargo.lock);
lbc_dir = logos-blockchain-circuits.packages.${system}.default;
# Parse Cargo.lock at eval time to find the locked risc0-circuit-recursion
# version and its crates.io checksum — no hardcoding required.
@ -99,8 +107,12 @@
pkgs.clang
pkgs.llvmPackages.libclang.lib
pkgs.gnutar # Required for crane's archive operations (macOS tar lacks --sort)
pkgs.python3 # Required for correct builds now, as python is sandboxed in nix builds
];
LIBCLANG_PATH = "${pkgs.llvmPackages.libclang.lib}/lib";
# Logos blockchain related env vars
LBC_ROOT_DIR = logos-blockchain-circuits.packages.${system}.default;
RAPIDSNARK_LIB_DIR = rust-rapidsnark.packages.${system}.rapidsnark;
# Point the risc0-circuit-recursion build script to the pre-fetched zip
# so it doesn't try to download it inside the sandbox.
RECURSION_SRC_PATH = "${recursionZkr}";
@ -114,7 +126,6 @@
'' + pkgs.lib.optionalString pkgs.stdenv.isDarwin ''
export PATH="$PATH:/usr/bin"
'';
LOGOS_BLOCKCHAIN_CIRCUITS = logos-blockchain-circuits.packages.${system}.default;
};
walletFfiPackage = craneLib.buildPackage (
@ -125,7 +136,7 @@
cargoExtraArgs = "-p wallet-ffi";
postInstall = ''
mkdir -p $out/include
cp wallet-ffi/wallet_ffi.h $out/include/
cp lez/wallet-ffi/wallet_ffi.h $out/include/
''
+ pkgs.lib.optionalString pkgs.stdenv.isDarwin ''
install_name_tool -id @rpath/libwallet_ffi.dylib $out/lib/libwallet_ffi.dylib
@ -141,7 +152,7 @@
cargoExtraArgs = "-p indexer_ffi";
postInstall = ''
mkdir -p $out/include
cp indexer/ffi/indexer_ffi.h $out/include/
cp lez/indexer/ffi/indexer_ffi.h $out/include/
''
+ pkgs.lib.optionalString pkgs.stdenv.isDarwin ''
install_name_tool -id @rpath/libindexer_ffi.dylib $out/lib/libindexer_ffi.dylib

View File

@ -37,9 +37,6 @@ RUN cp "$(which r0vm)" /usr/local/bin/r0vm
RUN test -x /usr/local/bin/r0vm
RUN r0vm --version
# Install logos blockchain circuits
RUN curl -sSL https://raw.githubusercontent.com/logos-blockchain/logos-blockchain/main/scripts/setup-logos-blockchain-circuits.sh | bash
WORKDIR /indexer_service
# Planner stage - generates dependency recipe
@ -83,9 +80,6 @@ COPY --from=builder --chown=indexer_service_user:indexer_service_user /usr/local
# Copy r0vm binary from builder
COPY --from=builder --chown=indexer_service_user:indexer_service_user /usr/local/bin/r0vm /usr/local/bin/r0vm
# Copy logos blockchain circuits from builder
COPY --from=builder --chown=indexer_service_user:indexer_service_user /root/.logos-blockchain-circuits /home/indexer_service_user/.logos-blockchain-circuits
VOLUME /var/lib/indexer_service
# Expose default port

View File

@ -36,6 +36,7 @@ hex.workspace = true
url.workspace = true
num-bigint.workspace = true
risc0-zkvm.workspace = true
futures.workspace = true
[features]
default = []

View File

@ -1,8 +1,9 @@
use std::{pin::Pin, sync::Arc, time::Duration};
use anyhow::{Context as _, Result};
use anyhow::{Context as _, Result, anyhow};
use common::block::Block;
use log::{info, warn};
pub use logos_blockchain_core::mantle::ops::channel::MsgId;
use logos_blockchain_core::mantle::ops::channel::inscribe::Inscription;
pub use logos_blockchain_key_management_system_service::keys::{Ed25519Key, ZkKey};
pub use logos_blockchain_zone_sdk::sequencer::SequencerCheckpoint;
@ -10,15 +11,19 @@ use logos_blockchain_zone_sdk::{
CommonHttpClient,
adapter::NodeHttpClient,
sequencer::{
Event, SequencerConfig as ZoneSdkSequencerConfig, SequencerHandle, WithdrawArg,
ZoneSequencer,
DepositInfo, Event, FinalizedOp, InscriptionInfo,
SequencerConfig as ZoneSdkSequencerConfig, WithdrawArg, WithdrawInfo, ZoneSequencer,
},
state::{DepositInfo, FinalizedOp, InscriptionInfo, WithdrawInfo},
};
use tokio::task::JoinHandle;
use tokio::{sync::mpsc, task::JoinHandle};
use crate::config::BedrockConfig;
/// Channel capacity for the publish inbox. One publish per produced block, drained
/// in microseconds by the drive task — 32 is huge headroom and just provides
/// backpressure if the drive task stalls (reconnect, long backfill).
const PUBLISH_INBOX_CAPACITY: usize = 32;
/// Sink for `Event::Published` checkpoints emitted by the drive task.
/// Caller is responsible for persistence (e.g. writing to rocksdb).
pub type CheckpointSink = Box<dyn Fn(SequencerCheckpoint) + Send + 'static>;
@ -61,7 +66,7 @@ pub trait BlockPublisherTrait: Clone {
/// Real block publisher backed by zone-sdk's `ZoneSequencer`.
#[derive(Clone)]
pub struct ZoneSdkPublisher {
handle: SequencerHandle<NodeHttpClient>,
publish_tx: mpsc::Sender<(Inscription, Vec<WithdrawArg>)>,
// Aborts the drive task when the last clone is dropped.
_drive_task: Arc<DriveTaskGuard>,
}
@ -93,7 +98,7 @@ impl BlockPublisherTrait for ZoneSdkPublisher {
..ZoneSdkSequencerConfig::default()
};
let (mut sequencer, mut handle) = ZoneSequencer::init_with_config(
let mut sequencer = ZoneSequencer::init_with_config(
config.channel_id,
bedrock_signing_key,
node,
@ -101,43 +106,93 @@ impl BlockPublisherTrait for ZoneSdkPublisher {
initial_checkpoint,
);
// Grab readiness receiver before moving the sequencer into the drive
// task so we can await cold-start completion below.
let mut ready_rx = sequencer.subscribe_ready();
let (publish_tx, mut publish_rx) =
mpsc::channel::<(Inscription, Vec<WithdrawArg>)>(PUBLISH_INBOX_CAPACITY);
let drive_task = tokio::spawn(async move {
loop {
let Some(event) = sequencer.next_event().await else {
continue;
};
match event {
Event::Checkpoint { checkpoint } => on_checkpoint(checkpoint),
Event::TxsFinalized { items } => {
for op in items.into_iter().flat_map(|item| item.ops) {
match op {
FinalizedOp::Inscription(inscription) => {
if let Some(block_id) = block_id_from_inscription(&inscription)
{
on_finalized_block(block_id);
#[expect(
clippy::integer_division_remainder_used,
reason = "tokio::select! expansion uses `%` for random branch selection"
)]
{
tokio::select! {
// Drain external publish requests by calling the
// borrowing handle — `&mut sequencer` is only
// available here.
Some((data_bounded, withdrawals)) = publish_rx.recv() => {
let data_byte_size = data_bounded.len();
if withdrawals.is_empty() {
if let Err(e) = sequencer.handle()
.publish(data_bounded)
.context("Failed to publish block") {
warn!("zone-sdk publish failed: {e:?}");
}
info!("Published block with the size of {data_byte_size} bytes");
} else {
let withdraw_count = withdrawals.len();
if let Err(e) = sequencer.handle()
.publish_atomic_withdraw(data_bounded, withdrawals)
.context("Failed to publish block with withdrawals") {
warn!("zone-sdk publish failed: {e:?}");
}
info!(
"Published block with the size of {data_byte_size} bytes and {withdraw_count} bridge withdrawals",
);
}
}
event = sequencer.next_event() => {
let Some(event) = event else {
continue;
};
match event {
Event::BlocksProcessed {
checkpoint,
channel_update: _,
finalized,
} => {
on_checkpoint(checkpoint);
for op in finalized.into_iter().flat_map(|item| item.ops) {
match op {
FinalizedOp::Inscription(inscription) => {
if let Some(block_id) =
block_id_from_inscription(&inscription)
{
on_finalized_block(block_id);
}
}
FinalizedOp::Deposit(deposit) => {
on_deposit_event(deposit).await;
}
FinalizedOp::Withdraw(withdraw) => {
on_withdraw_event(withdraw).await;
}
}
}
}
FinalizedOp::Deposit(deposit) => {
on_deposit_event(deposit).await;
}
FinalizedOp::Withdraw(withdraw) => {
on_withdraw_event(withdraw).await;
}
Event::Ready | Event::TurnNotification { .. } => {}
}
}
}
Event::ChannelUpdate { .. }
| Event::Published { .. }
| Event::Readiness { .. }
| Event::TurnNotification { .. } => {}
}
}
});
handle.wait_ready().await;
// Wait for cold-start backfill to complete before returning so callers
// can publish immediately (e.g. genesis block) without racing readiness.
ready_rx
.wait_for(|v| *v)
.await
.context("Zone-sdk readiness channel closed before becoming ready")?;
Ok(Self {
handle,
publish_tx,
_drive_task: Arc::new(DriveTaskGuard(drive_task)),
})
}
@ -147,28 +202,11 @@ impl BlockPublisherTrait for ZoneSdkPublisher {
let data_bounded: Inscription = data
.try_into()
.context("Block data exceeds maximum allowed size")?;
let data_byte_size = data_bounded.len();
if withdrawals.is_empty() {
self.handle
.publish_message(data_bounded)
.await
.context("Failed to publish block")?;
info!("Published block with the size of {data_byte_size} bytes");
return Ok(());
}
let withdraw_count = withdrawals.len();
self.handle
.publish_atomic_withdraw(data_bounded, withdrawals)
self.publish_tx
.send((data_bounded, withdrawals))
.await
.context("Failed to publish block with withdrawals")?;
info!(
"Published block with the size of {data_byte_size} bytes and {withdraw_count} bridge withdrawals",
);
.map_err(|_closed| anyhow!("Drive task is no longer running"))?;
Ok(())
}

View File

@ -12,7 +12,7 @@ use lee::{AccountId, PublicTransaction, program::Program, public_transaction::Me
use lee_core::GENESIS_BLOCK_ID;
use log::{error, info, warn};
use logos_blockchain_key_management_system_service::keys::{ED25519_SECRET_KEY_SIZE, Ed25519Key};
use logos_blockchain_zone_sdk::sequencer::WithdrawArg;
use logos_blockchain_zone_sdk::sequencer::{DepositInfo, WithdrawArg};
use mempool::{MemPool, MemPoolHandle};
#[cfg(feature = "mock")]
pub use mock::SequencerCoreWithMockClients;
@ -652,9 +652,7 @@ fn build_supply_bridge_account_genesis_transaction(balance: u128) -> PublicTrans
PublicTransaction::new(message, witness_set)
}
fn pending_deposit_event_record(
deposit: &logos_blockchain_zone_sdk::state::DepositInfo,
) -> PendingDepositEventRecord {
fn pending_deposit_event_record(deposit: &DepositInfo) -> PendingDepositEventRecord {
PendingDepositEventRecord {
deposit_op_id: HashType(deposit.op_id),
source_tx_hash: HashType(deposit.tx_hash.0),

View File

@ -37,9 +37,6 @@ RUN cp "$(which r0vm)" /usr/local/bin/r0vm
RUN test -x /usr/local/bin/r0vm
RUN r0vm --version
# Install logos blockchain circuits
RUN curl -sSL https://raw.githubusercontent.com/logos-blockchain/logos-blockchain/main/scripts/setup-logos-blockchain-circuits.sh | bash
WORKDIR /sequencer_service
# Build argument to enable standalone feature (defaults to false)
@ -95,9 +92,6 @@ COPY --from=builder --chown=sequencer_user:sequencer_user /usr/local/bin/sequenc
# Copy r0vm binary from builder
COPY --from=builder --chown=sequencer_user:sequencer_user /usr/local/bin/r0vm /usr/local/bin/r0vm
# Copy logos blockchain circuits from builder
COPY --from=builder --chown=sequencer_user:sequencer_user /root/.logos-blockchain-circuits /home/sequencer_user/.logos-blockchain-circuits
VOLUME /var/lib/sequencer_service
# Expose default port

View File

@ -15,6 +15,7 @@ wallet.workspace = true
lee.workspace = true
lee_core.workspace = true
sequencer_service_rpc = { workspace = true, features = ["client"] }
common.workspace = true
tokio.workspace = true
key_protocol.workspace = true

View File

@ -46,6 +46,7 @@ pub mod error;
pub mod generic_transaction;
pub mod keys;
pub mod pinata;
pub mod program_deployment;
pub mod sync;
pub mod transfer;
pub mod types;

View File

@ -0,0 +1,253 @@
use std::{ffi::CString, ptr, slice};
use common::transaction::LeeTransaction;
use lee::{program::Program, ProgramDeploymentTransaction};
use sequencer_service_rpc::RpcClient as _;
use crate::{
block_on,
error::{print_error, WalletFfiError},
generic_transaction::{FfiProgram, FfiTransactionResult},
wallet::get_wallet,
WalletHandle,
};
/// Send a program deployment transaction.
///
/// Publishes program for future use.
///
/// # Parameters
/// - `handle`: Valid wallet handle
/// - `elf_data`: Valid pointer to elf data in bytes
/// - `elf_size`: Size of elf data
/// - `out_result`: Output pointer for transfer result
///
/// # Returns
/// - `Success` if deployment was submitted successfully
/// - Error code on other failures
///
/// # Memory
/// The result must be freed with `wallet_ffi_free_transaction_result()`.
///
/// # Safety
/// - `handle` must be a valid wallet handle from `wallet_ffi_create_new` or `wallet_ffi_open`
/// - `elf_data` must be a valid pointer to elf data
/// - `out_result` must be a valid pointer to a `FfiTransferResult` struct
#[no_mangle]
pub unsafe extern "C" fn wallet_ffi_program_deployment(
handle: *mut WalletHandle,
elf_data: *const u8,
elf_size: usize,
out_result: *mut FfiTransactionResult,
) -> WalletFfiError {
let wrapper = match get_wallet(handle) {
Ok(w) => w,
Err(e) => return e,
};
if elf_data.is_null() || out_result.is_null() {
print_error("Null pointer argument");
return WalletFfiError::NullPointer;
}
let wallet = match wrapper.core.lock() {
Ok(w) => w,
Err(e) => {
print_error(format!("Failed to lock wallet: {e}"));
return WalletFfiError::InternalError;
}
};
let elf = unsafe { slice::from_raw_parts(elf_data, elf_size) }.to_vec();
let message = lee::program_deployment_transaction::Message::new(elf);
let transaction = ProgramDeploymentTransaction::new(message);
match block_on(
wallet
.sequencer_client
.send_transaction(LeeTransaction::ProgramDeployment(transaction)),
) {
Ok(tx_hash) => {
let tx_hash = CString::new(tx_hash.to_string())
.map_or(ptr::null_mut(), std::ffi::CString::into_raw);
unsafe {
(*out_result).tx_hash = tx_hash;
(*out_result).success = true;
}
WalletFfiError::Success
}
Err(e) => {
print_error(format!("Deployment failed: {e:?}"));
unsafe {
(*out_result).tx_hash = ptr::null_mut();
(*out_result).success = false;
}
WalletFfiError::NetworkError
}
}
}
/// Writes elf data of authenticated transfer program into buffer.
///
/// WARNING: Result is not consisent and change between versions, use for testing purposes only.
///
/// # Parameters
/// - `ffi_program`: Valid pointer to `FfiProgram`
///
/// # Returns
/// - `Success` if deployment was submitted successfully
/// - Error code on other failures
///
/// # Memory
/// - `FfiProgram` can be freed with corresponding `wallet_ffi_free_ffi_program` function
///
/// # Safety
/// - `ffi_program` must be a non-null pointer
#[no_mangle]
pub unsafe extern "C" fn wallet_ffi_transfer_elf(ffi_program: *mut FfiProgram) -> WalletFfiError {
if ffi_program.is_null() {
print_error("Null pointer argument");
return WalletFfiError::NullPointer;
}
let elf = Program::authenticated_transfer_program().elf().to_vec();
let (raw_elf_data, raw_elf_size, _) = elf.into_raw_parts();
unsafe {
(*ffi_program).elf_data = raw_elf_data;
(*ffi_program).elf_size = raw_elf_size;
};
WalletFfiError::Success
}
/// Writes elf data of authenticated token program into buffer.
///
/// WARNING: Result is not consisent and change between versions, use for testing purposes only.
///
/// # Parameters
/// - `ffi_program`: Valid pointer to `FfiProgram`
///
/// # Returns
/// - `Success` if deployment was submitted successfully
/// - Error code on other failures
///
/// # Memory
/// - `FfiProgram` can be freed with corresponding `wallet_ffi_free_ffi_program` function
///
/// # Safety
/// - `ffi_program` must be a non-null pointer
#[no_mangle]
pub unsafe extern "C" fn wallet_ffi_token_elf(ffi_program: *mut FfiProgram) -> WalletFfiError {
if ffi_program.is_null() {
print_error("Null pointer argument");
return WalletFfiError::NullPointer;
}
let elf = Program::token().elf().to_vec();
let (raw_elf_data, raw_elf_size, _) = elf.into_raw_parts();
unsafe {
(*ffi_program).elf_data = raw_elf_data;
(*ffi_program).elf_size = raw_elf_size;
};
WalletFfiError::Success
}
/// Writes elf data of amm into buffer.
///
/// WARNING: Result is not consisent and change between versions, use for testing purposes only.
///
/// # Parameters
/// - `ffi_program`: Valid pointer to `FfiProgram`
///
/// # Returns
/// - `Success` if deployment was submitted successfully
/// - Error code on other failures
///
/// # Memory
/// - `FfiProgram` can be freed with corresponding `wallet_ffi_free_ffi_program` function
///
/// # Safety
/// - `ffi_program` must be a non-null pointer
#[no_mangle]
pub unsafe extern "C" fn wallet_ffi_amm_elf(ffi_program: *mut FfiProgram) -> WalletFfiError {
if ffi_program.is_null() {
print_error("Null pointer argument");
return WalletFfiError::NullPointer;
}
let elf = Program::amm().elf().to_vec();
let (raw_elf_data, raw_elf_size, _) = elf.into_raw_parts();
unsafe {
(*ffi_program).elf_data = raw_elf_data;
(*ffi_program).elf_size = raw_elf_size;
};
WalletFfiError::Success
}
/// Writes elf data of ata into buffer.
///
/// WARNING: Result is not consisent and change between versions, use for testing purposes only.
///
/// # Parameters
/// - `ffi_program`: Valid pointer to `FfiProgram`
///
/// # Returns
/// - `Success` if deployment was submitted successfully
/// - Error code on other failures
///
/// # Memory
/// - `FfiProgram` can be freed with corresponding `wallet_ffi_free_ffi_program` function
///
/// # Safety
/// - `ffi_program` must be a non-null pointer
#[no_mangle]
pub unsafe extern "C" fn wallet_ffi_ata_elf(ffi_program: *mut FfiProgram) -> WalletFfiError {
if ffi_program.is_null() {
print_error("Null pointer argument");
return WalletFfiError::NullPointer;
}
let elf = Program::ata().elf().to_vec();
let (raw_elf_data, raw_elf_size, _) = elf.into_raw_parts();
unsafe {
(*ffi_program).elf_data = raw_elf_data;
(*ffi_program).elf_size = raw_elf_size;
};
WalletFfiError::Success
}
/// Free a ffi program returned by functions `wallet_ffi_*_elf`.
///
/// # Safety
/// The result must be either null or a valid result from a elf getter function.
#[no_mangle]
pub unsafe extern "C" fn wallet_ffi_free_ffi_program(ffi_program: *mut FfiProgram) {
if ffi_program.is_null() {
return;
}
unsafe {
let ffi_program = &*ffi_program;
if !ffi_program.elf_data.is_null() {
let elf = std::slice::from_raw_parts_mut(
ffi_program.elf_data.cast_mut(),
ffi_program.elf_size,
);
drop(Box::from_raw(std::ptr::from_mut::<[u8]>(elf)));
}
}
}

View File

@ -873,6 +873,122 @@ enum WalletFfiError wallet_ffi_claim_pinata_private_owned_not_initialized(struct
const uint8_t (*solution)[16],
struct FfiTransferResult *out_result);
/**
* Send a program deployment transaction.
*
* Publishes program for future use.
*
* # Parameters
* - `handle`: Valid wallet handle
* - `elf_data`: Valid pointer to elf data in bytes
* - `elf_size`: Size of elf data
* - `out_result`: Output pointer for transfer result
*
* # Returns
* - `Success` if deployment was submitted successfully
* - Error code on other failures
*
* # Memory
* The result must be freed with `wallet_ffi_free_transaction_result()`.
*
* # Safety
* - `handle` must be a valid wallet handle from `wallet_ffi_create_new` or `wallet_ffi_open`
* - `elf_data` must be a valid pointer to elf data
* - `out_result` must be a valid pointer to a `FfiTransferResult` struct
*/
enum WalletFfiError wallet_ffi_program_deployment(struct WalletHandle *handle,
const uint8_t *elf_data,
uintptr_t elf_size,
struct FfiTransactionResult *out_result);
/**
* Writes elf data of authenticated transfer program into buffer.
*
* WARNING: Result is not consisent and change between versions, use for testing purposes only.
*
* # Parameters
* - `ffi_program`: Valid pointer to `FfiProgram`
*
* # Returns
* - `Success` if deployment was submitted successfully
* - Error code on other failures
*
* # Memory
* - `FfiProgram` can be freed with corresponding `wallet_ffi_free_ffi_program` function
*
* # Safety
* - `ffi_program` must be a non-null pointer
*/
enum WalletFfiError wallet_ffi_transfer_elf(struct FfiProgram *ffi_program);
/**
* Writes elf data of authenticated token program into buffer.
*
* WARNING: Result is not consisent and change between versions, use for testing purposes only.
*
* # Parameters
* - `ffi_program`: Valid pointer to `FfiProgram`
*
* # Returns
* - `Success` if deployment was submitted successfully
* - Error code on other failures
*
* # Memory
* - `FfiProgram` can be freed with corresponding `wallet_ffi_free_ffi_program` function
*
* # Safety
* - `ffi_program` must be a non-null pointer
*/
enum WalletFfiError wallet_ffi_token_elf(struct FfiProgram *ffi_program);
/**
* Writes elf data of amm into buffer.
*
* WARNING: Result is not consisent and change between versions, use for testing purposes only.
*
* # Parameters
* - `ffi_program`: Valid pointer to `FfiProgram`
*
* # Returns
* - `Success` if deployment was submitted successfully
* - Error code on other failures
*
* # Memory
* - `FfiProgram` can be freed with corresponding `wallet_ffi_free_ffi_program` function
*
* # Safety
* - `ffi_program` must be a non-null pointer
*/
enum WalletFfiError wallet_ffi_amm_elf(struct FfiProgram *ffi_program);
/**
* Writes elf data of ata into buffer.
*
* WARNING: Result is not consisent and change between versions, use for testing purposes only.
*
* # Parameters
* - `ffi_program`: Valid pointer to `FfiProgram`
*
* # Returns
* - `Success` if deployment was submitted successfully
* - Error code on other failures
*
* # Memory
* - `FfiProgram` can be freed with corresponding `wallet_ffi_free_ffi_program` function
*
* # Safety
* - `ffi_program` must be a non-null pointer
*/
enum WalletFfiError wallet_ffi_ata_elf(struct FfiProgram *ffi_program);
/**
* Free a ffi program returned by functions `wallet_ffi_*_elf`.
*
* # Safety
* The result must be either null or a valid result from a elf getter function.
*/
void wallet_ffi_free_ffi_program(struct FfiProgram *ffi_program);
/**
* Synchronize private accounts to a specific block.
*