Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
G
go-ipfs
概览
概览
详情
活动
周期分析
版本库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
统计图
问题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
日程表
图表
维基
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
图像
聊天
创建新问题
作业
提交
问题看板
Open sidebar
jihao
go-ipfs
Commits
a4388624
提交
a4388624
authored
8月 10, 2014
作者:
Jeromy
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
more work implementing coral type lookups
上级
67ddab1e
全部展开
隐藏空白字符变更
内嵌
并排
正在显示
6 个修改的文件
包含
336 行增加
和
183 行删除
+336
-183
dht.go
routing/dht/dht.go
+113
-98
dht_test.go
routing/dht/dht_test.go
+91
-20
routing.go
routing/dht/routing.go
+74
-63
util.go
routing/kbucket/util.go
+18
-2
swarm.go
swarm/swarm.go
+14
-0
util.go
util/util.go
+26
-0
没有找到文件。
routing/dht/dht.go
浏览文件 @
a4388624
差异被折叠。
点击展开。
routing/dht/dht_test.go
浏览文件 @
a4388624
...
...
@@ -11,6 +11,37 @@ import (
"time"
)
func
setupDHTS
(
n
int
,
t
*
testing
.
T
)
([]
*
ma
.
Multiaddr
,
[]
*
peer
.
Peer
,
[]
*
IpfsDHT
)
{
var
addrs
[]
*
ma
.
Multiaddr
for
i
:=
0
;
i
<
4
;
i
++
{
a
,
err
:=
ma
.
NewMultiaddr
(
fmt
.
Sprintf
(
"/ip4/127.0.0.1/tcp/%d"
,
5000
+
i
))
if
err
!=
nil
{
t
.
Fatal
(
err
)
}
addrs
=
append
(
addrs
,
a
)
}
var
peers
[]
*
peer
.
Peer
for
i
:=
0
;
i
<
4
;
i
++
{
p
:=
new
(
peer
.
Peer
)
p
.
AddAddress
(
addrs
[
i
])
p
.
ID
=
peer
.
ID
([]
byte
(
fmt
.
Sprintf
(
"peer_%d"
,
i
)))
peers
=
append
(
peers
,
p
)
}
var
dhts
[]
*
IpfsDHT
for
i
:=
0
;
i
<
4
;
i
++
{
d
,
err
:=
NewDHT
(
peers
[
i
])
if
err
!=
nil
{
t
.
Fatal
(
err
)
}
dhts
=
append
(
dhts
,
d
)
d
.
Start
()
}
return
addrs
,
peers
,
dhts
}
func
TestPing
(
t
*
testing
.
T
)
{
u
.
Debug
=
false
addr_a
,
err
:=
ma
.
NewMultiaddr
(
"/ip4/127.0.0.1/tcp/2222"
)
...
...
@@ -90,11 +121,13 @@ func TestValueGetSet(t *testing.T) {
dht_a
.
Start
()
dht_b
.
Start
()
errsa
:=
dht_a
.
network
.
GetChan
()
.
Errors
errsb
:=
dht_b
.
network
.
GetChan
()
.
Errors
go
func
()
{
select
{
case
err
:=
<-
dht_a
.
network
.
Chan
.
Errors
:
case
err
:=
<-
errsa
:
t
.
Fatal
(
err
)
case
err
:=
<-
dht_b
.
network
.
Chan
.
Errors
:
case
err
:=
<-
errsb
:
t
.
Fatal
(
err
)
}
}()
...
...
@@ -118,6 +151,52 @@ func TestValueGetSet(t *testing.T) {
func
TestProvides
(
t
*
testing
.
T
)
{
u
.
Debug
=
false
addrs
,
_
,
dhts
:=
setupDHTS
(
4
,
t
)
_
,
err
:=
dhts
[
0
]
.
Connect
(
addrs
[
1
])
if
err
!=
nil
{
t
.
Fatal
(
err
)
}
_
,
err
=
dhts
[
1
]
.
Connect
(
addrs
[
2
])
if
err
!=
nil
{
t
.
Fatal
(
err
)
}
_
,
err
=
dhts
[
1
]
.
Connect
(
addrs
[
3
])
if
err
!=
nil
{
t
.
Fatal
(
err
)
}
err
=
dhts
[
3
]
.
PutLocal
(
u
.
Key
(
"hello"
),
[]
byte
(
"world"
))
if
err
!=
nil
{
t
.
Fatal
(
err
)
}
err
=
dhts
[
3
]
.
Provide
(
u
.
Key
(
"hello"
))
if
err
!=
nil
{
t
.
Fatal
(
err
)
}
time
.
Sleep
(
time
.
Millisecond
*
60
)
provs
,
err
:=
dhts
[
0
]
.
FindProviders
(
u
.
Key
(
"hello"
),
time
.
Second
)
if
err
!=
nil
{
t
.
Fatal
(
err
)
}
if
len
(
provs
)
!=
1
{
t
.
Fatal
(
"Didnt get back providers"
)
}
for
i
:=
0
;
i
<
4
;
i
++
{
dhts
[
i
]
.
Halt
()
}
}
func
TestLayeredGet
(
t
*
testing
.
T
)
{
u
.
Debug
=
false
var
addrs
[]
*
ma
.
Multiaddr
for
i
:=
0
;
i
<
4
;
i
++
{
a
,
err
:=
ma
.
NewMultiaddr
(
fmt
.
Sprintf
(
"/ip4/127.0.0.1/tcp/%d"
,
5000
+
i
))
...
...
@@ -147,7 +226,7 @@ func TestProvides(t *testing.T) {
_
,
err
:=
dhts
[
0
]
.
Connect
(
addrs
[
1
])
if
err
!=
nil
{
t
.
Fatal
(
err
)
t
.
Fatal
f
(
"Failed to connect: %s"
,
err
)
}
_
,
err
=
dhts
[
1
]
.
Connect
(
addrs
[
2
])
...
...
@@ -172,13 +251,13 @@ func TestProvides(t *testing.T) {
time
.
Sleep
(
time
.
Millisecond
*
60
)
provs
,
err
:=
dhts
[
0
]
.
FindProviders
(
u
.
Key
(
"hello"
),
time
.
Second
)
val
,
err
:=
dhts
[
0
]
.
GetValue
(
u
.
Key
(
"hello"
),
time
.
Second
)
if
err
!=
nil
{
t
.
Fatal
(
err
)
}
if
len
(
provs
)
!=
1
{
t
.
Fatal
(
"
Didnt get back providers
"
)
if
string
(
val
)
!=
"world"
{
t
.
Fatal
(
"
Got incorrect value.
"
)
}
for
i
:=
0
;
i
<
4
;
i
++
{
...
...
@@ -186,7 +265,7 @@ func TestProvides(t *testing.T) {
}
}
func
Test
LayeredGet
(
t
*
testing
.
T
)
{
func
Test
FindPeer
(
t
*
testing
.
T
)
{
u
.
Debug
=
false
var
addrs
[]
*
ma
.
Multiaddr
for
i
:=
0
;
i
<
4
;
i
++
{
...
...
@@ -230,25 +309,17 @@ func TestLayeredGet(t *testing.T) {
t
.
Fatal
(
err
)
}
err
=
dhts
[
3
]
.
PutLocal
(
u
.
Key
(
"hello"
),
[]
byte
(
"world"
)
)
p
,
err
:=
dhts
[
0
]
.
FindPeer
(
peers
[
2
]
.
ID
,
time
.
Second
)
if
err
!=
nil
{
t
.
Fatal
(
err
)
}
err
=
dhts
[
3
]
.
Provide
(
u
.
Key
(
"hello"
))
if
err
!=
nil
{
t
.
Fatal
(
err
)
if
p
==
nil
{
t
.
Fatal
(
"Failed to find peer."
)
}
time
.
Sleep
(
time
.
Millisecond
*
60
)
val
,
err
:=
dhts
[
0
]
.
GetValue
(
u
.
Key
(
"hello"
),
time
.
Second
)
if
err
!=
nil
{
t
.
Fatal
(
err
)
}
if
string
(
val
)
!=
"world"
{
t
.
Fatal
(
"Got incorrect value."
)
if
!
p
.
ID
.
Equal
(
peers
[
2
]
.
ID
)
{
t
.
Fatal
(
"Didnt find expected peer."
)
}
for
i
:=
0
;
i
<
4
;
i
++
{
...
...
routing/dht/routing.go
浏览文件 @
a4388624
...
...
@@ -3,8 +3,6 @@ package dht
import
(
"bytes"
"encoding/json"
"errors"
"fmt"
"math/rand"
"time"
...
...
@@ -35,19 +33,19 @@ func GenerateMessageID() uint64 {
// This is the top level "Store" operation of the DHT
func
(
s
*
IpfsDHT
)
PutValue
(
key
u
.
Key
,
value
[]
byte
)
{
complete
:=
make
(
chan
struct
{})
for
i
,
route
:=
range
s
.
routes
{
for
_
,
route
:=
range
s
.
routes
{
p
:=
route
.
NearestPeer
(
kb
.
ConvertKey
(
key
))
if
p
==
nil
{
s
.
network
.
Chan
.
Errors
<-
fmt
.
Errorf
(
"No peer found on level %d"
,
i
)
continue
s
.
network
.
Error
(
kb
.
ErrLookupFailure
)
go
func
()
{
complete
<-
struct
{}{}
}()
continue
}
go
func
()
{
err
:=
s
.
putValueToNetwork
(
p
,
string
(
key
),
value
)
if
err
!=
nil
{
s
.
network
.
Chan
.
Errors
<-
err
s
.
network
.
Error
(
err
)
}
complete
<-
struct
{}{}
}()
...
...
@@ -61,19 +59,46 @@ func (s *IpfsDHT) PutValue(key u.Key, value []byte) {
// If the search does not succeed, a multiaddr string of a closer peer is
// returned along with util.ErrSearchIncomplete
func
(
s
*
IpfsDHT
)
GetValue
(
key
u
.
Key
,
timeout
time
.
Duration
)
([]
byte
,
error
)
{
for
_
,
route
:=
range
s
.
routes
{
var
p
*
peer
.
Peer
p
=
route
.
NearestPeer
(
kb
.
ConvertKey
(
key
))
if
p
==
nil
{
return
nil
,
errors
.
New
(
"Table returned nil peer!"
)
}
route_level
:=
0
b
,
err
:=
s
.
getValueSingle
(
p
,
key
,
timeout
)
if
err
==
nil
{
return
b
,
nil
p
:=
s
.
routes
[
route_level
]
.
NearestPeer
(
kb
.
ConvertKey
(
key
))
if
p
==
nil
{
return
nil
,
kb
.
ErrLookupFailure
}
for
route_level
<
len
(
s
.
routes
)
&&
p
!=
nil
{
pmes
,
err
:=
s
.
getValueSingle
(
p
,
key
,
timeout
,
route_level
)
if
err
!=
nil
{
return
nil
,
u
.
WrapError
(
err
,
"getValue Error"
)
}
if
err
!=
u
.
ErrSearchIncomplete
{
return
nil
,
err
if
pmes
.
GetSuccess
()
{
if
pmes
.
Value
==
nil
{
// We were given provider[s]
return
s
.
getFromPeerList
(
key
,
timeout
,
pmes
.
GetPeers
(),
route_level
)
}
// Success! We were given the value
return
pmes
.
GetValue
(),
nil
}
else
{
// We were given a closer node
closers
:=
pmes
.
GetPeers
()
if
len
(
closers
)
>
0
{
maddr
,
err
:=
ma
.
NewMultiaddr
(
closers
[
0
]
.
GetAddr
())
if
err
!=
nil
{
// ??? Move up route level???
panic
(
"not yet implemented"
)
}
// TODO: dht.Connect has overhead due to an internal
// ping to the target. Use something else
p
,
err
=
s
.
Connect
(
maddr
)
if
err
!=
nil
{
// Move up route level
panic
(
"not yet implemented."
)
}
}
else
{
route_level
++
}
}
}
return
nil
,
u
.
ErrNotFound
...
...
@@ -86,7 +111,7 @@ func (s *IpfsDHT) GetValue(key u.Key, timeout time.Duration) ([]byte, error) {
func
(
s
*
IpfsDHT
)
Provide
(
key
u
.
Key
)
error
{
peers
:=
s
.
routes
[
0
]
.
NearestPeers
(
kb
.
ConvertKey
(
key
),
PoolSize
)
if
len
(
peers
)
==
0
{
//return an error
return
kb
.
ErrLookupFailure
}
pmes
:=
DHTMessage
{
...
...
@@ -97,7 +122,7 @@ func (s *IpfsDHT) Provide(key u.Key) error {
for
_
,
p
:=
range
peers
{
mes
:=
swarm
.
NewMessage
(
p
,
pbmes
)
s
.
network
.
Chan
.
Outgoing
<-
mes
s
.
network
.
Send
(
mes
)
}
return
nil
}
...
...
@@ -105,6 +130,9 @@ func (s *IpfsDHT) Provide(key u.Key) error {
// FindProviders searches for peers who can provide the value for given key.
func
(
s
*
IpfsDHT
)
FindProviders
(
key
u
.
Key
,
timeout
time
.
Duration
)
([]
*
peer
.
Peer
,
error
)
{
p
:=
s
.
routes
[
0
]
.
NearestPeer
(
kb
.
ConvertKey
(
key
))
if
p
==
nil
{
return
nil
,
kb
.
ErrLookupFailure
}
pmes
:=
DHTMessage
{
Type
:
PBDHTMessage_GET_PROVIDERS
,
...
...
@@ -116,7 +144,7 @@ func (s *IpfsDHT) FindProviders(key u.Key, timeout time.Duration) ([]*peer.Peer,
listenChan
:=
s
.
ListenFor
(
pmes
.
Id
,
1
,
time
.
Minute
)
u
.
DOut
(
"Find providers for: '%s'"
,
key
)
s
.
network
.
Chan
.
Outgoing
<-
mes
s
.
network
.
Send
(
mes
)
after
:=
time
.
After
(
timeout
)
select
{
case
<-
after
:
...
...
@@ -129,17 +157,12 @@ func (s *IpfsDHT) FindProviders(key u.Key, timeout time.Duration) ([]*peer.Peer,
if
err
!=
nil
{
return
nil
,
err
}
var
addrs
map
[
u
.
Key
]
string
err
=
json
.
Unmarshal
(
pmes_out
.
GetValue
(),
&
addrs
)
if
err
!=
nil
{
return
nil
,
err
}
var
prov_arr
[]
*
peer
.
Peer
for
pid
,
addr
:=
range
addrs
{
p
:=
s
.
network
.
Find
(
pid
)
for
_
,
prov
:=
range
pmes_out
.
GetPeers
()
{
p
:=
s
.
network
.
Find
(
u
.
Key
(
prov
.
GetId
())
)
if
p
==
nil
{
maddr
,
err
:=
ma
.
NewMultiaddr
(
addr
)
maddr
,
err
:=
ma
.
NewMultiaddr
(
prov
.
GetAddr
()
)
if
err
!=
nil
{
u
.
PErr
(
"error connecting to new peer: %s"
,
err
)
continue
...
...
@@ -162,48 +185,36 @@ func (s *IpfsDHT) FindProviders(key u.Key, timeout time.Duration) ([]*peer.Peer,
// FindPeer searches for a peer with given ID.
func
(
s
*
IpfsDHT
)
FindPeer
(
id
peer
.
ID
,
timeout
time
.
Duration
)
(
*
peer
.
Peer
,
error
)
{
p
:=
s
.
routes
[
0
]
.
NearestPeer
(
kb
.
ConvertPeerID
(
id
))
pmes
:=
DHTMessage
{
Type
:
PBDHTMessage_FIND_NODE
,
Key
:
string
(
id
),
Id
:
GenerateMessageID
(),
route_level
:=
0
p
:=
s
.
routes
[
route_level
]
.
NearestPeer
(
kb
.
ConvertPeerID
(
id
))
if
p
==
nil
{
return
nil
,
kb
.
ErrLookupFailure
}
mes
:=
swarm
.
NewMessage
(
p
,
pmes
.
ToProtobuf
())
listenChan
:=
s
.
ListenFor
(
pmes
.
Id
,
1
,
time
.
Minute
)
s
.
network
.
Chan
.
Outgoing
<-
mes
after
:=
time
.
After
(
timeout
)
select
{
case
<-
after
:
s
.
Unlisten
(
pmes
.
Id
)
return
nil
,
u
.
ErrTimeout
case
resp
:=
<-
listenChan
:
pmes_out
:=
new
(
PBDHTMessage
)
err
:=
proto
.
Unmarshal
(
resp
.
Data
,
pmes_out
)
if
err
!=
nil
{
return
nil
,
err
for
route_level
<
len
(
s
.
routes
)
{
pmes
,
err
:=
s
.
findPeerSingle
(
p
,
id
,
timeout
,
route_level
)
plist
:=
pmes
.
GetPeers
()
if
len
(
plist
)
==
0
{
route_level
++
}
addr
:=
string
(
pmes_out
.
GetValue
())
maddr
,
err
:=
ma
.
NewMultiaddr
(
addr
)
found
:=
plist
[
0
]
addr
,
err
:=
ma
.
NewMultiaddr
(
found
.
GetAddr
())
if
err
!=
nil
{
return
nil
,
err
return
nil
,
u
.
WrapError
(
err
,
"FindPeer received bad info"
)
}
found_peer
,
err
:=
s
.
Connect
(
m
addr
)
nxtPeer
,
err
:=
s
.
Connect
(
addr
)
if
err
!=
nil
{
u
.
POut
(
"Found peer but couldnt connect."
)
return
nil
,
err
return
nil
,
u
.
WrapError
(
err
,
"FindPeer failed to connect to new peer."
)
}
if
!
found_peer
.
ID
.
Equal
(
id
)
{
u
.
POut
(
"FindPeer: searching for '%s' but found '%s'"
,
id
.
Pretty
(),
found_peer
.
ID
.
Pretty
())
return
found_peer
,
u
.
ErrSearchIncomplete
if
pmes
.
GetSuccess
()
{
return
nxtPeer
,
nil
}
else
{
p
=
nxtPeer
}
return
found_peer
,
nil
}
return
nil
,
u
.
ErrNotFound
}
// Ping a peer, log the time it took
...
...
@@ -216,14 +227,14 @@ func (dht *IpfsDHT) Ping(p *peer.Peer, timeout time.Duration) error {
before
:=
time
.
Now
()
response_chan
:=
dht
.
ListenFor
(
pmes
.
Id
,
1
,
time
.
Minute
)
dht
.
network
.
Chan
.
Outgoing
<-
mes
dht
.
network
.
Send
(
mes
)
tout
:=
time
.
After
(
timeout
)
select
{
case
<-
response_chan
:
roundtrip
:=
time
.
Since
(
before
)
p
.
SetLatency
(
roundtrip
)
u
.
P
Out
(
"Ping took %s."
,
roundtrip
.
String
())
u
.
D
Out
(
"Ping took %s."
,
roundtrip
.
String
())
return
nil
case
<-
tout
:
// Timed out, think about removing peer from network
...
...
@@ -249,7 +260,7 @@ func (dht *IpfsDHT) GetDiagnostic(timeout time.Duration) ([]*diagInfo, error) {
pbmes
:=
pmes
.
ToProtobuf
()
for
_
,
p
:=
range
targets
{
mes
:=
swarm
.
NewMessage
(
p
,
pbmes
)
dht
.
network
.
Chan
.
Outgoing
<-
mes
dht
.
network
.
Send
(
mes
)
}
var
out
[]
*
diagInfo
...
...
routing/kbucket/util.go
浏览文件 @
a4388624
...
...
@@ -3,11 +3,16 @@ package dht
import
(
"bytes"
"crypto/sha256"
"errors"
peer
"github.com/jbenet/go-ipfs/peer"
u
"github.com/jbenet/go-ipfs/util"
)
// Returned if a routing table query returns no results. This is NOT expected
// behaviour
var
ErrLookupFailure
=
errors
.
New
(
"failed to find any peer in table"
)
// ID for IpfsDHT should be a byte slice, to allow for simpler operations
// (xor). DHT ids are based on the peer.IDs.
//
...
...
@@ -19,8 +24,8 @@ func (id ID) Equal(other ID) bool {
return
bytes
.
Equal
(
id
,
other
)
}
func
(
id
ID
)
Less
(
other
interface
{}
)
bool
{
a
,
b
:=
equalizeSizes
(
id
,
other
.
(
ID
)
)
func
(
id
ID
)
Less
(
other
ID
)
bool
{
a
,
b
:=
equalizeSizes
(
id
,
other
)
for
i
:=
0
;
i
<
len
(
a
);
i
++
{
if
a
[
i
]
!=
b
[
i
]
{
return
a
[
i
]
<
b
[
i
]
...
...
@@ -80,3 +85,14 @@ func ConvertKey(id u.Key) ID {
hash
:=
sha256
.
Sum256
([]
byte
(
id
))
return
hash
[
:
]
}
// Returns true if a is closer to key than b is
func
Closer
(
a
,
b
peer
.
ID
,
key
u
.
Key
)
bool
{
aid
:=
ConvertPeerID
(
a
)
bid
:=
ConvertPeerID
(
b
)
tgt
:=
ConvertKey
(
key
)
adist
:=
xor
(
aid
,
tgt
)
bdist
:=
xor
(
bid
,
tgt
)
return
adist
.
Less
(
bdist
)
}
swarm/swarm.go
浏览文件 @
a4388624
...
...
@@ -355,3 +355,17 @@ func (s *Swarm) Drop(p *peer.Peer) error {
return
conn
.
Close
()
}
func
(
s
*
Swarm
)
Send
(
mes
*
Message
)
{
s
.
Chan
.
Outgoing
<-
mes
}
func
(
s
*
Swarm
)
Error
(
e
error
)
{
s
.
Chan
.
Errors
<-
e
}
func
(
s
*
Swarm
)
GetChan
()
*
Chan
{
return
s
.
Chan
}
var
_
Network
=
&
Swarm
{}
util/util.go
浏览文件 @
a4388624
package
util
import
(
"bytes"
"errors"
"fmt"
"os"
"os/user"
"runtime"
"strings"
b58
"github.com/jbenet/go-base58"
...
...
@@ -34,6 +36,30 @@ func (k Key) Pretty() string {
return
b58
.
Encode
([]
byte
(
k
))
}
type
IpfsError
struct
{
Inner
error
Note
string
Stack
string
}
func
(
ie
*
IpfsError
)
Error
()
string
{
buf
:=
new
(
bytes
.
Buffer
)
fmt
.
Fprintln
(
buf
,
ie
.
Inner
)
fmt
.
Fprintln
(
buf
,
ie
.
Note
)
fmt
.
Fprintln
(
buf
,
ie
.
Stack
)
return
buf
.
String
()
}
func
WrapError
(
err
error
,
note
string
)
error
{
ie
:=
new
(
IpfsError
)
ie
.
Inner
=
err
ie
.
Note
=
note
stack
:=
make
([]
byte
,
2048
)
n
:=
runtime
.
Stack
(
stack
,
false
)
ie
.
Stack
=
string
(
stack
[
:
n
])
return
ie
}
// Hash is the global IPFS hash function. uses multihash SHA2_256, 256 bits
func
Hash
(
data
[]
byte
)
(
mh
.
Multihash
,
error
)
{
return
mh
.
Sum
(
data
,
mh
.
SHA2_256
,
-
1
)
...
...
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论