iotaledger / identity.rs

Implementation of the Decentralized Identity standards such as DID and Verifiable Credentials by W3C for the IOTA Tangle.
https://www.iota.org
Apache License 2.0
301 stars 87 forks source link

[Bug] (node:91512) UnhandledPromiseRejectionWarning: Chain Error: Invalid Root Document #264

Closed sdellava closed 3 years ago

sdellava commented 3 years ago

Bug description

identity.resolve("did:iota:HVbziVthxfpUMhv2xuo3Dhr1BtQqTaq373EXbi42vGKL") on testnet always return the error Invalid Root Document

iota node: https://api.lb-0.testnet.chrysalis2.com:443

did.document: https://explorer.iota.org/testnet/message/1c2de96b49cbc293c84f6077b404cd98bf240486f72d9d403d56680e2ac79a16

Language version

IOTA Identity version

Which version of IOTA Identity are you using? Version: 0.3.1

Steps To reproduce the bug

npm i @iota/identity-wasm node const identity = require('@iota/identity-wasm/node') const run = async () => { const key = await new identity.KeyPair(identity.KeyType.Ed25519) const doc = await identity.Document.fromKeyPair(key) doc.sign(key) message = await identity.publish(doc.toJSON(), { node: "https://api.lb-0.testnet.chrysalis2.com:443" }) console.log(message) document = await identity.resolve(doc.id.toString()) console.log(document) } run()

sdellava commented 3 years ago

update: here you can find two dids. The first is resolved, the second return error.

did:iota:2rXkhC7f4i62WLf3t62ngFSTEt9m6q4kHMTTFmK9JtLY - OK !

did:iota:8gpmPxYWx7GVqY6pdsh4rcJZhZRmgPfm1cTZXnPzVx1P - NO OK !!!

Looking in the explorer (mainnet) I can't find any significant error in the JSON.

JonasHiltl commented 3 years ago

I'm getting the same error while validating a credential with checkCredential(). I gues that the checkCredential function also resolves the Did document under the hood so the reason for the error is probably the same. Do you have any news on the issue?

m-renaud commented 3 years ago

@sdellava in the bug description you mention that the failure occurs when on the testnet, not the mainnet, but looking at the DIDs that are created, neither of them have a non-main network specified (such as did:iota:test:XYZ). Is it possible that the node is publishing to the testnet but resolve() is attempting to find the message on the main net?

I'm not super familiar with the WASM bindings, but in the Rust client API you need to specify Network::Testnet if you want to publish the transaction on the testnet. Looking at the WASM API docs I'm assuming it pulls the network from the document.

m-renaud commented 3 years ago

This actually led me to discover another issue: IotaDocument::from_keypair() doesn't have an option of using any network other than main, which leads to the following error if trying to modify the create_did_document.rs example and change the Client to use Network::Testnet:

let client: Client = ClientBuilder::new()
    .network(Network::Testnet)
    .node("https://api.lb-0.testnet.chrysalis2.com/")
    .build()
    .await?;

  // Use the client to publish the DID Document to the Tangle.
  println!("Publishing document...");
  document.publish(&client).await?;

ERROR:

Publishing document...
Expected: test, found main, for did: did:iota:DbEMGixbii9wNBJnieZ7JjsPmKY7PdDaXN9wC7va4xdg
Error: InvalidDIDNetwork
m-renaud commented 3 years ago

@JonasHiltl I assume this has the same root cause as the issue you're having. See my above response about testnet vs. mainnet DID format.

sdellava commented 3 years ago

Yes, I've noted too that the issue happen mostly (or exclusively?) in the testnet. So the bug should be related to the network selection, or network default configuration.

JonasHiltl commented 3 years ago

For me the issue happens on mainnet using https://chrysalis-nodes.iota.org:443

m-renaud commented 3 years ago

Thanks for the info, I'll take another look today if I have time. @JonasHiltl are there any other relevant console.log() outputs you have?

JonasHiltl commented 3 years ago

No other console.logs but for my case you can have a look at the file in which the error happens: This is the function which works well until the ChechCredential() gets called.

l1h3r commented 3 years ago

