Skip to content

TapTree roundtrip serialization fails with hidden branches #928

@dr-orlovsky

Description

@dr-orlovsky

TapTree can be build from TaprootBuilder having hidden branches; however PSBT does not provide format for presenting hidden branches. Thus, TapTree psbt serialization is buggy: it will present incorrect representation of trees/descriptors with hidden branches. As a result, TapTree also fails to roundtrip if a hidden branch is present:

    #[test]
    fn taptree_roundtrip_hidden() {
        let mut builder = compose_taproot_builder(0x51, [2, 2, 2]);
        builder = builder.add_leaf_with_ver(3, Script::from_hex("b9").unwrap(), LeafVersion::from_consensus(0xC2).unwrap()).unwrap();
        builder = builder.add_hidden(3, sha256::Hash::default()).unwrap();
        let tree = TapTree::from_inner(builder).unwrap();
        let tree_prime = TapTree::deserialize(&tree.serialize()).unwrap();
        assert_eq!(tree, tree_prime);
    }

fails: test result: FAILED. 248 passed; 1 failed

---- util::psbt::serialize::tests::taptree_roundtrip_hidden stdout ----
thread 'util::psbt::serialize::tests::taptree_roundtrip_hidden' panicked at 'called Result::unwrap() on an Err value: ParseFailed("Tree not in DFS order")', src/util/psbt/serialize.rs:415:66

The proposed solution is to introduce TaprootBuilder::has_hidden_branches and check that in TapTree::from_inner, returning error. I am already working on a PR fixing that.

Related discussion: #924 (comment)

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions