RGB-WG / rgb-std

RGB standard libs for WASM & low-level integrations (no FS/networking)
https://rgb.tech
Apache License 2.0
66 stars 30 forks source link

witness UTXO produces no terminals nor bundles #71

Closed nicbus closed 1 year ago

nicbus commented 1 year ago

Trying to do a witness UTXO transfer using our rgb-sandbox I hit what looks like a consignment issue.

When trying to transfer using witness UTXO every step completes and no error is returned, but when I check the balance of the involved peers, it's not what I expect.

Some more details:

When using a blinded UTXO for the transfer, everything works as expected and the final balances match the expected ones.

The difference seems to lie in the consignment contents. Specifically, the terminals and bundles sections are empty in the witness UTXO case, which explains why the consignment gets successfully validated and accepted. Once the tx is mined balances will of course be zero, because the issuance UTXO has been spent and no new allocations have been created.

Here's an excerpt of the consignment (inspect) from the failing case:

terminals: Confined(
    {},
),
bundles: Confined(
    [],
),

Here's the corresponding excerpt from a success case:

terminals: Confined(
    {
        Terminal {
            bundle_id: BundleId(
                Array<32>(a354a76e7752e3c6dc500ac29b73d3f0efe36f886e244e0490f4ed6f5cb9fbf1),
            ),
            seal: ConcealedUtxo(
                SecretSeal(
                    Array<32>(87e58953d9363c7bebfd6bdb41b8426e54aec2203bd14aebbfa48592a2923f96),
                ),
            ),
        },
    },
),
bundles: Confined(
    [
        AnchoredBundle {
            anchor: Anchor {
                txid: Txid(
                    "6fe84173a0816c92299107ecfc45689cac3d793361662870f0e9918832bbd785",
                ),
                mpc_proof: MerkleProof {
                    pos: 9,
                    path: Confined(
                        [
                            MerkleNode(
                                Array<32>(8c304cbf86b71be497656e5f2a2f4dbb2293899a902b82ea314101995bf1eea4),
                            ),
                            MerkleNode(
                                Array<32>(e7898716bd7cba977a6b71be11146589820018ea2342c81a0e77671f5434ff41),
                            ),
                            MerkleNode(
                                Array<32>(3e501e52b4da17675008aa1d96b9e3eb110b0b2db81c940b935f38176fbdb8ae),
                            ),
                            MerkleNode(
                                Array<32>(9fdef351b7125f355e7aa29ee4e999efad973878a8ae3d6f6c9e4db70f5706d7),
                            ),
                        ],
                    ),
                },
                dbc_proof: OpretFirst,
            },
            bundle: TransitionBundle(
                Confined(
                    {
                        OpId(
                            Array<32>(0d7e29b7bfbd96600c6f19e6220c700c0cea12f0a6afb432f51ba952b7a03522),
                        ): BundleItem {
                            inputs: Confined(
                                {
                                    0,
                                },
                            ),
                            transition: Some(
                                Transition {
                                    ffv: Ffv(
                                        0,
                                    ),
                                    contract_id: ContractId(
                                        Array<32>(290e83b8b2003d83b182b2596b4f8192e26e6881120b13c776ee5d22fd5759dd),
                                    ),
                                    transition_type: 2000,
                                    metadata: Confined(
                                        [],
                                    ),
                                    globals: GlobalState(
                                        Confined(
                                            {},
                                        ),
                                    ),
                                    inputs: Inputs(
                                        Confined(
                                            {
                                                Input {
                                                    prev_out: Opout {
                                                        op: OpId(
                                                            Array<32>(290e83b8b2003d83b182b2596b4f8192e26e6881120b13c776ee5d22fd5759dd),
                                                        ),
                                                        ty: 2000,
                                                        no: 0,
                                                    },
                                                    reserved: ReservedByte(
                                                        0,
                                                    ),
                                                },
                                            },
                                        ),
                                    ),
                                    assignments: Assignments(
                                        Confined(
                                            {
                                                2000: Fungible(
                                                    Confined(
                                                        [
                                                            Revealed {
                                                                seal: BlindSeal {
                                                                    method: OpretFirst,
                                                                    txid: WitnessTx,
                                                                    vout: Vout(
                                                                        0,
                                                                    ),
                                                                    blinding: 13343935844928001241,
                                                                },
                                                                state: RevealedValue {
                                                                    value: Bits64(
                                                                        1900,
                                                                    ),
                                                                    blinding: BlindingFactor(
                                                                        Array<32>(976e76cd030ace95f642c067b1a6bb4673a6e52019e7914466085f45ced52ae5),
                                                                    ),
                                                                },
                                                            },
                                                            ConfidentialSeal {
                                                                seal: SecretSeal(
                                                                    Array<32>(87e58953d9363c7bebfd6bdb41b8426e54aec2203bd14aebbfa48592a2923f96),
                                                                ),
                                                                state: RevealedValue {
                                                                    value: Bits64(
                                                                        100,
                                                                    ),
                                                                    blinding: BlindingFactor(
                                                                        Array<32>(646ab9cf46c7c1536786bff5376bb3d5948fd9abffd706c53c5f5cef05bcc3ce),
                                                                    ),
                                                                },
                                                            },
                                                        ],
                                                    ),
                                                ),
                                            },
                                        ),
                                    ),
                                    valencies: Valencies(
                                        Confined(
                                            {},
                                        ),
                                    ),
                                },
                            ),
                        },
                    },
                ),
            ),
        },
    ],
),
nicbus commented 1 year ago