@sdellava in the bug description you mention that the failure occurs when on the testnet, not the mainnet, but looking at the DIDs that are created, neither of them have a non-main network specified (such as did:iota:test:XYZ). Is it possible that the node is publishing to the testnet but resolve() is attempting to find the message on the main net?

This is the cause of the resolution issue. @sdellava you've published a document to the testnet without actually using a testnet DID (did:iota:test:<tag>).

Since the removal of IotaDocumentBuilder the only way to do this is by explicitly specifying the network via new DID(...).

const key = new KeyPair(KeyType.Ed25519)
const did = new DID(key, "test") // <---- "test" or "main"
const method = VerificationMethod.fromDID(did, key, "authentication")
const didDoc = Document.fromAuthentication(method)

The WASM bindings also don't detect the document network before publishing so for now you will also need to specify the network when calling Identity.publish.

const messageId = await Identity.publish(didDoc.toJSON(), { network: "test" })
m-renaud commented 3 years ago

Additionally, you need to specify { network: "test" } when calling identity.resolve().

The following code snippet works (for me). @JonasHiltl @sdellava could you confirm?

const identity = require('@iota/identity-wasm/node')
const run_testnet = async () => {
  const key = new identity.KeyPair(identity.KeyType.Ed25519)
  const did = new identity.DID(key, "test") // <---- "test" or "main"
  console.log(did)
  const method = identity.VerificationMethod.fromDID(did, key, "authentication")
  const didDoc = identity.Document.fromAuthentication(method)
  didDoc.sign(key)
  message = await identity.publish(didDoc.toJSON(), { node: "https://api.lb-0.testnet.chrysalis2.com:443", network: "test" })
  console.log(message)
  document = await identity.resolve(didDoc.id.toString(), { network: "test" })
  console.log(document)
}
run_testnet()
m-renaud commented 3 years ago

Also, @JonasHiltl if this is occurring on mainnet, you may be running into a separate problem; I don't know what that problem is though :P

sdellava commented 3 years ago

thank you @m-renaud. From my side you can close the issue, but I suggest to improve the example code and the documentation because node and network are optional and appear to be testnet/test by default.

sdellava commented 3 years ago

Additionally, you need to specify { network: "test" } when calling identity.resolve().

The following code snippet works (for me). @JonasHiltl @sdellava could you confirm?

const identity = require('@iota/identity-wasm/node')
const run_testnet = async () => {
  const key = new identity.KeyPair(identity.KeyType.Ed25519)
  const did = new identity.DID(key, "test") // <---- "test" or "main"
  console.log(did)
  const method = identity.VerificationMethod.fromDID(did, key, "authentication")
  const didDoc = identity.Document.fromAuthentication(method)
  didDoc.sign(key)
  message = await identity.publish(didDoc.toJSON(), { node: "https://api.lb-0.testnet.chrysalis2.com:443", network: "test" })
  console.log(message)
  document = await identity.resolve(didDoc.id.toString(), { network: "test" })
  console.log(document)
}
run_testnet()

Yes, I confirm.

JonasHiltl commented 3 years ago

Additionally, you need to specify { network: "test" } when calling identity.resolve().

The following code snippet works (for me). @JonasHiltl @sdellava could you confirm?


const identity = require('@iota/identity-wasm/node')

const run_testnet = async () => {

  const key = new identity.KeyPair(identity.KeyType.Ed25519)

  const did = new identity.DID(key, "test") // <---- "test" or "main"

  console.log(did)

  const method = identity.VerificationMethod.fromDID(did, key, "authentication")

  const didDoc = identity.Document.fromAuthentication(method)

  didDoc.sign(key)

  message = await identity.publish(didDoc.toJSON(), { node: "https://api.lb-0.testnet.chrysalis2.com:443", network: "test" })

  console.log(message)

  document = await identity.resolve(didDoc.id.toString(), { network: "test" })

  console.log(document)

}

run_testnet()

Yes it also works for me. It's strange that I get the same error while using the mainnet I will try to figure out the reason for my error and share it through a new issue. You can close this issue from my side.

m-renaud commented 3 years ago

@l1h3r the two above PRs were merged, can we close out this issue now?

sdellava commented 3 years ago

I guess so.