RGB-Tools / rgb-lightning-node

MIT License
17 stars 19 forks source link

Does rgb-lightning-node support sending RGB assets over lightning network yet? #20

Closed whfuyn closed 7 months ago

whfuyn commented 8 months ago

Hi there, I'm trying to understand the transfer process of RGB assets in rgb-lightning-node.

I notice that, in refresh_transfer, the transaction resolution in the transition verification (rgb_core::validation::Validator::validate_transition) are done by the electrum API, but that API seems to get transactions from Bitcoin and has nothing to do with the lightning network.

I'd like to know how it verifies transitions that happens on lightning network, or if it is not supported yet.

Additionally, I wonder what the relationship between sendpayment and sendasset is. I find that sendpayment pays an invoice with rgb_contract_id and rgb_amount. How does that work without the consignment logic in sendasset?

whfuyn commented 8 months ago

I read through the LDK related code in rgb-lightning-node, and it appears to have some code injected in the underlying rust-lightning library. Is its functionality achieved in a similar way like the satoshis in the channel?

I am a bit of confused about sendasset . Why does it only broadcast the PSBT only when it's a donation? For the receiver to validate the consignment, that PSBT must be published, right? Otherwise the validation status in the receiver side will be UnresolvedTransactions.

pocolocosv commented 8 months ago

Hi there, I'm trying to understand the transfer process of RGB assets in rgb-lightning-node.

I notice that, in refresh_transfer, the transaction resolution in the transition verification (rgb_core::validation::Validator::validate_transition) are done by the electrum API, but that API seems to get transactions from Bitcoin and has nothing to do with the lightning network.

Hi, I'm not sure what's your concern. The refresh_transfer is an API related to on-chain transfers and it has nothing to do with the Lightning Network.

I'd like to know how it verifies transitions that happens on lightning network, or if it is not supported yet.

RGB asset state transitions are created during a channel update and they are independently generated by each peer in a deterministic way. Only the commitment transaction signature is verified. The Lightning Network compatibility page on rgb.info provides additional context.

Additionally, I wonder what the relationship between sendpayment and sendasset is. I find that sendpayment pays an invoice with rgb_contract_id and rgb_amount. How does that work without the consignment logic in sendasset?

sendpayment will send a payment through a Lightning RGB aware channel, while sendasset will send an asset using a Bitcoin on-chain transaction.

Furthermore, consignment handling and verification is done by the refresh methods in RGB and not by sendasset.

I read through the LDK related code in rgb-lightning-node, and it appears to have some code injected in the underlying rust-lightning library. Is its functionality achieved in a similar way like the satoshis in the channel?

Yes, RGB-Tools/rust-lightning does add RGB functionality to the original lightningdevkit/rust-lightning project. You can see the changes to v0.0.118 here. And yes, RGB assets are transferred between channel participants by updating the commitment transactions with the state transitions.

I am a bit of confused about sendasset . Why does it only broadcast the PSBT only when it's a donation? For the receiver to validate the consignment, that PSBT must be published, right? Otherwise the validation status in the receiver side will be UnresolvedTransactions.

When donation is set to true the transaction can be broadcasted immediately. When donation is set to false, the recipient first needs to validate the consignment and ACK the transfer (during a refresh) and only then the sender can broadcast the transaction (during a refresh of his own).

whfuyn commented 7 months ago

Thanks for your help, @pocolocosv . I manage to make both sendasset and sendpayment work.

sendasset

RGB_INVOICE=$(
    curl -X POST -H "Content-type: application/json" \
        -d "{ \"min_confirmations\": 0, \"asset_id\": \"$ASSET_ID\" }" \
        $PEER_RPC/rgbinvoice \
        | jq -r '.invoice'
)

DECODED_RGB_INVOICE=$(
    curl -X POST \
        -H 'Content-Type: application/json' \
        -d "{ \"invoice\": \"$RGB_INVOICE\" }" \
        'http://localhost:3001/decodergbinvoice'
)

RGB_INVOICE_RECIPIENT_ID=$(echo $DECODED_RGB_INVOICE | jq -r '.recipient_id')
RGB_INVOICE_TRANSPORT_ENDPOINTS=$(echo $DECODED_RGB_INVOICE | jq -r '.transport_endpoints')
RGB_INVOICE_AMOUNT=$(echo $DECODED_RGB_INVOICE | jq -r '.amount')
RGB_INVOICE_ASSET_ID=$(echo $DECODED_RGB_INVOICE | jq -r '.asset_id')
if [ "$RGB_INVOICE_AMOUNT" = "null" ]; then
    RGB_INVOICE_AMOUNT=42
fi

curl -X POST \
    -H 'Content-Type: application/json' \
    -d "{
        \"asset_id\": \"$RGB_INVOICE_ASSET_ID\",
        \"amount\": $RGB_INVOICE_AMOUNT,
        \"blinded_utxo\": \"$RGB_INVOICE_RECIPIENT_ID\",
        \"donation\": false,
        \"min_confirmations\": 1,
        \"transport_endpoints\": $RGB_INVOICE_TRANSPORT_ENDPOINTS
    }" \
    "$NODE_RPC/sendasset"
# Peer refresh.
curl -X POST -H "Content-type: application/json" "$PEER_RPC/refreshtransfers"
# Local refresh.
curl -X POST -H "Content-type: application/json" "$NODE_RPC/refreshtransfers"
# Peer refresh again.
# After this refresh, peer's transfer status become "Settled", but why doesn't it need to wait for an online confirmation?
curl -X POST -H "Content-type: application/json" "$PEER_RPC/refreshtransfers"
# Local refresh, but local transfer status won't change.
curl -X POST -H "Content-type: application/json" "$NODE_RPC/refreshtransfers"
# After mining some blocks
./regtest.sh mine 12
# Local transfer status becomes "Settled"
curl -X POST -H "Content-type: application/json" "$NODE_RPC/refreshtransfers"

sendpayment

# Open channel.
curl -X POST -H "Content-type: application/json" \
    -d "{
        \"peer_pubkey_and_addr\": \"$PEER_LDK_PUBKEY_AND_ADDR\",
        \"capacity_sat\": 30010,
        \"push_msat\": 1394000,
        \"asset_amount\": 500,
        \"asset_id\": \"$ASSET_ID\",
        \"public\": true,
        \"with_anchors\": true
    }" \
    $NODE_RPC/openchannel

# Mine some blocks
sleep 3
./regtest.sh mine 24
sleep 3

# Create an invoice from peer.
LN_INVOICE=$(
    curl -X POST -H "Content-type: application/json" \
        -d "{
            \"amt_msat\": 3000000,
            \"expiry_sec\": 420,
            \"asset_id\": \"$ASSET_ID\",
            \"asset_amount\": 77
        }" \
        $PEER_RPC/lninvoice \
        | jq -r '.invoice'
)
sleep 5

curl -X POST -H "Content-type: application/json" \
    -d "{ \"invoice\": \"$LN_INVOICE\" }" \
    "$NODE_RPC"/sendpayment
sleep 5

# Close channel
curl -X POST -H "Content-type: application/json" \
    -d "{
        \"channel_id\": \"$CHANNEL_ID\",
        \"peer_pubkey\": \"$PEER_PUBKEY\",
        \"force\": false
    }" \
    "$NODE_RPC/closechannel"

# Waiting for `periodic_sweep`.
# This is actually one sweep on startup + daily sweep.
# For development, change `interval_secs` in `periodic_sweep` to small number.
sleep 10
./regtest.sh mine 24

Is this the intended procedure?

whfuyn commented 7 months ago

When donation is set to true the transaction can be broadcasted immediately. When donation is set to false, the recipient first needs to validate the consignment and ACK the transfer (during a refresh) and only then the sender can broadcast the transaction (during a refresh of his own).

Do you mean that the validation on the recipient side only validates the previous history and does not involve the transaction that is about to transfer the ownership of these RGB assets (the transaction that the sender will broadcast after receiving ACK)?

pocolocosv commented 7 months ago

Is this the intended procedure?

There’s no intended procedure but the sent commands look correct.

Do you mean that the validation on the recipient side only validates the previous history and does not involve the transaction that is about to transfer the ownership of these RGB assets (the transaction that the sender will broadcast after receiving ACK)?

No, that's not what I meant. What I was trying to say is that in donation mode the sender will not wait for the recipient to ACK the consignment before broadcasting the TX. The recipient will always validate the transitions anchored to the TX, no matter if it was sent in donation or not.

whfuyn commented 7 months ago

I understand that the recipient will always validate the transitions anchored to the TX, but I was confused about whether the TX consuming the UTXO that owns the RGB assets is needed to be on-chain for the recipient to validate.

Based on what I see now, I think it's not a part of the validation on the recipient's side, but rather what the "WaitingConfirmations" status waits for.

Is this understanding correct?

pocolocosv commented 7 months ago

I understand that the recipient will always validate the transitions anchored to the TX, but I was confused about whether the TX consuming the UTXO that owns the RGB assets is needed to be on-chain for the recipient to validate.

Based on what I see now, I think it's not a part of the validation on the recipient's side, but rather what the "WaitingConfirmations" status waits for.

Is this understanding correct?

Not entirely, upon receiving the consignment, the recipient will verify the RGB transfer history, before the transaction (TX) is broadcast, and reply to the sender (via RGB proxy server) with a positive (ACK) or negative (NACK) acknowledgment. In the case of a donation, the sender will have already broadcast the TX without waiting for the recipient's acknowledgment (ACK) from the recipient. Once the recipient observes the broadcasted TX, the consignment will be re-validated and this time also the anchoring to the TX will be checked.

See the following diagrams for an explanation. Transfer diagrams Transfer state diagrams

whfuyn commented 7 months ago

Thanks for your kind help, @pocolocosv !

When I was reading the code, I didn't find these workflow diagrams and had to rely on my own understanding to figure out each step.

I think it would be very helpful if we mention these workflow diagrams in the readme.

pocolocosv commented 7 months ago

You’re welcome. The diagrams are mentioned in rgb-lib’s README.md in section Diagrams towards the end of the file.