ipns实现机制解读

ipns是ipfs的域名系统。

前言

将ipns记录保存在dht之前,需要验证发布对象的真实性(有可能该对象是被别的节点冒用的),具体是通过检测签名是否与公钥和节点ID匹配,因此需要知道公钥。

ipfs init的时候,会自动生成RSA公私钥,通过对RSA公钥做multihash得到peerID,即peerID = multihash(pk)。

从v0.4.16开始,ipfs支持更新的ed25519算法生成公私钥,公钥可以嵌入到peerID中,因此不需要额外发送公钥。

从v0.4.16开始,/ipns完全足够work了。现在还保留/pk,主要是v0.4.16版本做了一次“软分叉”,使得v0.4.16以后的版本能把IpnsEntry存到v0.4.16以前的版本,但是以前的版本不能把IpnsEntry存到之后的版本,这对以前的版本不公平,却可以促进它们升级到更高版本,对整个网络是有利的。

ipfs通过dht.PutValue函数将ipns记录保存在本地以及其它peers的dht.datastore中;通过dht.GetValue函数从本地以及其它peers获取记录。

运行环境

版本: go-ipfs@v0.4.23 go-ipfs@v0.0.1

本文运行两个节点,一个在ubuntu,另外一个在windows,下文用ipfs1代表ubuntu端的ipfs,用ipfs2代表windows端的ipfs。两个节点将彼此的地址添加到彼此的bootstrap中,形成由2个节点组成的测试网。

两者的peerID分别为:

ipfs1: QmdvR13vcQvRUy8vrdK7g2guwLVB4fQZGSbNifERCz5iNT
ipfs2: Qmco9fPhEC9aYsFxY3ZekoUMZucmNa9soWDXh6xgr6FsJy

将bitswap/dht/eventlog的log等级设置为debug

$ ipfs log level bitswap debug & ipfs log level dht debug & ipfs log level eventlog debug & ipfs log level namesys debug & ipfs log level ipns-repub debug & ipfs log reprovider debug
[1] 4617
[2] 4618
Changed log level of 'dht' to 'debug'
Changed log level of 'bitswap' to 'debug'
Changed log level of 'eventlog' to 'debug'
[1]-  已完成               ipfs log level bitswap debug
[2]+  已完成               ipfs log level dht debug

普通操作

更新并发布ipns:

ipfs name publish
$ ipfs name publish QmStPNdn4LngCMAbw1nRS5YTsYDHr4HCbdy12y8uhsxS8o
Published to QmdvR13vcQvRUy8vrdK7g2guwLVB4fQZGSbNifERCz5iNT: /ipfs/QmStPNdn4LngCMAbw1nRS5YTsYDHr4HCbdy12y8uhsxS8o

log

18:43:37.010 DEBUG        dht: PutValue /pk/ 煍Hm+
3�#T˞�p�V
          {�w|!��m�5�0 routing.go:47
18:43:37.010 DEBUG        dht: getLocal /pk/ 煍Hm+
3�#T˞�p�V
          {�w|!��m�5�0 dht.go:245
18:43:37.010 DEBUG        dht: PutValue /ipns/ 煍Hm+
3�#T˞�p�V
          {�w|!��m�5�0 routing.go:47
18:43:37.010 DEBUG        dht: putLocal: /pk/ 煍Hm+
3�#T˞�p�V
          {�w|!��m�5�0 key:"/pk/\022 \347\205\215Hm+\n3\221\033#T\313\236\330p\372V\013{\276w|!\035\242\262m\2035\3010" value:"\010\000\022\246\0020\202\001\"0\r\006\t*\206H\206\367\r\001\001\001\005\000\003\202\001\017\0000\202\001\n\002\202\001\001\000\301\025\221\271Y\257D\254\373\372\200\rc\215\n\327\240>\255s*U\255\312\203\t\n_\244m\335\035\241\375\033\345$\236\024o).K\032\332&c\023uk\311\222\333\226\005\224O\206L\224\371\316\270\245\0062\023\255\252\236\224\372\320-\033\216\317~\221\325\216\304\236\246v\223*?\177\255\240\326\031\n\340?\277\231\036\010C\033jz!S\376r\313\226\331\346\375*\237\234\242\236\014\r\247\214\022-/\267\236\230\304\361L\244\244`b\322\305\005H\031\262H\221S\207!\271\263y/+\275@\267\002j\270l6`\273\331\331\355n\013\257-\334+\000p[\243B\300\376\354\035\234[\323B\035\217\340\254\326\330-&9y\311\307\032\325\263\201\001\355\334\334\270\0073\204*\2342;b\304@]%TP@t\312p\222\224:f\324u\025\234*S/\323ji\025\333\303T\353\314\201\217\tU\370'\007\355\002\351\350\r\301\013\002\003\001\000\001" timeReceived:"2020-02-19T02:43:37.010515835Z"  dht.go:263
18:43:37.010 DEBUG        dht: getLocal /ipns/ 煍Hm+
3�#T˞�p�V
          {�w|!��m�5�0 dht.go:245
18:43:37.011 DEBUG        dht: dialling Qmco9fPhEC9aYsFxY3ZekoUMZucmNa9soWDXh6xgr6FsJy took 0ms (as observed by the dht subsystem). dial_queue.go:331
18:43:37.011 DEBUG        dht: delivering dialled peer to DHT; took 0ms. dial_queue.go:186
18:43:37.011 DEBUG        dht: putLocal: /ipns/ 煍Hm+
3�#T˞�p�V
          {�w|!��m�5�0 key:"/ipns/\022 \347\205\215Hm+\n3\221\033#T\313\236\330p\372V\013{\276w|!\035\242\262m\2035\3010" value:"\n4/ipfs/QmStPNdn4LngCMAbw1nRS5YTsYDHr4HCbdy12y8uhsxS8o\022\200\002\021]\352\300:\3652.\252\336?\271\\\276\223&\255otsZ\231\372W~\177Z\377%V(\035\244\310\003y\311\003D\265\326\361U$&\007\223\230Z#Z\304\273\035<\006-\334\210\\\021\352\251$\r\217)#*\346\313\236\346\323\303\"R\335\372\377\336\"\347\323\341vY \244\177\327\334\335\351\341\3216\324\337\2423\324%\255\220\244*<\205\365\273\242\224\267\010#\202o\0323\325\273z&\023\255\246\033\303_\322\232\321G\262\000\273%\027Q\022\252\314B\204\266\014U\251\257E\233\375U\035e@95\230<\347T\360\201;\004\217\372\211\215\202\377\2373\036\210,\304_M\220Xm\301p\034$`iG\274q\004\271.%\235\226CR\206\020\310H\365\260\263\335\343\001\236\263e2\004V\265\266\355w7.C\303\2055\023\014=?\273u]\3101\010i\335f\343![0\216\013P\222g\245\327\031\251M\"M\030\000\"\0362020-02-20T02:43:37.005860075Z(\t:\253\002\010\000\022\246\0020\202\001\"0\r\006\t*\206H\206\367\r\001\001\001\005\000\003\202\001\017\0000\202\001\n\002\202\001\001\000\301\025\221\271Y\257D\254\373\372\200\rc\215\n\327\240>\255s*U\255\312\203\t\n_\244m\335\035\241\375\033\345$\236\024o).K\032\332&c\023uk\311\222\333\226\005\224O\206L\224\371\316\270\245\0062\023\255\252\236\224\372\320-\033\216\317~\221\325\216\304\236\246v\223*?\177\255\240\326\031\n\340?\277\231\036\010C\033jz!S\376r\313\226\331\346\375*\237\234\242\236\014\r\247\214\022-/\267\236\230\304\361L\244\244`b\322\305\005H\031\262H\221S\207!\271\263y/+\275@\267\002j\270l6`\273\331\331\355n\013\257-\334+\000p[\243B\300\376\354\035\234[\323B\035\217\340\254\326\330-&9y\311\307\032\325\263\201\001\355\334\334\270\0073\204*\2342;b\304@]%TP@t\312p\222\224:f\324u\025\234*S/\323ji\025\333\303T\353\314\201\217\tU\370'\007\355\002\351\350\r\301\013\002\003\001\000\001" timeReceived:"2020-02-19T02:43:37.01125562Z"  dht.go:263
18:43:37.011 DEBUG        dht: dialling Qmco9fPhEC9aYsFxY3ZekoUMZucmNa9soWDXh6xgr6FsJy took 0ms (as observed by the dht subsystem). dial_queue.go:331
18:43:37.012 DEBUG        dht: delivering dialled peer to DHT; took 0ms. dial_queue.go:186
18:43:37.012 DEBUG        dht: QUERY worker for: Qmco9fPhEC9aYsFxY3ZekoUMZucmNa9soWDXh6xgr6FsJy - not found, and no closer peers. query.go:312
18:43:37.012 DEBUG        dht: closestPeers query run error: routing: not found lookup.go:98
18:43:37.013 DEBUG        dht: QUERY worker for: Qmco9fPhEC9aYsFxY3ZekoUMZucmNa9soWDXh6xgr6FsJy - not found, and no closer peers. query.go:312
18:43:37.013 DEBUG        dht: closestPeers query run error: routing: not found lookup.go:98

从log可知,ipfs1前后putValue了2个ipns记录,一个是/ipns,另外一个是/pk。

ipfs1通过调用PutValue函数,PutValue函数会首先检查传入的IpfsEntry(ipns记录)的签名和有效期,接着决定是否更新当前的IpfsEntry,更新的标准是: 先看Sequence,再看Validity,最后看Value。

相比旧的IpfsEntry,传入的Sequence比较大则更新;比较小则返回错误;相等看Validity,传入的Validity比较大更新,比较小返回错误,相等的话,再对比Value,如果Value还是一样,代表两个IpfsEntry一样,更新记录。换言之,该机制主要用于防止旧的记录覆盖新的记录。

如果全部检验通过,ipfs1会首先把IpfsEntry记录存到本地(dht.datastore),接着计算/ipns/xxx这个key的sha256,然后和ipfs1 peerID计算距离,从ipfs1的routingTable选出alpha个距离最近的节点,向它们发送put_value消息,内容是最新的IpfsEntry;

ipfs2收到ipfs1的put_value消息后,首先也会检查传入的IpfsEntry(ipns记录)的签名和有效期,接着决定是否更新当前的IpfsEntry,更新标准同上。

以下是IpnsEntry的结构:

type IpnsEntry struct {
	Value        []byte                  `protobuf:"bytes,1,req,name=value" json:"value,omitempty"`
	Signature    []byte                  `protobuf:"bytes,2,req,name=signature" json:"signature,omitempty"`
	ValidityType *IpnsEntry_ValidityType `protobuf:"varint,3,opt,name=validityType,enum=ipns.pb.IpnsEntry_ValidityType" json:"validityType,omitempty"`
	Validity     []byte                  `protobuf:"bytes,4,opt,name=validity" json:"validity,omitempty"`
	Sequence     *uint64                 `protobuf:"varint,5,opt,name=sequence" json:"sequence,omitempty"`
	Ttl          *uint64                 `protobuf:"varint,6,opt,name=ttl" json:"ttl,omitempty"`
	// in order for nodes to properly validate a record upon receipt, they need the public
	// key associated with it. For old RSA keys, its easiest if we just send this as part of
	// the record itself. For newer ed25519 keys, the public key can be embedded in the
	// peerID, making this field unnecessary.
	PubKey               []byte   `protobuf:"bytes,7,opt,name=pubKey" json:"pubKey,omitempty"`

其中,value就是刚刚name publish后的值,在本文是QmStPNdn4LngCMAbw1nRS5YTsYDHr4HCbdy12y8uhsxS8o。

Validity是有效期,默认是24h,超过该有效期,这个记录就是无效的。

Sequence用于标识版本,Sequence越大表示越新,只有value变动了,Sequence才加1。存储前先判断自己是否有这个记录,如果没有,验证签名和有效期通过后保存;如果有,取出记录,对比Sequence,如果新记录的Sequence更大,则保存新记录。

Ttl(Time to live),作用等同于ping中TTL。

默认republish时间

ipfs config文件

"Ipns": {
    "RecordLifetime": "",
    "RepublishPeriod": "",
    "ResolveCacheSize": 128
  }

默认republish时间为4h,默认记录有效期为24h

// DefaultRebroadcastInterval is the default interval at which we rebroadcast IPNS records
var DefaultRebroadcastInterval = time.Hour * 4

// InitialRebroadcastDelay is the delay before first broadcasting IPNS records on start
var InitialRebroadcastDelay = time.Minute * 1

// FailureRetryInterval is the interval at which we retry IPNS records broadcasts (when they fail)
var FailureRetryInterval = time.Minute * 5

// DefaultRecordLifetime is the default lifetime for IPNS records
const DefaultRecordLifetime = time.Hour * 24
ipfs name resolve

ipfs1 name resolve

$ ipfs name resolve /ipns/QmdvR13vcQvRUy8vrdK7g2guwLVB4fQZGSbNifERCz5iNT
/ipfs/QmStPNdn4LngCMAbw1nRS5YTsYDHr4HCbdy12y8uhsxS8o

ipfs1 log

01:37:11.910 DEBUG    namesys: RoutingResolver resolving QmdvR13vcQvRUy8vrdK7g2guwLVB4fQZGSbNifERCz5iNT routing.go:53
01:37:11.910 DEBUG        dht: getPublicKey for: QmdvR13vcQvRUy8vrdK7g2guwLVB4fQZGSbNifERCz5iNT records.go:27
01:37:11.910 DEBUG        dht: getLocal /ipns/ 煍Hm+
3�#T˞�p�V
          {�w|!��m�5�0 dht.go:245
01:37:11.911 DEBUG        dht: have it locally routing.go:290
01:37:11.911 DEBUG        dht: peers in rt: 1 [Qmco9fPhEC9aYsFxY3ZekoUMZucmNa9soWDXh6xgr6FsJy] routing.go:307
01:37:11.911 DEBUG        dht: dialling Qmco9fPhEC9aYsFxY3ZekoUMZucmNa9soWDXh6xgr6FsJy took 0ms (as observed by the dht subsystem). dial_queue.go:331
01:37:11.911 DEBUG    namesys: resolved /ipns/QmdvR13vcQvRUy8vrdK7g2guwLVB4fQZGSbNifERCz5iNT to /ipfs/QmStPNdn4LngCMAbw1nRS5YTsYDHr4HCbdy12y8uhsxS8o base.go:69
01:37:11.913 DEBUG        dht: getValueOrPeers: got value dht.go:197
01:37:11.913 DEBUG        dht: QUERY worker for: Qmco9fPhEC9aYsFxY3ZekoUMZucmNa9soWDXh6xgr6FsJy - not found, and no closer peers. query.go:312

ipfs2 log

17:42:14.044 DEBUG        dht: Qmco9fPhEC9aYsFxY3ZekoUMZucmNa9soWDXh6xgr6FsJy handleGetValue for key: /ipns/ 煍Hm+
3�#T˞�p�V{�w|!��m�5�0 handlers.go:51
17:42:14.044 DEBUG        dht: Qmco9fPhEC9aYsFxY3ZekoUMZucmNa9soWDXh6xgr6FsJy handleGetValue looking into ds handlers.go:90
17:42:14.044 DEBUG        dht: Qmco9fPhEC9aYsFxY3ZekoUMZucmNa9soWDXh6xgr6FsJy handleGetValue looking into ds GOT [10 40 47 105 112 110 115 47 18 32 231 133 141 72 109 43 10 51 145 27 35 84 203 158 216 112 250 86 11 123 190 119 124 33 29 162 178 109 131 53 193 48 18 139 5 10 52 47 105 112 102 115 47 81 109 83 116 80 78 100 110 52 76 110 103 67 77 65 98 119 49 110 82 83 53 89 84 115 89 68 72 114 52 72 67 98 100 121 49 50 121 56 117 104 115 120 83 56 111 18 128 2 144 152 67 228 238 174 28 125 246 248 183 187 74 71 183 93 243 152 131 185 173 94 173 151 83 82 151 107 222 112 3 213 29 87 18 251 76 147 149 69 224 90 101 163 0 69 224 136 204 233 13 75 130 115 245 12 157 96 71 209 146 192 72 69 52 142 184 92 36 254 211 134 178 24 96 25 117 64 84 195 214 196 47 6 211 59 174 174 69 112 240 89 133 73 215 45 54 145 95 229 138 108 118 106 223 43 224 74 237 207 11 171 80 26 33 165 18 16 97 109 9 151 3 13 13 112 94 143 216 45 253 47 61 254 188 168 21 250 99 120 219 184 135 55 150 242 81 222 141 110 197 192 149 224 122 182 132 139 246 128 84 237 208 169 200 131 195 175 234 242 76 21 175 115 21 101 187 216 145 72 74 57 71 30 11 175 31 131 232 165 116 229 219 227 116 29 249 202 143 24 163 159 125 92 80 68 39 6 8 234 250 73 22 1 58 249 16 48 9 31 118 45 29 184 76 33 241 78 126 205 251 35 154 132 192 20 190 15 35 240 254 109 152 144 231 28 247 107 47 241 198 120 222 135 13 243 24 0 34 30 50 48 50 48 45 48 50 45 50 48 84 48 56 58 49 53 58 49 48 46 53 56 57 54 56 54 54 53 57 90 40 9 58 171 2 8 0 18 166 2 48 130 1 34 48 13 6 9 42 134 72 134 247 13 1 1 1 5 0 3 130 1 15 0 48 130 1 10 2 130 1 1 0 193 21 145 185 89 175 68 172 251 250 128 13 99 141 10 215 160 62 173 115 42 85 173 202 131 9 10 95 164 109 221 29 161 253 27 229 36 158 20 111 41 46 75 26 218 38 99 19 117 107 201 146 219 150 5 148 79 134 76 148 249 206 184 165 6 50 19 173 170 158 148 250 208 45 27 142 207 126 145 213 142 196 158 166 118 147 42 63 127 173 160 214 25 10 224 63 191 153 30 8 67 27 106 122 33 83 254 114 203 150 217 230 253 42 159 156 162 158 12 13 167 140 18 45 47 183 158 152 196 241 76 164 164 96 98 210 197 5 72 25 178 72 145 83 135 33 185 179 121 47 43 189 64 183 2 106 184 108 54 96 187 217 217 237 110 11 175 45 220 43 0 112 91 163 66 192 254 236 29 156 91 211 66 29 143 224 172 214 216 45 38 57 121 201 199 26 213 179 129 1 237 220 220 184 7 51 132 42 156 50 59 98 196 64 93 37 84 80 64 116 202 112 146 148 58 102 212 117 21 156 42 83 47 211 106 105 21 219 195 84 235 204 129 143 9 85 248 39 7 237 2 233 232 13 193 11 2 3 1 0 1 42 28 50 48 50 48 45 48 50 45 49 57 84 48 56 58 49 52 58 50 52 46 51 51 50 55 53 54 53 90] handlers.go:93
17:42:14.044 DEBUG        dht: Qmco9fPhEC9aYsFxY3ZekoUMZucmNa9soWDXh6xgr6FsJy handleGetValue success! handlers.go:105

name resolve /ipns/xxx的时候,ipfs1首先会解析peerID,看能否获得peerID对应publicKey。接着调用SearchValue,SearchValue先从本地(dht.datastore)中查,由于不知道当前该记录是否为最新的记录,不管本地有没有这个记录,ipfs2会先计算/ipns/xxx这个key的sha256,然后和ipfs1 peerID计算距离,从ipfs1的routingTable选出alpha个距离最近的节点,向他们发送get_value消息,询问ipns/xxx这个key对应的value。

ipfs2收到get_value请求后,首先从本地(dht.datastore)中查找,由于不知道当前该记录是否为最新的记录,不管本地有没有这个记录,ipfs2都会从routingTable选出K(现为20)个距离记录sha256("/ipns/xxx")最近的节点(closerPeers),将节点信息(closerPeers)和记录(两者都可为空)发给ipfs1。

ipfs1收到ipfs2的回复后,如果resp中有记录就将其收集起来,如果resp中有closerPeers,则将它们添加到peerstore.AddrBook(值得注意的是,该AddrBook带有超时机制),以便接下来向它们发起get_value查询请求。

ipfs1最后把本地和从网络询问到的IpfsEntry收集起来,选出最新的IpfsEntry(新旧的判断标准同上文),如果发现本地的记录是旧的或者本地原本没记录,就更新本地记录;如果发现其它节点发过来的IpfsEntry是旧的,就向它们发送put value消息,内容是最新的IpfsEntry,以更新它们的记录。对于那些回复中不带有IpfsEntry的节点,原来就不存该记录(IpfsEntry),所以不会给它们put value。

ipfs cat /ipns/xxx

ipfs2 cat /ipns/xxx

$ ipfs cat /ipns/QmdvR13vcQvRUy8vrdK7g2guwLVB4fQZGSbNifERCz5iNT
Hello, Now is midnight

ipfs1 log

08:02:58.587 DEBUG        dht: QmdvR13vcQvRUy8vrdK7g2guwLVB4fQZGSbNifERCz5iNT handleGetValue for key: /ipns/ 煍Hm+
3�#T˞�p�V
          {�w|!��m�5�0 handlers.go:51
08:02:58.587 DEBUG        dht: QmdvR13vcQvRUy8vrdK7g2guwLVB4fQZGSbNifERCz5iNT handleGetValue looking into ds handlers.go:90
08:02:58.587 DEBUG        dht: QmdvR13vcQvRUy8vrdK7g2guwLVB4fQZGSbNifERCz5iNT handleGetValue looking into ds GOT [10 40 47 105 112 110 115 47 18 32 231 133 141 72 109 43 10 51 145 27 35 84 203 158 216 112 250 86 11 123 190 119 124 33 29 162 178 109 131 53 193 48 18 139 5 10 52 47 105 112 102 115 47 81 109 83 116 80 78 100 110 52 76 110 103 67 77 65 98 119 49 110 82 83 53 89 84 115 89 68 72 114 52 72 67 98 100 121 49 50 121 56 117 104 115 120 83 56 111 18 128 2 111 51 121 114 140 69 130 232 189 19 234 222 79 13 25 90 20 239 252 200 98 249 140 229 109 91 146 195 5 207 29 1 190 62 167 12 248 144 8 224 191 74 0 137 73 165 165 193 203 250 120 219 30 193 173 87 66 30 221 233 203 79 184 227 82 21 184 160 241 152 25 129 137 17 162 182 3 191 180 163 14 50 30 227 242 187 234 36 49 253 56 67 152 83 190 166 253 115 20 118 135 213 155 154 150 126 100 195 250 197 97 82 34 212 164 62 144 244 111 51 23 255 71 93 185 15 89 67 154 64 145 68 33 147 126 194 62 46 180 212 193 109 4 142 229 20 72 103 98 211 130 17 237 25 183 194 160 27 27 0 80 196 203 5 202 36 8 215 7 244 178 199 124 249 73 33 231 125 63 139 52 187 155 81 192 142 173 12 1 62 132 95 135 168 83 219 75 13 13 232 138 90 135 142 92 201 88 100 97 200 135 219 215 47 76 133 221 220 104 212 159 115 39 153 226 152 15 176 157 250 160 188 42 225 67 21 180 40 44 74 205 51 162 85 200 38 249 214 153 7 180 250 208 104 161 151 24 0 34 30 50 48 50 48 45 48 50 45 49 55 84 49 54 58 48 48 58 48 50 46 48 48 55 50 57 54 48 53 53 90 40 2 58 171 2 8 0 18 166 2 48 130 1 34 48 13 6 9 42 134 72 134 247 13 1 1 1 5 0 3 130 1 15 0 48 130 1 10 2 130 1 1 0 193 21 145 185 89 175 68 172 251 250 128 13 99 141 10 215 160 62 173 115 42 85 173 202 131 9 10 95 164 109 221 29 161 253 27 229 36 158 20 111 41 46 75 26 218 38 99 19 117 107 201 146 219 150 5 148 79 134 76 148 249 206 184 165 6 50 19 173 170 158 148 250 208 45 27 142 207 126 145 213 142 196 158 166 118 147 42 63 127 173 160 214 25 10 224 63 191 153 30 8 67 27 106 122 33 83 254 114 203 150 217 230 253 42 159 156 162 158 12 13 167 140 18 45 47 183 158 152 196 241 76 164 164 96 98 210 197 5 72 25 178 72 145 83 135 33 185 179 121 47 43 189 64 183 2 106 184 108 54 96 187 217 217 237 110 11 175 45 220 43 0 112 91 163 66 192 254 236 29 156 91 211 66 29 143 224 172 214 216 45 38 57 121 201 199 26 213 179 129 1 237 220 220 184 7 51 132 42 156 50 59 98 196 64 93 37 84 80 64 116 202 112 146 148 58 102 212 117 21 156 42 83 47 211 106 105 21 219 195 84 235 204 129 143 9 85 248 39 7 237 2 233 232 13 193 11 2 3 1 0 1 42 30 50 48 50 48 45 48 50 45 49 54 84 49 54 58 48 48 58 48 50 46 48 49 48 56 55 54 49 56 51 90] handlers.go:93
08:02:58.587 DEBUG        dht: QmdvR13vcQvRUy8vrdK7g2guwLVB4fQZGSbNifERCz5iNT handleGetValue success! handlers.go:105
08:02:58.590  INFO    bitswap: Sending block [Block QmStPNdn4LngCMAbw1nRS5YTsYDHr4HCbdy12y8uhsxS8o] to Qmco9fPhEC9aYsFxY3ZekoUMZucmNa9soWDXh6xgr6FsJy workers.go:94
08:02:58.601 DEBUG        dht: QmdvR13vcQvRUy8vrdK7g2guwLVB4fQZGSbNifERCz5iNT adding Qmco9fPhEC9aYsFxY3ZekoUMZucmNa9soWDXh6xgr6FsJy as a provider for 'QmStPNdn4LngCMAbw1nRS5YTsYDHr4HCbdy12y8uhsxS8o'
 handlers.go:351
08:02:58.602 DEBUG        dht: received provider Qmco9fPhEC9aYsFxY3ZekoUMZucmNa9soWDXh6xgr6FsJy for QmStPNdn4LngCMAbw1nRS5YTsYDHr4HCbdy12y8uhsxS8o (addrs: [/ip4/192.168.1.3/tcp/4001 /ip4/169.254.72.9/tcp/4001 /ip4/192.168.56.1/tcp/4001 /ip4/192.168.25.1/tcp/4001 /ip4/192.168.5.1/tcp/4001 /ip4/127.0.0.1/tcp/4001 /ip6/2409:8a55:435:8000:48b9:2f2b:e352:4f47/tcp/4001 /ip6/2409:8a55:435:8000:b4b1:84fe:321b:8183/tcp/4001 /ip6/::1/tcp/4001]) handlers.go:368

ipfs2 log

00:02:17.476 DEBUG        dht: getPublicKey for: QmdvR13vcQvRUy8vrdK7g2guwLVB4fQZGSbNifERCz5iNT records.go:27
00:02:17.477 DEBUG        dht: getLocal /ipns/ 煍Hm+
3�#T˞�p�V{�w|!��m�5�0 dht.go:245
00:02:17.477 DEBUG        dht: have it locally routing.go:290
00:02:17.477 DEBUG        dht: peers in rt: 1 [QmdvR13vcQvRUy8vrdK7g2guwLVB4fQZGSbNifERCz5iNT] routing.go:307
00:02:17.477 DEBUG        dht: dialling QmdvR13vcQvRUy8vrdK7g2guwLVB4fQZGSbNifERCz5iNT took 0ms (as observed by the dht subsystem). dial_queue.go:331
00:02:17.477 DEBUG        dht: delivering dialled peer to DHT; took 0ms. dial_queue.go:186
00:02:17.479 DEBUG        dht: getValueOrPeers: got value dht.go:197
00:02:17.479 DEBUG        dht: QUERY worker for: QmdvR13vcQvRUy8vrdK7g2guwLVB4fQZGSbNifERCz5iNT - not found, and no closer peers. query.go:312
00:02:17.480  INFO    bitswap: want blocks: [QmStPNdn4LngCMAbw1nRS5YTsYDHr4HCbdy12y8uhsxS8o] wantmanager.go:73
00:02:17.482 DEBUG    bitswap: got block [Block QmStPNdn4LngCMAbw1nRS5YTsYDHr4HCbdy12y8uhsxS8o] from QmdvR13vcQvRUy8vrdK7g2guwLVB4fQZGSbNifERCz5iNT bitswap.go:337
00:02:17.486 DEBUG        dht: Provide  QmStPNdn4LngCMAbw1nRS5YTsYDHr4HCbdy12y8uhsxS8o routing.go:407

ipfs2通过dht调用GetValue函数,GetValue函数会调用SearchValue函数寻找记录,SearchValue具体过程同上文"ipns resolve"中描述的过程一样。

ipfs2拿到最新的记录后,解析该记录,得到一个block的CID,ipfs1在自己的datastore找这个block,如果找不到,则通过bitswap向ipfs1发送wantlist请求,在拿到块后,向DHT网络provide了这个块,表明自己提供这个块的下载。

指定操作

当前生成的key如下:
$ ipfs key list -l
QmdvR13vcQvRUy8vrdK7g2guwLVB4fQZGSbNifERCz5iNT self   

self就是节点ID,是默认的key。

ipfs name publish命令的完整形式如下:
ipfs name publish [--resolve=false] [--lifetime=<lifetime> | -t] [--allow-offline] [--ttl=<ttl>] [--key=<key> | -k] [--quieter | -Q] [--]
                    <ipfs-path>

key参数用于指定ipns使用哪个key,不指定的话默认使用self

使用ed25519生成公私钥对
$ ipfs key gen -t ed25519 -s 2048 edKey
12D3KooWSWds5zGmaSVg7ig412MVmAEK98QN456ZFTKxU1NYiwUy

$ ipfs key list -l
QmdvR13vcQvRUy8vrdK7g2guwLVB4fQZGSbNifERCz5iNT       self   
12D3KooWSWds5zGmaSVg7ig412MVmAEK98QN456ZFTKxU1NYiwUy edKey   

ipfs name publish的时候使用新创建的edKey
$ ipfs name publish -k edKey QmStPNdn4LngCMAbw1nRS5YTsYDHr4HCbdy12y8uhsxS8o
Published to 12D3KooWSWds5zGmaSVg7ig412MVmAEK98QN456ZFTKxU1NYiwUy: /ipfs/QmStPNdn4LngCMAbw1nRS5YTsYDHr4HCbdy12y8uhsxS8o

log

19:15:46.042 DEBUG        dht: getLocal /ipns/ �
                                                  �_���"�:K43{��B�(���P���A<�D�� dht.go:245
19:15:46.042 DEBUG        dht: peers in rt: 1 [Qmco9fPhEC9aYsFxY3ZekoUMZucmNa9soWDXh6xgr6FsJy] routing.go:307
19:15:46.043 DEBUG        dht: dialling Qmco9fPhEC9aYsFxY3ZekoUMZucmNa9soWDXh6xgr6FsJy took 0ms (as observed by the dht subsystem). dial_queue.go:331
19:15:46.043 DEBUG        dht: delivering dialled peer to DHT; took 0ms. dial_queue.go:186
19:15:46.044 WARNI        dht: getValueOrPeers: routing.ErrNotFound dht.go:215
19:15:46.044 DEBUG        dht: ERROR worker for: Qmco9fPhEC9aYsFxY3ZekoUMZucmNa9soWDXh6xgr6FsJy routing: not found query.go:286
19:15:46.044 DEBUG        dht: loggableKey could not cast key to a CID: 2f69706e732f002408011220f80bf85f95f0fe22b23a4b34337bc18b42a928e6d6ff50e4f1ab413cb444d5e6 expected 1 as the cid version number, got: 0 lookup.go:44
19:15:46.044 DEBUG        dht: PutValue /ipns/ �
                                                  �_���"�:K43{��B�(���P���A<�D�� routing.go:47
19:15:46.044 DEBUG        dht: getLocal /ipns/ �
                                                  �_���"�:K43{��B�(���P���A<�D�� dht.go:245
19:15:46.045 DEBUG        dht: putLocal: /ipns/ �
                                                   �_���"�:K43{��B�(���P���A<�D�� key:"/ipns/\000$\010\001\022 \370\013\370_\225\360\376\"\262:K43{\301\213B\251(\346\326\377P\344\361\253A<\264D\325\346" value:"\n4/ipfs/QmStPNdn4LngCMAbw1nRS5YTsYDHr4HCbdy12y8uhsxS8o\022@N\025\263!s\325\224\303F,`\3201u&\253\255\237\036\300\003\366{\321\340;\225\353\221\373Zu\226\345O\223oC\375\r\244\343Q\206\030\031\006\307s\315N\356\257\276[\r\234_\031\217\204\373\006\010\030\000\"\0362020-02-20T03:15:46.042676531Z(\000" timeReceived:"2020-02-19T03:15:46.045003755Z"  dht.go:263
19:15:46.045 DEBUG        dht: loggableKey could not cast key to a CID: 2f69706e732f002408011220f80bf85f95f0fe22b23a4b34337bc18b42a928e6d6ff50e4f1ab413cb444d5e6 expected 1 as the cid version number, got: 0 lookup.go:44
19:15:46.045 DEBUG        dht: dialling Qmco9fPhEC9aYsFxY3ZekoUMZucmNa9soWDXh6xgr6FsJy took 0ms (as observed by the dht subsystem). dial_queue.go:331
19:15:46.045 DEBUG        dht: delivering dialled peer to DHT; took 0ms. dial_queue.go:186
19:15:46.045 DEBUG        dht: QUERY worker for: Qmco9fPhEC9aYsFxY3ZekoUMZucmNa9soWDXh6xgr6FsJy - not found, and no closer peers. query.go:312
19:15:46.045 DEBUG        dht: closestPeers query run error: routing: not found lookup.go:98
19:15:46.046 DEBUG        dht: loggableKey could not cast key to a CID: 2f69706e732f002408011220f80bf85f95f0fe22b23a4b34337bc18b42a928e6d6ff50e4f1ab413cb444d5e6 expected 1 as the cid version number, got: 0 lookup.go:44

由log可以看出,此处只有/ipns,不再有/pk,因为用的是通过ed25519生成的key,可以通过peerID反推出pk,继而检验/ipns记录的真实性。

当ipfs name publish时,如果使用的是RSA生成的key,IpnsEntry(也就是ipns记录)中的PubKey字段记录了公钥,存储到DHT之前(即使是自己也)需要先使用该公钥验证entry中的签名,验证通过方可存储,以保证存储对象可信。

如果使用的是ed25519生成的key,IpnsEntry(也就是ipns记录)中的PubKey字段是空的,因为通过peerID就可以反推出公钥。

v0.4.16之前的做法是:

IpnsEntry没有PubKey这个字段,通过DHT中的putValue存2条记录,一条是/ipns,key是/ipns/ p e e r I D , v a l u e 是 I p n s E n t r y ; 另 外 一 条 是 / p k , k e y 是 / p k / peerID, value是IpnsEntry;另外一条是/pk,key是/pk/ peerID,valueIpnsEntry/pkkey/pk/peerID,value是PublicKey,即公钥存在另外一条记录,通过peerID即可获得。可见,现在(V0.4.15以后)的做法更加合理。

从上面我们可以知道,这个版本(v0.4.23)的ipfs,/ipns完全能够work了。现在还保留/pk,主要是v0.4.16版本做了一次“软分叉”,使得v0.4.16以后的版本能把IpnsEntry存到v0.4.16以前的版本,但是以前的版本不能把IpnsEntry存到之后的版本,这对以前的版本不公平,却可以促进它们升级到更高版本,对整个网络是有利的。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值