orbitdb / field-manual

The Offical User's Guide to OrbitDB
207 stars 43 forks source link

Ipfs.node.dag.get fails in Chapter 2 of the tutorial #140

Closed santiag0m closed 2 years ago

santiag0m commented 3 years ago

I was following the tutorial but got stuck for a while in Chapter 2 with the following error:

.../myproject/node_modules/multibase/src/rfc4648.js:71
  for (let i = 0; i < data.length; ++i) {
                           ^

TypeError: Cannot read property 'length' of undefined
    at encode (.../myproject/node_modules/multibase/src/rfc4648.js:71:28)
    at Object.encode (.../myproject/node_modules/multibase/src/rfc4648.js:111:14)
    at Base.encode (.../myproject/node_modules/multibase/src/base.js:33:23)
    at toString (.../myproject/node_modules/uint8arrays/to-string.js:45:29)
    at blockEvent (.../myproject/node_modules/ipfs-bitswap/src/notifications.js:23:38)
    at Notifications.wantBlock (.../myproject/node_modules/ipfs-bitswap/src/notifications.js:68:22)
    at Bitswap.get (.../myproject/node_modules/ipfs-bitswap/src/index.js:276:26)
    at BlockService.get (.../myproject/node_modules/ipfs-block-service/src/index.js:97:28)
    at IPLDResolver.get (.../myproject/node_modules/ipld/src/index.js:155:33)
    at get (.../myproject/node_modules/ipfs-core/src/components/dag/get.js:31:25)

After searching similar issues in IPFS, I found this one: https://github.com/ipfs/js-ipfs/issues/3689 . Turns out that IPFS now expects a CID object when handling content.

I was able to fix it by adding a CID constructor in the NewPiecePlease class.

To do this I had to install the cids npm package. For it to work in the browser I added the following script tag (for version 1.1.4 as newer versions are not available):

<script src="https://unpkg.com/cids@1.1.4/dist/index.min.js"></script>
matheusmartins56 commented 3 years ago

I was following the tutorial but got stuck for a while in Chapter 2 with the following error:

.../myproject/node_modules/multibase/src/rfc4648.js:71
  for (let i = 0; i < data.length; ++i) {
                           ^

TypeError: Cannot read property 'length' of undefined
    at encode (.../myproject/node_modules/multibase/src/rfc4648.js:71:28)
    at Object.encode (.../myproject/node_modules/multibase/src/rfc4648.js:111:14)
    at Base.encode (.../myproject/node_modules/multibase/src/base.js:33:23)
    at toString (.../myproject/node_modules/uint8arrays/to-string.js:45:29)
    at blockEvent (.../myproject/node_modules/ipfs-bitswap/src/notifications.js:23:38)
    at Notifications.wantBlock (.../myproject/node_modules/ipfs-bitswap/src/notifications.js:68:22)
    at Bitswap.get (.../myproject/node_modules/ipfs-bitswap/src/index.js:276:26)
    at BlockService.get (.../myproject/node_modules/ipfs-block-service/src/index.js:97:28)
    at IPLDResolver.get (.../myproject/node_modules/ipld/src/index.js:155:33)
    at get (.../myproject/node_modules/ipfs-core/src/components/dag/get.js:31:25)

After searching similar issues in IPFS, I found this one: ipfs/js-ipfs#3689 . Turns out that IPFS now expects a CID object when handling content.

I was able to fix it by adding a CID constructor in the NewPiecePlease class.

To do this I had to install the cids npm package. For it to work in the browser I added the following script tag (for version 1.1.4 as newer versions are not available):

<script src="https://unpkg.com/cids@1.1.4/dist/index.min.js"></script>

Even after i included the script above, i get the error that 'CID is not defined'. I also tried with the scrips the cids package included, but i get a 404 error.

santiag0m commented 3 years ago

Turns out the CID package is not necessary. It is possible to create a new CID using IPFS with new this.Ipfs.CID(hash_str).

kvutien commented 3 years ago

I confirm the finding of @santiag0m and of @matheusmartins56: the REPL command const content = await NPP.node.dag.get(cid) provokes the error listed by @santiag0m.

I traced the error in the different packages of node_modules and I found that the bug is in node_modules/ipfs-bitswap/src/notifications.js:23:38

This statement is const blockEvent = (cid) => block:${uint8ArrayToString(cid.multihash, 'base64')}. In this statement the function uint8ArrayToString is called with cid.multihash. When I traced back the call, indeed the cid of the REPL command was cascaded, unchanged, down the calls.

Googling around, I found this old "inactive" doc of ipfs.dag.get: "A place for archived, legacy and old repositories from the IPFS project". The example given matches the example of this tutorial, but it is "archived"

I found the current docs here and the code of the tutorial doesn't seem to match this doc.

I might be mistaking but my guess is that there has been a breaking change in one of the npm packages between the moment the tutorial was made and today. -- I'll try and set it straight, but with no guarantees, I'm really a beginner. :)

kvutien commented 3 years ago

I think I'm getting closer to the bug.

  1. In the IPFS release note of 0.41 of February 2020, a breaking change, it is said in the Core API "add results now contain a cid property (a CID instance) instead of a string hash property."
  2. In the trace of the error, I see
    at blockEvent (/Users/kvutien/development/orbitdb-ch1/node_modules/ipfs-bitswap/src/notifications.js:23:38)
    const blockEvent = (cid) => `block:${uint8ArrayToString(cid.multihash, 'base64')}

    The function uint8ArrayToString failed trying to read cid.multihash from an object cid that is actually returned by the previous call as a hash string.

The previous call was to addNewPiece which called pieces.put. It seems to me that the discrepancy is here: the OrbitDB function put returns a hash string that is fed to an IPFS function that expects a JSON.

Calling on @aphelionz for confirmation?

kvutien commented 3 years ago

It's confirmed: the problem lies in the REPL instruction given in the tutorial, the module orbit-db return a string and the module ipfs expects an Uint8Array. Now how do we change it?

Try 1. I tried to use the counterpart of NPP.pieces.put instead of what is written in the tutorial

 content = await NPP.pieces.get(cid)
 //instead of what is written in the tutorial
 //const content = await NPP.node.dag.get(cid)

the error was no more triggered. But the result is empty:

kvutien@VTKT5 orbitdb-ch1 % node --experimental-repl-await
...
> cid
'zdpuAnDVaC6371n8ik8SQCAb43ebYkLm1XXhgwqXikhnUHSQB'
> content = await NPP.pieces.get(cid)
[]

Try 2. I made a JavaScript program to use node.dag.put , the counterpart of node.dag.get and see what is the cid.multihash value returned

/* 
 * Main JavaScript program to check the cid returned by ipfs.add
 */
const Ipfs = require ('ipfs-core');

async function create() {
    console.log(' --> calling create IPFS node;')
    // create an IPFS node
    const node = await Ipfs.create({
        preload: {enabled: false},
        repo: './ipfs',
        config: {
            Bootstrap: [],
            Addresses: {Swarm: []}
        }
    })
    const cid = await node.dag.put({name: 'test'});
    console.log(' ---> cid.multihash =', cid.multihash)
}
create();

The ouput is

kvutien@VTKT5 orbitdb-ch1 % node test.js
 --> calling create IPFS node;
 ---> cid.multihash = Uint8Array(34) [
   18,  32, 113, 229, 142, 183, 117,  57,
  212, 139, 249, 124,  10, 201,  60,  53,
   35,  71,  85,   1,  23, 241,  67, 102,
   14, 131, 112, 153,  10,  69, 242,  34,
  183,  76
]
zhiquan911 commented 2 years ago

@kvutien

To run on the browser, you need to modify the code as follows: const content = await NPP.node.dag.get(new NPP.Ipfs.CID(cid))

lilian131 commented 2 years ago

@kvutien

To run on the browser, you need to modify the code as follows: const content = await NPP.node.dag.get(new NPP.Ipfs.CID(cid))

thanks it works remplacing NPP.node.dag.get(Ipfs.asCID(cid)) by NPP.node.dag.get(new NPP.Ipfs.CID(cid))

kvutien commented 2 years ago

Cool I'll try. Thanks. -- Vu Tien Khang

Le 1 déc. 2021 à 07:15, lilian131 @.***> a écrit :

@kvutien https://github.com/kvutien To run on the browser, you need to modify the code as follows: const content = await NPP.node.dag.get(new NPP.Ipfs.CID(cid))

thanks it works remplacing NPP.node.dag.get(Ipfs.asCID(cid)) by NPP.node.dag.get(new NPP.Ipfs.CID(cid))

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/orbitdb/field-manual/issues/140#issuecomment-983323997, or unsubscribe https://github.com/notifications/unsubscribe-auth/AHY2OURHYIWJ4C22PS5DDV3UOW4RZANCNFSM46TIJWMA. Triage notifications on the go with GitHub Mobile for iOS https://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675 or Android https://play.google.com/store/apps/details?id=com.github.android&referrer=utm_campaign%3Dnotification-email%26utm_medium%3Demail%26utm_source%3Dgithub.

aphelionz commented 2 years ago

I believe this was updated in the latest PR, so closing