Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
G
go-ipfs
概览
概览
详情
活动
周期分析
版本库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
统计图
问题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
日程表
图表
维基
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
图像
聊天
创建新问题
作业
提交
问题看板
Open sidebar
jihao
go-ipfs
Commits
c7fb7ce1
提交
c7fb7ce1
authored
10月 22, 2015
作者:
Jeromy
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
cache ipns entries to speed things up a little
License: MIT Signed-off-by:
Jeromy
<
jeromyj@gmail.com
>
上级
f36ada87
显示空白字符变更
内嵌
并排
正在显示
14 个修改的文件
包含
210 行增加
和
26 行删除
+210
-26
ipns.go
core/commands/ipns.go
+23
-5
publish.go
core/commands/publish.go
+13
-1
core.go
core/core.go
+29
-2
ipns_test.go
fuse/ipns/ipns_test.go
+1
-1
namesys.go
namesys/namesys.go
+4
-2
namesys.pb.go
namesys/pb/namesys.pb.go
+8
-0
namesys.proto
namesys/pb/namesys.proto
+2
-0
publisher.go
namesys/publisher.go
+18
-0
repub_test.go
namesys/republisher/repub_test.go
+4
-0
resolve_test.go
namesys/resolve_test.go
+3
-3
routing.go
namesys/routing.go
+98
-12
init.go
repo/config/init.go
+4
-0
ipns.go
repo/config/ipns.go
+2
-0
t0240-republisher.sh
test/sharness/t0240-republisher.sh
+1
-0
没有找到文件。
core/commands/ipns.go
浏览文件 @
c7fb7ce1
...
...
@@ -45,6 +45,7 @@ Resolve the value of another name:
},
Options
:
[]
cmds
.
Option
{
cmds
.
BoolOption
(
"recursive"
,
"r"
,
"Resolve until the result is not an IPNS name"
),
cmds
.
BoolOption
(
"nocache"
,
"n"
,
"Do not used cached entries"
),
},
Run
:
func
(
req
cmds
.
Request
,
res
cmds
.
Response
)
{
...
...
@@ -62,13 +63,27 @@ Resolve the value of another name:
}
}
router
:=
n
.
Routing
if
local
,
_
,
_
:=
req
.
Option
(
"local"
)
.
Bool
();
local
{
router
=
offline
.
NewOfflineRouter
(
n
.
Repo
.
Datastore
(),
n
.
PrivateKey
)
nocache
,
_
,
_
:=
req
.
Option
(
"nocache"
)
.
Bool
()
local
,
_
,
_
:=
req
.
Option
(
"local"
)
.
Bool
()
// default to nodes namesys resolver
var
resolver
namesys
.
Resolver
=
n
.
Namesys
if
local
&&
nocache
{
res
.
SetError
(
errors
.
New
(
"cannot specify both local and nocache"
),
cmds
.
ErrNormal
)
return
}
var
name
string
if
local
{
offroute
:=
offline
.
NewOfflineRouter
(
n
.
Repo
.
Datastore
(),
n
.
PrivateKey
)
resolver
=
namesys
.
NewRoutingResolver
(
offroute
,
0
)
}
if
nocache
{
resolver
=
namesys
.
NewNameSystem
(
n
.
Routing
,
n
.
Repo
.
Datastore
(),
0
)
}
var
name
string
if
len
(
req
.
Arguments
())
==
0
{
if
n
.
Identity
==
""
{
res
.
SetError
(
errors
.
New
(
"Identity not loaded!"
),
cmds
.
ErrNormal
)
...
...
@@ -86,7 +101,10 @@ Resolve the value of another name:
depth
=
namesys
.
DefaultDepthLimit
}
resolver
:=
namesys
.
NewRoutingResolver
(
router
)
if
!
strings
.
HasPrefix
(
name
,
"/ipns/"
)
{
name
=
"/ipns/"
+
name
}
output
,
err
:=
resolver
.
ResolveN
(
req
.
Context
(),
name
,
depth
)
if
err
!=
nil
{
res
.
SetError
(
err
,
cmds
.
ErrNormal
)
...
...
core/commands/publish.go
浏览文件 @
c7fb7ce1
...
...
@@ -52,6 +52,7 @@ Publish an <ipfs-path> to another public key (not implemented):
Options
:
[]
cmds
.
Option
{
cmds
.
BoolOption
(
"resolve"
,
"resolve given path before publishing (default=true)"
),
cmds
.
StringOption
(
"lifetime"
,
"t"
,
"time duration that the record will be valid for (default: 24hrs)"
),
cmds
.
StringOption
(
"ttl"
,
"time duration this record should be cached for (caution: experimental)"
),
},
Run
:
func
(
req
cmds
.
Request
,
res
cmds
.
Response
)
{
log
.
Debug
(
"Begin Publish"
)
...
...
@@ -96,7 +97,18 @@ Publish an <ipfs-path> to another public key (not implemented):
popts
.
pubValidTime
=
d
}
output
,
err
:=
publish
(
req
.
Context
(),
n
,
n
.
PrivateKey
,
path
.
Path
(
pstr
),
popts
)
ctx
:=
req
.
Context
()
if
ttl
,
found
,
_
:=
req
.
Option
(
"ttl"
)
.
String
();
found
{
d
,
err
:=
time
.
ParseDuration
(
ttl
)
if
err
!=
nil
{
res
.
SetError
(
err
,
cmds
.
ErrNormal
)
return
}
ctx
=
context
.
WithValue
(
ctx
,
"ipns-publish-ttl"
,
d
)
}
output
,
err
:=
publish
(
ctx
,
n
,
n
.
PrivateKey
,
path
.
Path
(
pstr
),
popts
)
if
err
!=
nil
{
res
.
SetError
(
err
,
cmds
.
ErrNormal
)
return
...
...
core/core.go
浏览文件 @
c7fb7ce1
...
...
@@ -226,8 +226,13 @@ func (n *IpfsNode) startOnlineServicesWithHost(ctx context.Context, host p2phost
bitswapNetwork
:=
bsnet
.
NewFromIpfsHost
(
n
.
PeerHost
,
n
.
Routing
)
n
.
Exchange
=
bitswap
.
New
(
ctx
,
n
.
Identity
,
bitswapNetwork
,
n
.
Blockstore
,
alwaysSendToPeer
)
size
,
err
:=
n
.
getCacheSize
()
if
err
!=
nil
{
return
err
}
// setup name system
n
.
Namesys
=
namesys
.
NewNameSystem
(
n
.
Routing
,
n
.
Repo
.
Datastore
())
n
.
Namesys
=
namesys
.
NewNameSystem
(
n
.
Routing
,
n
.
Repo
.
Datastore
()
,
size
)
// setup ipns republishing
err
=
n
.
setupIpnsRepublisher
()
...
...
@@ -238,6 +243,23 @@ func (n *IpfsNode) startOnlineServicesWithHost(ctx context.Context, host p2phost
return
nil
}
// getCacheSize returns cache life and cache size
func
(
n
*
IpfsNode
)
getCacheSize
()
(
int
,
error
)
{
cfg
,
err
:=
n
.
Repo
.
Config
()
if
err
!=
nil
{
return
0
,
err
}
cs
:=
cfg
.
Ipns
.
ResolveCacheSize
if
cs
==
0
{
cs
=
128
}
if
cs
<
0
{
return
0
,
fmt
.
Errorf
(
"cannot specify negative resolve cache size"
)
}
return
cs
,
nil
}
func
(
n
*
IpfsNode
)
setupIpnsRepublisher
()
error
{
cfg
,
err
:=
n
.
Repo
.
Config
()
if
err
!=
nil
{
...
...
@@ -456,7 +478,12 @@ func (n *IpfsNode) SetupOfflineRouting() error {
n
.
Routing
=
offroute
.
NewOfflineRouter
(
n
.
Repo
.
Datastore
(),
n
.
PrivateKey
)
n
.
Namesys
=
namesys
.
NewNameSystem
(
n
.
Routing
,
n
.
Repo
.
Datastore
())
size
,
err
:=
n
.
getCacheSize
()
if
err
!=
nil
{
return
err
}
n
.
Namesys
=
namesys
.
NewNameSystem
(
n
.
Routing
,
n
.
Repo
.
Datastore
(),
size
)
return
nil
}
...
...
fuse/ipns/ipns_test.go
浏览文件 @
c7fb7ce1
...
...
@@ -113,7 +113,7 @@ func setupIpnsTest(t *testing.T, node *core.IpfsNode) (*core.IpfsNode, *fstest.M
}
node
.
Routing
=
offroute
.
NewOfflineRouter
(
node
.
Repo
.
Datastore
(),
node
.
PrivateKey
)
node
.
Namesys
=
namesys
.
NewNameSystem
(
node
.
Routing
,
node
.
Repo
.
Datastore
())
node
.
Namesys
=
namesys
.
NewNameSystem
(
node
.
Routing
,
node
.
Repo
.
Datastore
()
,
0
)
ipnsfs
,
err
:=
nsfs
.
NewFilesystem
(
context
.
Background
(),
node
.
DAG
,
node
.
Namesys
,
node
.
Pinning
,
node
.
PrivateKey
)
if
err
!=
nil
{
...
...
namesys/namesys.go
浏览文件 @
c7fb7ce1
...
...
@@ -26,12 +26,12 @@ type mpns struct {
}
// NewNameSystem will construct the IPFS naming system based on Routing
func
NewNameSystem
(
r
routing
.
IpfsRouting
,
ds
ds
.
Datastore
)
NameSystem
{
func
NewNameSystem
(
r
routing
.
IpfsRouting
,
ds
ds
.
Datastore
,
cachesize
int
)
NameSystem
{
return
&
mpns
{
resolvers
:
map
[
string
]
resolver
{
"dns"
:
newDNSResolver
(),
"proquint"
:
new
(
ProquintResolver
),
"dht"
:
newRoutingResolver
(
r
),
"dht"
:
NewRoutingResolver
(
r
,
cachesize
),
},
publishers
:
map
[
string
]
Publisher
{
"/ipns/"
:
NewRoutingPublisher
(
r
,
ds
),
...
...
@@ -39,6 +39,8 @@ func NewNameSystem(r routing.IpfsRouting, ds ds.Datastore) NameSystem {
}
}
const
DefaultResolverCacheTTL
=
time
.
Minute
// Resolve implements Resolver.
func
(
ns
*
mpns
)
Resolve
(
ctx
context
.
Context
,
name
string
)
(
path
.
Path
,
error
)
{
return
ns
.
ResolveN
(
ctx
,
name
,
DefaultDepthLimit
)
...
...
namesys/pb/namesys.pb.go
浏览文件 @
c7fb7ce1
...
...
@@ -57,6 +57,7 @@ type IpnsEntry struct {
ValidityType
*
IpnsEntry_ValidityType
`protobuf:"varint,3,opt,name=validityType,enum=namesys.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"`
XXX_unrecognized
[]
byte
`json:"-"`
}
...
...
@@ -99,6 +100,13 @@ func (m *IpnsEntry) GetSequence() uint64 {
return
0
}
func
(
m
*
IpnsEntry
)
GetTtl
()
uint64
{
if
m
!=
nil
&&
m
.
Ttl
!=
nil
{
return
*
m
.
Ttl
}
return
0
}
func
init
()
{
proto
.
RegisterEnum
(
"namesys.pb.IpnsEntry_ValidityType"
,
IpnsEntry_ValidityType_name
,
IpnsEntry_ValidityType_value
)
}
namesys/pb/namesys.proto
浏览文件 @
c7fb7ce1
...
...
@@ -12,4 +12,6 @@ message IpnsEntry {
optional
bytes
validity
=
4
;
optional
uint64
sequence
=
5
;
optional
uint64
ttl
=
6
;
}
namesys/publisher.go
浏览文件 @
c7fb7ce1
...
...
@@ -121,6 +121,19 @@ func (p *ipnsPublisher) getPreviousSeqNo(ctx context.Context, ipnskey key.Key) (
return
e
.
GetSequence
(),
nil
}
// setting the TTL on published records is an experimental feature.
// as such, i'm using the context to wire it through to avoid changing too
// much code along the way.
func
checkCtxTTL
(
ctx
context
.
Context
)
(
time
.
Duration
,
bool
)
{
v
:=
ctx
.
Value
(
"ipns-publish-ttl"
)
if
v
==
nil
{
return
0
,
false
}
d
,
ok
:=
v
.
(
time
.
Duration
)
return
d
,
ok
}
func
PutRecordToRouting
(
ctx
context
.
Context
,
k
ci
.
PrivKey
,
value
path
.
Path
,
seqnum
uint64
,
eol
time
.
Time
,
r
routing
.
IpfsRouting
,
id
peer
.
ID
)
error
{
namekey
,
ipnskey
:=
IpnsKeysForID
(
id
)
entry
,
err
:=
CreateRoutingEntryData
(
k
,
value
,
seqnum
,
eol
)
...
...
@@ -128,6 +141,11 @@ func PutRecordToRouting(ctx context.Context, k ci.PrivKey, value path.Path, seqn
return
err
}
ttl
,
ok
:=
checkCtxTTL
(
ctx
)
if
ok
{
entry
.
Ttl
=
proto
.
Uint64
(
uint64
(
ttl
.
Nanoseconds
()))
}
err
=
PublishEntry
(
ctx
,
r
,
ipnskey
,
entry
)
if
err
!=
nil
{
return
err
...
...
namesys/republisher/repub_test.go
浏览文件 @
c7fb7ce1
...
...
@@ -18,6 +18,8 @@ import (
)
func
TestRepublish
(
t
*
testing
.
T
)
{
// set cache life to zero for testing low-period repubs
ctx
,
cancel
:=
context
.
WithCancel
(
context
.
Background
())
defer
cancel
()
...
...
@@ -34,6 +36,8 @@ func TestRepublish(t *testing.T) {
t
.
Fatal
(
err
)
}
nd
.
Namesys
=
namesys
.
NewNameSystem
(
nd
.
Routing
,
nd
.
Repo
.
Datastore
(),
0
)
nodes
=
append
(
nodes
,
nd
)
}
...
...
namesys/resolve_test.go
浏览文件 @
c7fb7ce1
...
...
@@ -19,7 +19,7 @@ func TestRoutingResolve(t *testing.T) {
d
:=
mockrouting
.
NewServer
()
.
Client
(
testutil
.
RandIdentityOrFatal
(
t
))
dstore
:=
ds
.
NewMapDatastore
()
resolver
:=
NewRoutingResolver
(
d
)
resolver
:=
NewRoutingResolver
(
d
,
0
)
publisher
:=
NewRoutingPublisher
(
d
,
dstore
)
privk
,
pubk
,
err
:=
testutil
.
RandTestKeyPair
(
512
)
...
...
@@ -53,7 +53,7 @@ func TestPrexistingExpiredRecord(t *testing.T) {
dstore
:=
ds
.
NewMapDatastore
()
d
:=
mockrouting
.
NewServer
()
.
ClientWithDatastore
(
context
.
Background
(),
testutil
.
RandIdentityOrFatal
(
t
),
dstore
)
resolver
:=
NewRoutingResolver
(
d
)
resolver
:=
NewRoutingResolver
(
d
,
0
)
publisher
:=
NewRoutingPublisher
(
d
,
dstore
)
privk
,
pubk
,
err
:=
testutil
.
RandTestKeyPair
(
512
)
...
...
@@ -90,7 +90,7 @@ func TestPrexistingRecord(t *testing.T) {
dstore
:=
ds
.
NewMapDatastore
()
d
:=
mockrouting
.
NewServer
()
.
ClientWithDatastore
(
context
.
Background
(),
testutil
.
RandIdentityOrFatal
(
t
),
dstore
)
resolver
:=
NewRoutingResolver
(
d
)
resolver
:=
NewRoutingResolver
(
d
,
0
)
publisher
:=
NewRoutingPublisher
(
d
,
dstore
)
privk
,
pubk
,
err
:=
testutil
.
RandTestKeyPair
(
512
)
...
...
namesys/routing.go
浏览文件 @
c7fb7ce1
...
...
@@ -2,16 +2,19 @@ package namesys
import
(
"fmt"
"time"
proto
"github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/gogo/protobuf/proto"
lru
"github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/hashicorp/golang-lru"
mh
"github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-multihash"
"github.com/ipfs/go-ipfs/Godeps/_workspace/src/golang.org/x/net/context"
logging
"github.com/ipfs/go-ipfs/vendor/QmTBXYb6y2ZcJmoXVKk3pf9rzSEjbCg7tQaJW7RSuH14nv/go-log"
key
"github.com/ipfs/go-ipfs/blocks/key"
pb
"github.com/ipfs/go-ipfs/namesys/pb"
path
"github.com/ipfs/go-ipfs/path"
routing
"github.com/ipfs/go-ipfs/routing"
logging
"github.com/ipfs/go-ipfs/vendor/QmTBXYb6y2ZcJmoXVKk3pf9rzSEjbCg7tQaJW7RSuH14nv/go-log
"
u
"github.com/ipfs/go-ipfs/util
"
)
var
log
=
logging
.
Logger
(
"namesys"
)
...
...
@@ -19,25 +22,84 @@ var log = logging.Logger("namesys")
// routingResolver implements NSResolver for the main IPFS SFS-like naming
type
routingResolver
struct
{
routing
routing
.
IpfsRouting
cache
*
lru
.
Cache
}
// NewRoutingResolver constructs a name resolver using the IPFS Routing system
// to implement SFS-like naming on top.
func
NewRoutingResolver
(
route
routing
.
IpfsRouting
)
Resolver
{
if
route
==
nil
{
panic
(
"attempt to create resolver with nil routing system"
)
func
(
r
*
routingResolver
)
cacheGet
(
name
string
)
(
path
.
Path
,
bool
)
{
if
r
.
cache
==
nil
{
return
""
,
false
}
ientry
,
ok
:=
r
.
cache
.
Get
(
name
)
if
!
ok
{
return
""
,
false
}
entry
,
ok
:=
ientry
.
(
cacheEntry
)
if
!
ok
{
// should never happen, purely for sanity
log
.
Panicf
(
"unexpected type %T in cache for %q."
,
ientry
,
name
)
}
return
&
routingResolver
{
routing
:
route
}
if
time
.
Now
()
.
Before
(
entry
.
eol
)
{
return
entry
.
val
,
true
}
r
.
cache
.
Remove
(
name
)
return
""
,
false
}
// newRoutingResolver returns a resolver instead of a Resolver.
func
newRoutingResolver
(
route
routing
.
IpfsRouting
)
resolver
{
func
(
r
*
routingResolver
)
cacheSet
(
name
string
,
val
path
.
Path
,
rec
*
pb
.
IpnsEntry
)
{
if
r
.
cache
==
nil
{
return
}
// if completely unspecified, just use one minute
ttl
:=
DefaultResolverCacheTTL
if
rec
.
Ttl
!=
nil
{
recttl
:=
time
.
Duration
(
rec
.
GetTtl
())
if
recttl
>=
0
{
ttl
=
recttl
}
}
cacheTil
:=
time
.
Now
()
.
Add
(
ttl
)
eol
,
ok
:=
checkEOL
(
rec
)
if
ok
&&
eol
.
Before
(
cacheTil
)
{
cacheTil
=
eol
}
r
.
cache
.
Add
(
name
,
cacheEntry
{
val
:
val
,
eol
:
cacheTil
,
})
}
type
cacheEntry
struct
{
val
path
.
Path
eol
time
.
Time
}
// NewRoutingResolver constructs a name resolver using the IPFS Routing system
// to implement SFS-like naming on top.
// cachesize is the limit of the number of entries in the lru cache. Setting it
// to '0' will disable caching.
func
NewRoutingResolver
(
route
routing
.
IpfsRouting
,
cachesize
int
)
*
routingResolver
{
if
route
==
nil
{
panic
(
"attempt to create resolver with nil routing system"
)
}
return
&
routingResolver
{
routing
:
route
}
var
cache
*
lru
.
Cache
if
cachesize
>
0
{
cache
,
_
=
lru
.
New
(
cachesize
)
}
return
&
routingResolver
{
routing
:
route
,
cache
:
cache
,
}
}
// Resolve implements Resolver.
...
...
@@ -54,6 +116,11 @@ func (r *routingResolver) ResolveN(ctx context.Context, name string, depth int)
// resolve SFS-like names.
func
(
r
*
routingResolver
)
resolveOnce
(
ctx
context
.
Context
,
name
string
)
(
path
.
Path
,
error
)
{
log
.
Debugf
(
"RoutingResolve: '%s'"
,
name
)
cached
,
ok
:=
r
.
cacheGet
(
name
)
if
ok
{
return
cached
,
nil
}
hash
,
err
:=
mh
.
FromB58String
(
name
)
if
err
!=
nil
{
log
.
Warning
(
"RoutingResolve: bad input hash: [%s]
\n
"
,
name
)
...
...
@@ -98,10 +165,29 @@ func (r *routingResolver) resolveOnce(ctx context.Context, name string) (path.Pa
valh
,
err
:=
mh
.
Cast
(
entry
.
GetValue
())
if
err
!=
nil
{
// Not a multihash, probably a new record
return
path
.
ParsePath
(
string
(
entry
.
GetValue
()))
p
,
err
:=
path
.
ParsePath
(
string
(
entry
.
GetValue
()))
if
err
!=
nil
{
return
""
,
err
}
r
.
cacheSet
(
name
,
p
,
entry
)
return
p
,
nil
}
else
{
// Its an old style multihash record
log
.
Warning
(
"Detected old style multihash record"
)
return
path
.
FromKey
(
key
.
Key
(
valh
)),
nil
p
:=
path
.
FromKey
(
key
.
Key
(
valh
))
r
.
cacheSet
(
name
,
p
,
entry
)
return
p
,
nil
}
}
func
checkEOL
(
e
*
pb
.
IpnsEntry
)
(
time
.
Time
,
bool
)
{
if
e
.
GetValidityType
()
==
pb
.
IpnsEntry_EOL
{
eol
,
err
:=
u
.
ParseRFC3339
(
string
(
e
.
GetValidity
()))
if
err
!=
nil
{
return
time
.
Time
{},
false
}
return
eol
,
true
}
return
time
.
Time
{},
false
}
repo/config/init.go
浏览文件 @
c7fb7ce1
...
...
@@ -64,6 +64,10 @@ func Init(out io.Writer, nBitsForKeypair int) (*Config, error) {
IPNS
:
"/ipns"
,
},
Ipns
:
Ipns
{
ResolveCacheSize
:
128
,
},
// tracking ipfs version used to generate the init folder and adding
// update checker default setting.
Version
:
VersionDefaultValue
(),
...
...
repo/config/ipns.go
浏览文件 @
c7fb7ce1
...
...
@@ -3,4 +3,6 @@ package config
type
Ipns
struct
{
RepublishPeriod
string
RecordLifetime
string
ResolveCacheSize
int
}
test/sharness/t0240-republisher.sh
浏览文件 @
c7fb7ce1
...
...
@@ -26,6 +26,7 @@ setup_iptb() {
for i in $(test_seq 0 3)
do
ipfsi $i config Ipns.RepublishPeriod 20s
ipfsi $i config --json Ipns.ResolveCacheSize 0
done
'
...
...
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论