Skip to content
This repository has been archived by the owner on Dec 9, 2023. It is now read-only.

Failed asset transfer when using i9n #102

Closed
jharveyb opened this issue Nov 17, 2020 · 15 comments
Closed

Failed asset transfer when using i9n #102

jharveyb opened this issue Nov 17, 2020 · 15 comments
Assignees
Labels
bug Something isn't working
Milestone

Comments

@jharveyb
Copy link
Contributor

I have successfully issued an asset with the issue i9n function (validated with rgb-cli).

However, when I try to transfer this asset, stashd returns an error after receiving the request to generate the consignment data.

Specifically, after the stash runtime receives the ConsignRequest, it returns this error:
ERROR rgb::contracts::fungible::runtime] Stash daemon has returned failure code: Failure { code: 3, info: "ServiceError { domain: Anchor(\"Incorrect public key data: {_0}\"), service: Stash }" }

AFAICT, the error originates here - all the addresses are bech32 and generated with rust-bitcoincore-rpc, so they should be valid.

I am using this PSBT: cHNidP8BAFICAAAAAQGzz8+yqacT1Ht5YXmBF4DzgLj3nlPgWsCk1UTKoC0YAAAAAAD/////AVBEBCoBAAAAFgAU+DbfVBjpyC+SVNiB1hZqXX2q6oYAAAAAAAEAhQIAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/////BAFFAQH/////AgDyBSoBAAAAFgAUpkvo4kwaLqiaQCDJdNVXblUJ/cgAAAAAAAAAACZqJKohqe3i9hw/cdHe/T+pmd+jaVN1XGkGiXmZYrSL69g2l06M+QAAAAABAR8A8gUqAQAAABYAFKZL6OJMGi6omkAgyXTVV25VCf3IIgYDsInjExR4/MdnmDzQ5TtrF/mpn1iaOoEiTzHKeCjmkmAQl905VQAAAIAAAACAAAAAgAAiAgJ4/wTVYOZ4rrY0kDMSgS4INs/9t7st5TjSlGQJFneXyxCX3TlVAAAAgAAAAIACAACAAA==

I have made successful transfers in the past using rgb-cli and similar PSBTs, around when rgb-node was version beta.4 - I am not sure if the required PSBT structure has changed since then.

@dr-orlovsky dr-orlovsky self-assigned this Nov 19, 2020
@dr-orlovsky dr-orlovsky added this to the v0.2 milestone Nov 19, 2020
@dr-orlovsky
Copy link
Member

Thanks for reporting. Can you pls provide a full command line args you are using for doing the transfer? If you can, pls attach cache/assets.yaml file from the daemon data directory.

@dr-orlovsky
Copy link
Member

Regarding the origin of the error, this seems to be right. Clearly it can't read public key from PSBT. Will investigate with the command line options you provide

@jharveyb
Copy link
Contributor Author

Sure - the transfer:

i9n_rgb.runtime.transfer( vec![issue_outpoint], vec![change_outcoins], transfer_invoice, funded_psbt.psbt.clone(), consignment_file, transaction_file, );

issue_outpoint = OutPoint { txid: 7cf042e20ceb1e7772c34d3b0537a4507bf08e0221833d2cc5f35d1eff437900, vout: 0, }
change_outcoins = Outcoins { coins: 14.0, vout: 0, txid: Some( aa4016426ec257b7f76f8076f47e0db609ad396a9133432739a52eb29539210a, ), }
transfer_invoice = Invoice { contract_id: cd63f437d2ccb0d3d9052221c819da750c6e51f99f4faef0a1169f4da31e8f20, outpoint: BlindedUtxo( 17411af60bb2a927522789e2df69e56272a678912c10dd719566de57de06888a, ), amount: 14.0, }

assets.yaml here.

Two possible causes I've thought of:

  • For making the invoice, I saw that using an Outpoint derived from an address is not yet implemented. So instead I do:
    let blind_hash = rgb::lnpbp::bp::blind::OutpointHash::from(outpoint);
    let blind = fungible::Outpoint::BlindedUtxo(blind_hash);
    I'm not sure if that is correct.

  • I have been using an rgbd instance that is started with the network set to testnet, but I am using a regtest instance. IIRC this would cause address prefixes to be different / incompatible. I had trouble previously with getting rgbd to start with regtest as the chain / network, but I'll look into this more now.

@jharveyb
Copy link
Contributor Author

Re: network mismatch between rgbd and bitcoind, I think I am running into some of the config issues brought up here.

Specifically, I am starting the rgb processes via i9n::Runtime::init with threaded = true. The rgb processes don't seem to register the network setting as regtest, for both states of threaded. I observe the same behavior when starting rgbd from the command line.

@dr-orlovsky dr-orlovsky added the bug Something isn't working label Nov 19, 2020
@dr-orlovsky
Copy link
Member

Yes, seems related to #19. Let's see will the fix there solve this issue as well

@jharveyb
Copy link
Contributor Author

jharveyb commented Dec 1, 2020

I've updated to v0.2.0-beta.4, and rgb-node now registers the given regtest chain param, which is great.

However, I still have the same error from stash on transfer, so unsure what the root cause is.

@jharveyb
Copy link
Contributor Author

jharveyb commented Dec 8, 2020

For more information on the origin of the error:

-i9n::fungible, transfer method -> (RPC with TransferApi)
--contracts::fungible, rpc_transfer method -> (RPC with ConsignRequest)
---stash::fungible, rpc_consign method -> (transitions, PSBT)
----lnpbp::rgb::stash::anchor, commit function -> (PSBT output, "RGB", PSBT_OUT_PUBKEY)
-----lnpbp::bp::psbt, proprietary_key method
------lnpbp::paradigms, strict_decode function

Here we return lnpbp::paradigms::strict_encoding::Error, and this propogates back up.
In anchor::commit, this error is mapped to lnpbp::rgb::stash::anchor::Error::WrongPubkeyData.
The stash runtime wraps this in its RPC reply to the fungible runtime, which returns the final error message in the debug logs.

@dr-orlovsky
Copy link
Member

I am working on PSBT analysis tool in Bitcoin Pro which I will use to solve the problem

@dr-orlovsky
Copy link
Member

dr-orlovsky commented Dec 17, 2020

Ok, I found the reason of the issue (but not a solution yet). It's really wierd.

PSBT, when read from Base64 in i9n, deserializes public key with two additional bytes in front (which represents the lengths of the record, 0x33, 0x00). These two bytes are absent when PSBT is deserialized from binary file. Both deserializations call the same method from rust-bitcoin, so this must not happen (but it happens though).

base64 deserialization: https://github.com/LNP-BP/rgb-node/blob/c3a15e92051f20009888e70dd77c88eb44768480/src/i9n/fungible.rs#L101

unknown: {Key { type_value: 254, key: [3, 82, 71, 66, 1] }: [33, 0, 3, 158, 255, 31, 84, 122, 29, 95, 146, 223, 162, 186, 122, 246, 172, 151, 26, 75, 208, 59, 164, 167, 52, 176, 49, 86, 162, 86, 184, 173, 58, 30, 249]} }] } }

binary deserialization: https://github.com/LNP-BP/rgb-node/blob/c3a15e92051f20009888e70dd77c88eb44768480/src/cli/fungible.rs#L462

unknown: {Key { type_value: 254, key: [3, 82, 71, 66, 1] }: [3, 158, 255, 31, 84, 122, 29, 95, 146, 223, 162, 186, 122, 246, 172, 151, 26, 75, 208, 59, 164, 167, 52, 176, 49, 86, 162, 86, 184, 173, 58, 30, 249]} }] }

Deserialization in i9n calls deserialize function to read from binary array https://github.com/rust-bitcoin/rust-bitcoin/blob/master/src/consensus/encode.rs#L163-L186, however this function just directly calls to consensus_decode like cli version: https://github.com/rust-bitcoin/rust-bitcoin/blob/master/src/util/psbt/mod.rs#L119

@rajarshimaitra may you help me looking into this, spend several hrs and still not being able to figure out how this could happen

@dr-orlovsky
Copy link
Member

The bug is clearly in rust-bitcoin; @rajarshimaitra I will ask you to help me finding it there. Currently made a workaround in RGB Node and the issue is closed here (we still need to file it to rust-bitcoin)

@dr-orlovsky
Copy link
Member

Filed a bug in rust-bitcoin rust-bitcoin/rust-bitcoin#532

@dr-orlovsky
Copy link
Member

dr-orlovsky commented Dec 17, 2020

Actually it seems my fix does not work either. So when we do a PartiallysignedTransaction::consensus_decode for in-memory data (converted from Base64) we got different PSBT data structure than when we do the same PartiallysignedTransaction::consensus_decode from a file, which is very, very weird

@dr-orlovsky dr-orlovsky reopened this Dec 17, 2020
@jharveyb
Copy link
Contributor Author

That is indeed very strange - I will try to replicate, let me know if I can help in some other way.

@rajarshimaitra
Copy link
Contributor

@dr-orlovsky, Noted. This looks interesting, I will dig it tonight.

@rajarshimaitra
Copy link
Contributor

rajarshimaitra commented Dec 17, 2020

@dr-orlovsky seems strange from my end. I tried to reproduce the behaviour as per your comment #102 (comment).

I have made this small test that is using the above two decoding methods to reproduce the behaviour

    fn test1() {
        
        // Test psbt encoding decoding from files and memory buffer

        let file_name = "/rgb-node/sample/source_tx.psbt";
        let psbt_file = File::open(file_name).unwrap();

        // decode the PSBT file
        let psbt_from_file = PartiallySignedTransaction::consensus_decode(psbt_file).unwrap();


        // Same file but decoded into bytes 
        let mut psbt_file = File::open(file_name).unwrap();
        let metadata = std::fs::metadata(&file_name).expect("unable to read metadata");
        let mut psbt_bytes = vec![0; metadata.len() as usize];
        psbt_file.read(&mut psbt_bytes).unwrap();

        
        // decode PSBT from in-memory bytes
        let psbt_from_bytes: PartiallySignedTransaction = deserialize(&psbt_bytes).unwrap();
        
        // This equality ensures decoding in memory buffer and files are same
        assert_eq!(psbt_from_bytes, psbt_from_file);

        //test decoding from base64 to simulate the bug of same byte array
        let base64_psbt = base64::encode(psbt_bytes);
        let psbt_bytes_2 = base64::decode(base64_psbt).unwrap();
        let psbt_from_bytes_2 : PartiallySignedTransaction = deserialize(&psbt_bytes_2).unwrap();

        // This assertion ensures base64 decoding is also equal 
        assert_eq!(psbt_from_bytes, psbt_from_bytes_2);
    }

This above is passing all the assertions. Still trying to reproduce the bug.

@dr-orlovsky dr-orlovsky modified the milestones: v0.2, v0.2.1 Dec 18, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

3 participants