Skip to content

Understanding the Arc optimizations #16

@thunderbiscuit

Description

@thunderbiscuit

We are currently using this optimization when using Arcs (example using TxOut):

impl From<TxOut> for BitcoinTxOut {
    fn from(tx_out: TxOut) -> Self {
        let value = match Arc::try_unwrap(tx_out.value) {
            Ok(val) => val.0,
            Err(arc) => arc.0,
        };

        let script_pubkey = match Arc::try_unwrap(tx_out.script_pubkey) {
            Ok(val) => val.0,
            Err(arc) => arc.0.clone(),
        };

        BitcoinTxOut {
            value,
            script_pubkey,
        }
    }
}

I'm trying to wrap my head around how this really works. Here is my rough understanding:

In the case where we have a TxOut type on the Kotlin side and there is only one reference to it, when we feed this type to a method that takes TxOut, it will de-Arc it and consume the inner value of the Amount type and provide it to the method that requires it.

What I'm still unclear on:

The issue I am unclear on is:

  • When the Rust method that consumes the TxOut type returns, isn't the memory de-allocated, therefore the value inside Amount cleared?
  • If that's the case but I still attempt to use the txOut variable created in Kotlin, will we have a problem? Am I miscounting the references here and the Arc will account for this somehow?

Kotlin example to show what I'm wondering about:

val txOut = wallet.giveMeATxOut()                 // some method that returns a TxOut object
importantInformation = wallet.analyzeTxOut(txOut) // the variable goes through the From<TxOut> pipeline and gets "de-Arc'ed"
println(txOut.value)                              // will this be a dangling pointer??

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions