@@ -1865,3 +1865,97 @@ func TestVerifySubtreeRootInclusion_infiniteRecursion(t *testing.T) {
1865
1865
require .Error (t , err )
1866
1866
})
1867
1867
}
1868
+
1869
+ func TestComputeRootWithBasicValidation (t * testing.T ) {
1870
+ tree := exampleNMT (1 , true , 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 )
1871
+ hasher := tree .treeHasher .(* NmtHasher )
1872
+
1873
+ nid := namespace.ID {3 }
1874
+ proof , err := tree .ProveNamespace (nid )
1875
+ require .NoError (t , err )
1876
+
1877
+ leaves := tree .Get (nid )
1878
+ require .NotEmpty (t , leaves )
1879
+
1880
+ namespacedLeaves := make ([][]byte , len (leaves ))
1881
+ copy (namespacedLeaves , leaves )
1882
+
1883
+ leafHashes , err := ComputeAndValidateLeafHashes (hasher , nid , namespacedLeaves )
1884
+ require .NoError (t , err )
1885
+
1886
+ t .Run ("valid namespace validation" , func (t * testing.T ) {
1887
+ root , err := tree .Root ()
1888
+ require .NoError (t , err )
1889
+
1890
+ gotRoot , err := proof .ComputeRootWithBasicValidation (hasher , nid , leafHashes , true )
1891
+ require .NoError (t , err )
1892
+ assert .Equal (t , root , gotRoot )
1893
+ })
1894
+
1895
+ t .Run ("fails on wrong leaf hashes" , func (t * testing.T ) {
1896
+ // corrupt hash input
1897
+ corrupted := append ([][]byte (nil ), leafHashes ... )
1898
+ corrupted [0 ] = []byte ("invalid" )
1899
+
1900
+ _ , err := proof .ComputeRootWithBasicValidation (hasher , nid , corrupted , true )
1901
+ require .Error (t , err )
1902
+ })
1903
+ }
1904
+
1905
+ func TestValidateNamespace_FailsOnWrongNID (t * testing.T ) {
1906
+ tree := exampleNMT (1 , true , 1 , 2 , 3 , 4 )
1907
+ hasher := tree .treeHasher .(* NmtHasher )
1908
+
1909
+ nid := namespace.ID {2 }
1910
+ proof , err := tree .ProveNamespace (nid )
1911
+ require .NoError (t , err )
1912
+
1913
+ leaves := tree .Get (nid )
1914
+ require .NotEmpty (t , leaves )
1915
+
1916
+ // corrupt the namespace of the first leaf
1917
+ corruptedLeaf := make ([]byte , len (leaves [0 ]))
1918
+ copy (corruptedLeaf , leaves [0 ])
1919
+ // change both min and max namespace bytes to simulate a different namespace
1920
+ corruptedLeaf [0 ] = 99
1921
+
1922
+ leaves [0 ] = corruptedLeaf
1923
+
1924
+ leafHashes , err := ComputeAndValidateLeafHashes (hasher , nid , leaves )
1925
+ require .Error (t , err ) // Expect failure here
1926
+
1927
+ // Only call ValidateNamespace if hash step unexpectedly succeeds
1928
+ if err == nil {
1929
+ err = proof .ValidateNamespace (hasher , nid , leafHashes )
1930
+ require .Error (t , err )
1931
+ }
1932
+ }
1933
+
1934
+ func TestValidateCompleteness_FailsOnIncompleteSubtrees (t * testing.T ) {
1935
+ // Create a tree with multiple leaves of the same namespace
1936
+ tree := exampleNMT (1 , true , 1 , 2 , 2 , 2 , 3 , 4 , 5 , 6 )
1937
+
1938
+ nid := namespace.ID {2 }
1939
+ proof , err := tree .ProveNamespace (nid )
1940
+ require .NoError (t , err )
1941
+
1942
+ hasher := tree .treeHasher .(* NmtHasher )
1943
+
1944
+ // Confirm original proof passes completeness
1945
+ err = proof .ValidateCompleteness (hasher , nid )
1946
+ require .NoError (t , err , "baseline completeness check should pass" )
1947
+
1948
+ // Inject a node with namespace = 2 (same as the query)
1949
+ // This should simulate a missing share in the proof (incompleteness)
1950
+ leaf := namespace .PrefixedData (append ([]byte {2 }, []byte ("extra" )... ))
1951
+ badNode , err := hasher .HashLeaf (leaf )
1952
+ require .NoError (t , err )
1953
+
1954
+ // Inject it to the right side of the proof, simulating a right subtree
1955
+ proof .nodes = append (proof .nodes , badNode )
1956
+
1957
+ // Now it should fail completeness
1958
+ err = proof .ValidateCompleteness (hasher , nid )
1959
+ require .Error (t , err )
1960
+ require .ErrorIs (t , err , ErrFailedCompletenessCheck )
1961
+ }
0 commit comments