@dr-orlovsky you can use this branch of the rgb-sandbox to reproduce my fidings

dr-orlovsky commented 1 year ago

Can't replicate: when I am using the link for the sandbox everything seems to run correctly and at the end I get

sender balance: 0
receiver balance: 1742

Can you pls provide me with a stock.dat - and the latest PSBT file before it was finalized?

nicbus commented 1 year ago

Can't replicate: when I am using the link for the sandbox everything seems to run correctly and at the end I get

sender balance: 0
receiver balance: 1742

Can you pls provide me with a stock.dat - and the latest PSBT file before it was finalized?

Strange result, as 2000 assets are issued and 100 transferred, so the expected final balances are:

Did you modify the sandbox code in any way or were you running it exactly as in commit 4147e65?

This is an example of what I get as last messages (and what I would also expect in your case):

 > final balances
outpoints: 8e2f3db0bb3d748cab7ef9d8ac26de40df8999d8b2ad43e4dfe3339e241b204f:2
wallet issuer allocations:
    amount=2000  utxo=7237edb79b641b51107d19bf84a61d8c66093d9487a97de1331dba2a69cf4220:0

ERROR: balance (0) differs from expected (1900)

where 8e2f3db0bb3d748cab7ef9d8ac26de40df8999d8b2ad43e4dfe3339e241b204f:2 is the current wallet unspent and 7237edb79b641b51107d19bf84a61d8c66093d9487a97de1331dba2a69cf4220:0 is the issuance UTXO.

I have re-run the sandbox from a clean clone, to make sure I had no local differences from what you downloaded and it didn't work anymore. The problem seems due to changes in rgb-contracts and its dependencies.

I think the breaking change is in rgb-wallet commit e6dbafe (iface: refactor VelocityClass). By modifying the wallet descriptor to use change index 0 (instead of the previous 1) the sandbox is now working again as expected.

I have pushed an update to the same rgb-sandbox branch (commit 1cf57de).

Note: I also added a check for the electrs port being already in use (it now quits with an error), to help prevent issues like the ones you were describing in yesterday's call.

Please try using the updated sandbox and let me know your findings. I expect it to give you the same error I get.

dr-orlovsky commented 1 year ago

Did you modify the sandbox code in any way or were you running it exactly as in commit 4147e65?

I haven't modified it. But I just cloned your fork, so now I see that it points to your master which is 095800b8807f136b57fd2ff4e333f82d1a4243e9. Will check with that specific commit!

dr-orlovsky commented 1 year ago

Now it "works" (i.e. I get error of 0 balance you described).

Can you pls let me know how I can extract PSBT and stock.dat?

nicbus commented 1 year ago

Can you pls let me know how I can extract PSBT and stock.dat?

You can find files from the last run inside the data0/1/2 directories (respectively: issuer, recipient 1, recipient 2).

As examples, the stock file for the issuer can thus be found in data0/regtest/stock.dat and the psbt for the 1st transfer in data0/tx_1.psbt.

nicbus commented 1 year ago

The sandbox has been updated to use the fix in branch fix/71. The issue seems to still be there.

You can fetch the new commit and should be able to reproduce it. Note: the rgb-schemata submodule needs to be updated.

In the sandbox I updated the contract template so the issuance now works with rgb-contracts from the master branch. I still use my fork of it as rgb-wallet needs a fix for beneficiary vs assetOwner FieldName (just a quick&dirty workaround so the transfer works).

dr-orlovsky commented 1 year ago

Ok, it seems I need to print out debug info from the code - so I need to update rgb-std over and over again to see the output in the sandbox. How hard it will be to use the RGB-WG/rgb-wallet/fix/71 branch in the sandbox?

nicbus commented 1 year ago

Ok, it seems I need to print out debug info from the code - so I need to update rgb-std over and over again to see the output in the sandbox. How hard it will be to use the RGB-WG/rgb-wallet/fix/71 branch in the sandbox?

That's easy, the sandbox installs rgb-contracts on each run, so you can change it (e.g. to a local version) and patch the (e.g. rgb-std) dependencies there.

To do so, look for the install_rgb_crates() function in the demo.sh script. There you can tweak the cargo install command for rgb-contracts.

nicbus commented 1 year ago

Updated the sandbox to use the latest rgb-contracts (cd81a7b) and rgb-schemata (c356aee), plus related changes. Updates pushed to the usual branch (commit 0b801f9).

I can confirm the transfer to an invoice containing an address is now working.