Skip to content
ipfs-http-clientやっと解決2
sand-box
2021-11-04

こける前に書いた
https://akibakokoubou.jp/2021/10/06/プログラマのための-system-7-system-7-revealed
をやっとで掲載。

あと少し修正要だった。

markdown
UnhandledPromiseRejectionWarning: TypeError: Invalid DAG-PB form (links must be sorted by Name bytes)
UnhandledPromiseRejectionWarning: TypeError: Invalid DAG-PB form (links must be sorted by Name bytes)

と出たのでなにかと思ったら、リンクはバイト形式でソートされていないといけないそうだ。
https://github.com/ipld/specs/blob/master/block-layer/codecs/dag-pb.md

markdown
elements must be sorted in ascending order by their Name values, which are compared by bytes rather than as strings
elements must be sorted in ascending order by their Name values, which are compared by bytes rather than as strings
typescript
//  import追加と置き換え
import { CID } from 'multiformats/cid'
import {PBLink} from "@ipld/dag-pb";
import * as dagPB from '@ipld/dag-pb'

//  記事ノードを作る
const imgDirNode = dagPB.createNode(new Uint8Array(), imgList)
const imdDirCid = await this.client.dag.put(imgDirNode)
const imgDirLink = dagPB.createLink("images", 0, imdDirCid)
const indexNode = dagPB.createNode(new TextEncoder().encode(mdBody))
const indexCid = await this.client.dag.put(indexNode)
const indexLink = dagPB.createLink("index.md", 0, indexCid)
const list = [indexLink, imgDirLink]
const postNode = dagPB.createNode(new TextEncoder().encode(slug), list);

// 既存の記事リンクを取ってくる
  const originalChildren = await this.client.dag.get(CID.parse(rootCid));
  const nextChildList: PBLink[] = originalChildren.value.Links

// 記事リンクを追加する
  const addLink = dagPB.createLink(addName, 0, CID.parse(addCid));
  nextChildList.push(addLink)
  const sorted = nextChildList.sort((a, b) => {
    if (a.Name && b.Name) {
      return this.compareBytes(enc.encode(a.Name), enc.encode(b.Name))
    }
    return 0;
  })


// 新しいrootを追加する
  const root = await this.client.dag.put({Data: new Uint8Array(), Links: sorted}, {
    // @ts-ignore
    "store-codec": 'dag-pb',
    "input-codec": 'dag-pb',
    format: 'dag-pb',
    pin: true
  });
// 単純バイトソート
compareBytes(a: Uint8Array, b: Uint8Array) {
  const len = Math.max(a.length,b.length)
  for (let i = 0; i < len; i++) {
    const k = a[i] - b[i]
    if (k != 0) {
      return k
    }
  }
  return a.length - b.length
}
//  import追加と置き換え
import { CID } from 'multiformats/cid'
import {PBLink} from "@ipld/dag-pb";
import * as dagPB from '@ipld/dag-pb'

//  記事ノードを作る
const imgDirNode = dagPB.createNode(new Uint8Array(), imgList)
const imdDirCid = await this.client.dag.put(imgDirNode)
const imgDirLink = dagPB.createLink("images", 0, imdDirCid)
const indexNode = dagPB.createNode(new TextEncoder().encode(mdBody))
const indexCid = await this.client.dag.put(indexNode)
const indexLink = dagPB.createLink("index.md", 0, indexCid)
const list = [indexLink, imgDirLink]
const postNode = dagPB.createNode(new TextEncoder().encode(slug), list);

// 既存の記事リンクを取ってくる
  const originalChildren = await this.client.dag.get(CID.parse(rootCid));
  const nextChildList: PBLink[] = originalChildren.value.Links

// 記事リンクを追加する
  const addLink = dagPB.createLink(addName, 0, CID.parse(addCid));
  nextChildList.push(addLink)
  const sorted = nextChildList.sort((a, b) => {
    if (a.Name && b.Name) {
      return this.compareBytes(enc.encode(a.Name), enc.encode(b.Name))
    }
    return 0;
  })


// 新しいrootを追加する
  const root = await this.client.dag.put({Data: new Uint8Array(), Links: sorted}, {
    // @ts-ignore
    "store-codec": 'dag-pb',
    "input-codec": 'dag-pb',
    format: 'dag-pb',
    pin: true
  });
// 単純バイトソート
compareBytes(a: Uint8Array, b: Uint8Array) {
  const len = Math.max(a.length,b.length)
  for (let i = 0; i < len; i++) {
    const k = a[i] - b[i]
    if (k != 0) {
      return k
    }
  }
  return a.length - b.length
}