Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
M
mybee
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
vicotor
mybee
Commits
f5aa73f8
Unverified
Commit
f5aa73f8
authored
Apr 30, 2021
by
Peter Mrekaj
Committed by
GitHub
Apr 30, 2021
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Rename address to reference in pinning related code (#1616)
parent
b175f97c
Changes
11
Hide whitespace changes
Inline
Side-by-side
Showing
11 changed files
with
152 additions
and
149 deletions
+152
-149
Swarm.yaml
openapi/Swarm.yaml
+11
-11
bytes_test.go
pkg/api/bytes_test.go
+13
-9
bzz_test.go
pkg/api/bzz_test.go
+14
-10
chunk_test.go
pkg/api/chunk_test.go
+9
-9
pin.go
pkg/api/pin.go
+33
-33
pin_test.go
pkg/api/pin_test.go
+13
-13
router.go
pkg/api/router.go
+1
-1
doc.go
pkg/pinning/doc.go
+1
-1
mock.go
pkg/pinning/mock/mock.go
+13
-18
pinning.go
pkg/pinning/pinning.go
+29
-29
pinning_test.go
pkg/pinning/pinning_test.go
+15
-15
No files found.
openapi/Swarm.yaml
View file @
f5aa73f8
...
...
@@ -440,21 +440,21 @@ paths:
default
:
description
:
Default response
"
/pins/{
address
}"
:
"
/pins/{
reference
}"
:
parameters
:
-
in
:
path
name
:
address
name
:
reference
schema
:
$ref
:
"
SwarmCommon.yaml#/components/schemas/SwarmOnlyReference"
required
:
true
description
:
Swarm
address
of the root hash
description
:
Swarm
reference
of the root hash
post
:
summary
:
Pin
root hash with given address
summary
:
Pin
the root hash with the given reference
tags
:
-
Root hash pinning
responses
:
"
201"
:
description
:
Pinning root hash with
address
description
:
Pinning root hash with
reference
content
:
application/json
:
schema
:
...
...
@@ -468,12 +468,12 @@ paths:
default
:
description
:
Default response
delete
:
summary
:
Unpin
root hash with given address
summary
:
Unpin
the root hash with the given reference
tags
:
-
Root hash pinning
responses
:
"
200"
:
description
:
Unpinning root hash with
address
description
:
Unpinning root hash with
reference
content
:
application/json
:
schema
:
...
...
@@ -487,12 +487,12 @@ paths:
default
:
description
:
Default response
get
:
summary
:
Get pinning status of
root hash with given address
summary
:
Get pinning status of
the root hash with the given reference
tags
:
-
Root hash pinning
responses
:
"
200"
:
description
:
Address of
pinned root hash
description
:
Reference of the
pinned root hash
content
:
application/json
:
schema
:
...
...
@@ -510,12 +510,12 @@ paths:
"
/pins"
:
get
:
summary
:
Get
list of pinned root hashes address
es
summary
:
Get
the list of pinned root hash referenc
es
tags
:
-
Root hash pinning
responses
:
"
200"
:
description
:
List of pinned root hash
es address
es
description
:
List of pinned root hash
referenc
es
content
:
application/json
:
schema
:
...
...
pkg/api/bytes_test.go
View file @
f5aa73f8
...
...
@@ -70,7 +70,11 @@ func TestBytes(t *testing.T) {
t
.
Fatal
(
"storer check root chunk address: have none; want one"
)
}
if
have
,
want
:=
len
(
pinningMock
.
Entries
()),
0
;
have
!=
want
{
refs
,
err
:=
pinningMock
.
Pins
()
if
err
!=
nil
{
t
.
Fatal
(
"unable to get pinned references"
)
}
if
have
,
want
:=
len
(
refs
),
0
;
have
!=
want
{
t
.
Fatalf
(
"root pin count mismatch: have %d; want %d"
,
have
,
want
)
}
})
...
...
@@ -83,24 +87,24 @@ func TestBytes(t *testing.T) {
jsonhttptest
.
WithRequestHeader
(
api
.
SwarmPinHeader
,
"true"
),
jsonhttptest
.
WithUnmarshalJSONResponse
(
&
res
),
)
chunkAddr
:=
res
.
Reference
reference
:=
res
.
Reference
has
,
err
:=
storerMock
.
Has
(
context
.
Background
(),
chunkAddr
)
has
,
err
:=
storerMock
.
Has
(
context
.
Background
(),
reference
)
if
err
!=
nil
{
t
.
Fatal
(
err
)
}
if
!
has
{
t
.
Fatal
(
"storer check root chunk
address
: have none; want one"
)
t
.
Fatal
(
"storer check root chunk
reference
: have none; want one"
)
}
if
have
,
want
:=
len
(
pinningMock
.
Entries
()),
1
;
have
!=
want
{
t
.
Fatalf
(
"root pin count mismatch: have %d; want %d"
,
have
,
want
)
}
addrs
,
err
:=
pinningMock
.
Pins
()
refs
,
err
:=
pinningMock
.
Pins
()
if
err
!=
nil
{
t
.
Fatal
(
err
)
}
if
have
,
want
:=
addrs
[
0
],
chunkAddr
;
!
have
.
Equal
(
want
)
{
if
have
,
want
:=
len
(
refs
),
1
;
have
!=
want
{
t
.
Fatalf
(
"root pin count mismatch: have %d; want %d"
,
have
,
want
)
}
if
have
,
want
:=
refs
[
0
],
reference
;
!
have
.
Equal
(
want
)
{
t
.
Fatalf
(
"root pin reference mismatch: have %q; want %q"
,
have
,
want
)
}
})
...
...
pkg/api/bzz_test.go
View file @
f5aa73f8
...
...
@@ -108,7 +108,11 @@ func TestBzzFiles(t *testing.T) {
t
.
Fatal
(
"storer check root chunk address: have none; want one"
)
}
if
have
,
want
:=
len
(
pinningMock
.
Entries
()),
0
;
have
!=
want
{
refs
,
err
:=
pinningMock
.
Pins
()
if
err
!=
nil
{
t
.
Fatal
(
"unable to get pinned references"
)
}
if
have
,
want
:=
len
(
refs
),
0
;
have
!=
want
{
t
.
Fatalf
(
"root pin count mismatch: have %d; want %d"
,
have
,
want
)
}
})
...
...
@@ -140,33 +144,33 @@ func TestBzzFiles(t *testing.T) {
},
},
})
address
:=
swarm
.
MustParseHexAddress
(
"f30c0aa7e9e2a0ef4c9b1b750ebfeaeb7c7c24da700bb089da19a46e3677824b"
)
reference
:=
swarm
.
MustParseHexAddress
(
"f30c0aa7e9e2a0ef4c9b1b750ebfeaeb7c7c24da700bb089da19a46e3677824b"
)
jsonhttptest
.
Request
(
t
,
client
,
http
.
MethodPost
,
fileUploadResource
,
http
.
StatusCreated
,
jsonhttptest
.
WithRequestHeader
(
api
.
SwarmPostageBatchIdHeader
,
batchOkStr
),
jsonhttptest
.
WithRequestHeader
(
api
.
SwarmPinHeader
,
"true"
),
jsonhttptest
.
WithRequestBody
(
tr
),
jsonhttptest
.
WithRequestHeader
(
"Content-Type"
,
api
.
ContentTypeTar
),
jsonhttptest
.
WithExpectedJSONResponse
(
api
.
BzzUploadResponse
{
Reference
:
address
,
Reference
:
reference
,
}),
)
has
,
err
:=
storerMock
.
Has
(
context
.
Background
(),
address
)
has
,
err
:=
storerMock
.
Has
(
context
.
Background
(),
reference
)
if
err
!=
nil
{
t
.
Fatal
(
err
)
}
if
!
has
{
t
.
Fatal
(
"storer check root chunk
address
: have none; want one"
)
t
.
Fatal
(
"storer check root chunk
reference
: have none; want one"
)
}
if
have
,
want
:=
len
(
pinningMock
.
Entries
()),
1
;
have
!=
want
{
t
.
Fatalf
(
"root pin count mismatch: have %d; want %d"
,
have
,
want
)
}
addrs
,
err
:=
pinningMock
.
Pins
()
refs
,
err
:=
pinningMock
.
Pins
()
if
err
!=
nil
{
t
.
Fatal
(
err
)
}
if
have
,
want
:=
addrs
[
0
],
address
;
!
have
.
Equal
(
want
)
{
if
have
,
want
:=
len
(
refs
),
1
;
have
!=
want
{
t
.
Fatalf
(
"root pin count mismatch: have %d; want %d"
,
have
,
want
)
}
if
have
,
want
:=
refs
[
0
],
reference
;
!
have
.
Equal
(
want
)
{
t
.
Fatalf
(
"root pin reference mismatch: have %q; want %q"
,
have
,
want
)
}
})
...
...
pkg/api/chunk_test.go
View file @
f5aa73f8
...
...
@@ -105,30 +105,30 @@ func TestChunkUploadDownload(t *testing.T) {
}
})
t
.
Run
(
"pin-ok"
,
func
(
t
*
testing
.
T
)
{
address
:=
chunk
.
Address
()
reference
:=
chunk
.
Address
()
jsonhttptest
.
Request
(
t
,
client
,
http
.
MethodPost
,
chunksEndpoint
,
http
.
StatusCreated
,
jsonhttptest
.
WithRequestHeader
(
api
.
SwarmPostageBatchIdHeader
,
batchOkStr
),
jsonhttptest
.
WithRequestBody
(
bytes
.
NewReader
(
chunk
.
Data
())),
jsonhttptest
.
WithExpectedJSONResponse
(
api
.
ChunkAddressResponse
{
Reference
:
address
}),
jsonhttptest
.
WithExpectedJSONResponse
(
api
.
ChunkAddressResponse
{
Reference
:
reference
}),
jsonhttptest
.
WithRequestHeader
(
api
.
SwarmPinHeader
,
"True"
),
)
has
,
err
:=
storerMock
.
Has
(
context
.
Background
(),
address
)
has
,
err
:=
storerMock
.
Has
(
context
.
Background
(),
reference
)
if
err
!=
nil
{
t
.
Fatal
(
err
)
}
if
!
has
{
t
.
Fatal
(
"storer check root chunk
address
: have none; want one"
)
t
.
Fatal
(
"storer check root chunk
reference
: have none; want one"
)
}
if
have
,
want
:=
len
(
pinningMock
.
Entries
()),
1
;
have
!=
want
{
t
.
Fatalf
(
"root pin count mismatch: have %d; want %d"
,
have
,
want
)
}
addrs
,
err
:=
pinningMock
.
Pins
()
refs
,
err
:=
pinningMock
.
Pins
()
if
err
!=
nil
{
t
.
Fatal
(
err
)
}
if
have
,
want
:=
addrs
[
0
],
address
;
!
have
.
Equal
(
want
)
{
if
have
,
want
:=
len
(
refs
),
1
;
have
!=
want
{
t
.
Fatalf
(
"root pin count mismatch: have %d; want %d"
,
have
,
want
)
}
if
have
,
want
:=
refs
[
0
],
reference
;
!
have
.
Equal
(
want
)
{
t
.
Fatalf
(
"root pin reference mismatch: have %q; want %q"
,
have
,
want
)
}
...
...
pkg/api/pin.go
View file @
f5aa73f8
...
...
@@ -14,19 +14,19 @@ import (
"github.com/gorilla/mux"
)
// pinRootHash pins root hash of given
address
. This method is idempotent.
// pinRootHash pins root hash of given
reference
. This method is idempotent.
func
(
s
*
server
)
pinRootHash
(
w
http
.
ResponseWriter
,
r
*
http
.
Request
)
{
addr
,
err
:=
swarm
.
ParseHexAddress
(
mux
.
Vars
(
r
)[
"address
"
])
ref
,
err
:=
swarm
.
ParseHexAddress
(
mux
.
Vars
(
r
)[
"reference
"
])
if
err
!=
nil
{
s
.
logger
.
Debugf
(
"pin root hash: unable to parse
address %q: %v"
,
addr
,
err
)
s
.
logger
.
Error
(
"pin root hash: unable to parse
address
"
)
jsonhttp
.
BadRequest
(
w
,
"bad
address
"
)
s
.
logger
.
Debugf
(
"pin root hash: unable to parse
reference %q: %v"
,
ref
,
err
)
s
.
logger
.
Error
(
"pin root hash: unable to parse
reference
"
)
jsonhttp
.
BadRequest
(
w
,
"bad
reference
"
)
return
}
has
,
err
:=
s
.
pinning
.
HasPin
(
addr
)
has
,
err
:=
s
.
pinning
.
HasPin
(
ref
)
if
err
!=
nil
{
s
.
logger
.
Debugf
(
"pin root hash: checking of tracking pin for %q failed: %v"
,
addr
,
err
)
s
.
logger
.
Debugf
(
"pin root hash: checking of tracking pin for %q failed: %v"
,
ref
,
err
)
s
.
logger
.
Error
(
"pin root hash: checking of tracking pin failed"
)
jsonhttp
.
InternalServerError
(
w
,
nil
)
return
...
...
@@ -36,9 +36,9 @@ func (s *server) pinRootHash(w http.ResponseWriter, r *http.Request) {
return
}
err
=
s
.
pinning
.
CreatePin
(
r
.
Context
(),
addr
,
true
)
err
=
s
.
pinning
.
CreatePin
(
r
.
Context
(),
ref
,
true
)
if
err
!=
nil
{
s
.
logger
.
Debugf
(
"pin root hash: creation of tracking pin for %q failed: %v"
,
addr
,
err
)
s
.
logger
.
Debugf
(
"pin root hash: creation of tracking pin for %q failed: %v"
,
ref
,
err
)
s
.
logger
.
Error
(
"pin root hash: creation of tracking pin failed"
)
jsonhttp
.
InternalServerError
(
w
,
nil
)
return
...
...
@@ -49,17 +49,17 @@ func (s *server) pinRootHash(w http.ResponseWriter, r *http.Request) {
// unpinRootHash unpin's an already pinned root hash. This method is idempotent.
func
(
s
*
server
)
unpinRootHash
(
w
http
.
ResponseWriter
,
r
*
http
.
Request
)
{
addr
,
err
:=
swarm
.
ParseHexAddress
(
mux
.
Vars
(
r
)[
"address
"
])
ref
,
err
:=
swarm
.
ParseHexAddress
(
mux
.
Vars
(
r
)[
"reference
"
])
if
err
!=
nil
{
s
.
logger
.
Debugf
(
"unpin root hash: unable to parse
address
: %v"
,
err
)
s
.
logger
.
Error
(
"unpin root hash: unable to parse
address
"
)
jsonhttp
.
BadRequest
(
w
,
"bad
address
"
)
s
.
logger
.
Debugf
(
"unpin root hash: unable to parse
reference
: %v"
,
err
)
s
.
logger
.
Error
(
"unpin root hash: unable to parse
reference
"
)
jsonhttp
.
BadRequest
(
w
,
"bad
reference
"
)
return
}
has
,
err
:=
s
.
pinning
.
HasPin
(
addr
)
has
,
err
:=
s
.
pinning
.
HasPin
(
ref
)
if
err
!=
nil
{
s
.
logger
.
Debugf
(
"pin root hash: checking of tracking pin for %q failed: %v"
,
addr
,
err
)
s
.
logger
.
Debugf
(
"pin root hash: checking of tracking pin for %q failed: %v"
,
ref
,
err
)
s
.
logger
.
Error
(
"pin root hash: checking of tracking pin failed"
)
jsonhttp
.
InternalServerError
(
w
,
nil
)
return
...
...
@@ -69,13 +69,13 @@ func (s *server) unpinRootHash(w http.ResponseWriter, r *http.Request) {
return
}
switch
err
:=
s
.
pinning
.
DeletePin
(
r
.
Context
(),
addr
);
{
switch
err
:=
s
.
pinning
.
DeletePin
(
r
.
Context
(),
ref
);
{
case
errors
.
Is
(
err
,
pinning
.
ErrTraversal
)
:
s
.
logger
.
Debugf
(
"unpin root hash: deletion of pin for %q failed: %v"
,
addr
,
err
)
s
.
logger
.
Debugf
(
"unpin root hash: deletion of pin for %q failed: %v"
,
ref
,
err
)
jsonhttp
.
InternalServerError
(
w
,
nil
)
return
case
err
!=
nil
:
s
.
logger
.
Debugf
(
"unpin root hash: deletion of pin for %q failed: %v"
,
addr
,
err
)
s
.
logger
.
Debugf
(
"unpin root hash: deletion of pin for %q failed: %v"
,
ref
,
err
)
s
.
logger
.
Error
(
"unpin root hash: deletion of pin for failed"
)
jsonhttp
.
InternalServerError
(
w
,
nil
)
return
...
...
@@ -84,20 +84,20 @@ func (s *server) unpinRootHash(w http.ResponseWriter, r *http.Request) {
jsonhttp
.
OK
(
w
,
nil
)
}
// getPinnedRootHash returns back the given
address
if its root hash is pinned.
// getPinnedRootHash returns back the given
reference
if its root hash is pinned.
func
(
s
*
server
)
getPinnedRootHash
(
w
http
.
ResponseWriter
,
r
*
http
.
Request
)
{
addr
,
err
:=
swarm
.
ParseHexAddress
(
mux
.
Vars
(
r
)[
"address
"
])
ref
,
err
:=
swarm
.
ParseHexAddress
(
mux
.
Vars
(
r
)[
"reference
"
])
if
err
!=
nil
{
s
.
logger
.
Debugf
(
"pinned root hash: unable to parse
address %q: %v"
,
addr
,
err
)
s
.
logger
.
Error
(
"pinned root hash: unable to parse
address
"
)
jsonhttp
.
BadRequest
(
w
,
"bad
address
"
)
s
.
logger
.
Debugf
(
"pinned root hash: unable to parse
reference %q: %v"
,
ref
,
err
)
s
.
logger
.
Error
(
"pinned root hash: unable to parse
reference
"
)
jsonhttp
.
BadRequest
(
w
,
"bad
reference
"
)
return
}
has
,
err
:=
s
.
pinning
.
HasPin
(
addr
)
has
,
err
:=
s
.
pinning
.
HasPin
(
ref
)
if
err
!=
nil
{
s
.
logger
.
Debugf
(
"pinned root hash: unable to check
address %q in the localstore: %v"
,
addr
,
err
)
s
.
logger
.
Error
(
"pinned root hash: unable to check
address
in the localstore"
)
s
.
logger
.
Debugf
(
"pinned root hash: unable to check
reference %q in the localstore: %v"
,
ref
,
err
)
s
.
logger
.
Error
(
"pinned root hash: unable to check
reference
in the localstore"
)
jsonhttp
.
InternalServerError
(
w
,
nil
)
return
}
...
...
@@ -108,25 +108,25 @@ func (s *server) getPinnedRootHash(w http.ResponseWriter, r *http.Request) {
}
jsonhttp
.
OK
(
w
,
struct
{
Address
swarm
.
Address
`json:"address
"`
Reference
swarm
.
Address
`json:"reference
"`
}{
Address
:
addr
,
Reference
:
ref
,
})
}
// listPinnedRootHashes lists all the
address of the pinned root hashes.
.
// listPinnedRootHashes lists all the
references of the pinned root hashes
.
func
(
s
*
server
)
listPinnedRootHashes
(
w
http
.
ResponseWriter
,
r
*
http
.
Request
)
{
pinned
,
err
:=
s
.
pinning
.
Pins
()
if
err
!=
nil
{
s
.
logger
.
Debugf
(
"list pinned root
addresses: unable to list address
es: %v"
,
err
)
s
.
logger
.
Error
(
"list pinned root
addresses: unable to list address
es"
)
s
.
logger
.
Debugf
(
"list pinned root
references: unable to list referenc
es: %v"
,
err
)
s
.
logger
.
Error
(
"list pinned root
references: unable to list referenc
es"
)
jsonhttp
.
InternalServerError
(
w
,
nil
)
return
}
jsonhttp
.
OK
(
w
,
struct
{
Addresses
[]
swarm
.
Address
`json:"address
es"`
References
[]
swarm
.
Address
`json:"referenc
es"`
}{
Address
es
:
pinned
,
Referenc
es
:
pinned
,
})
}
pkg/api/pin_test.go
View file @
f5aa73f8
...
...
@@ -31,46 +31,46 @@ func checkPinHandlers(t *testing.T, client *http.Client, rootHash string) {
const
pinsBasePath
=
"/pins"
var
(
pins
Address
Path
=
pinsBasePath
+
"/"
+
rootHash
pinsInvalid
Address
Path
=
pinsBasePath
+
"/"
+
"838d0a193ecd1152d1bb1432d5ecc02398533b2494889e23b8bd5ace30ac2zzz"
pinsUnknown
Address
Path
=
pinsBasePath
+
"/"
+
"838d0a193ecd1152d1bb1432d5ecc02398533b2494889e23b8bd5ace30ac2ccc"
pins
Reference
Path
=
pinsBasePath
+
"/"
+
rootHash
pinsInvalid
Reference
Path
=
pinsBasePath
+
"/"
+
"838d0a193ecd1152d1bb1432d5ecc02398533b2494889e23b8bd5ace30ac2zzz"
pinsUnknown
Reference
Path
=
pinsBasePath
+
"/"
+
"838d0a193ecd1152d1bb1432d5ecc02398533b2494889e23b8bd5ace30ac2ccc"
)
jsonhttptest
.
Request
(
t
,
client
,
http
.
MethodGet
,
pinsInvalid
Address
Path
,
http
.
StatusBadRequest
)
jsonhttptest
.
Request
(
t
,
client
,
http
.
MethodGet
,
pinsInvalid
Reference
Path
,
http
.
StatusBadRequest
)
jsonhttptest
.
Request
(
t
,
client
,
http
.
MethodGet
,
pinsUnknown
Address
Path
,
http
.
StatusNotFound
,
jsonhttptest
.
Request
(
t
,
client
,
http
.
MethodGet
,
pinsUnknown
Reference
Path
,
http
.
StatusNotFound
,
jsonhttptest
.
WithExpectedJSONResponse
(
jsonhttp
.
StatusResponse
{
Message
:
http
.
StatusText
(
http
.
StatusNotFound
),
Code
:
http
.
StatusNotFound
,
}),
)
jsonhttptest
.
Request
(
t
,
client
,
http
.
MethodPost
,
pins
Address
Path
,
http
.
StatusCreated
,
jsonhttptest
.
Request
(
t
,
client
,
http
.
MethodPost
,
pins
Reference
Path
,
http
.
StatusCreated
,
jsonhttptest
.
WithExpectedJSONResponse
(
jsonhttp
.
StatusResponse
{
Message
:
http
.
StatusText
(
http
.
StatusCreated
),
Code
:
http
.
StatusCreated
,
}),
)
jsonhttptest
.
Request
(
t
,
client
,
http
.
MethodGet
,
pins
Address
Path
,
http
.
StatusOK
,
jsonhttptest
.
Request
(
t
,
client
,
http
.
MethodGet
,
pins
Reference
Path
,
http
.
StatusOK
,
jsonhttptest
.
WithExpectedJSONResponse
(
struct
{
Address
swarm
.
Address
`json:"address
"`
Reference
swarm
.
Address
`json:"reference
"`
}{
Address
:
swarm
.
MustParseHexAddress
(
rootHash
),
Reference
:
swarm
.
MustParseHexAddress
(
rootHash
),
}),
)
jsonhttptest
.
Request
(
t
,
client
,
http
.
MethodGet
,
pinsBasePath
,
http
.
StatusOK
,
jsonhttptest
.
WithExpectedJSONResponse
(
struct
{
Addresses
[]
swarm
.
Address
`json:"address
es"`
References
[]
swarm
.
Address
`json:"referenc
es"`
}{
Address
es
:
[]
swarm
.
Address
{
swarm
.
MustParseHexAddress
(
rootHash
)},
Referenc
es
:
[]
swarm
.
Address
{
swarm
.
MustParseHexAddress
(
rootHash
)},
}),
)
jsonhttptest
.
Request
(
t
,
client
,
http
.
MethodDelete
,
pins
Address
Path
,
http
.
StatusOK
)
jsonhttptest
.
Request
(
t
,
client
,
http
.
MethodDelete
,
pins
Reference
Path
,
http
.
StatusOK
)
jsonhttptest
.
Request
(
t
,
client
,
http
.
MethodGet
,
pins
Address
Path
,
http
.
StatusNotFound
,
jsonhttptest
.
Request
(
t
,
client
,
http
.
MethodGet
,
pins
Reference
Path
,
http
.
StatusNotFound
,
jsonhttptest
.
WithExpectedJSONResponse
(
jsonhttp
.
StatusResponse
{
Message
:
http
.
StatusText
(
http
.
StatusNotFound
),
Code
:
http
.
StatusNotFound
,
...
...
pkg/api/router.go
View file @
f5aa73f8
...
...
@@ -143,7 +143,7 @@ func (s *server) setupRouting() {
"GET"
:
http
.
HandlerFunc
(
s
.
listPinnedRootHashes
),
})),
)
handle
(
"/pins/{
address
}"
,
web
.
ChainHandlers
(
handle
(
"/pins/{
reference
}"
,
web
.
ChainHandlers
(
s
.
gatewayModeForbidEndpointHandler
,
web
.
FinalHandler
(
jsonhttp
.
MethodHandler
{
"GET"
:
http
.
HandlerFunc
(
s
.
getPinnedRootHash
),
...
...
pkg/pinning/doc.go
View file @
f5aa73f8
...
...
@@ -3,5 +3,5 @@
// license that can be found in the LICENSE file.
// Package pinning provides a simple set of
// operations for tracking pinned
address
es.
// operations for tracking pinned
referenc
es.
package
pinning
pkg/pinning/mock/mock.go
View file @
f5aa73f8
...
...
@@ -21,43 +21,38 @@ func NewServiceMock() *ServiceMock {
// ServiceMock represents a simple mock of pinning.Interface.
// The implementation is not goroutine-safe.
type
ServiceMock
struct
{
index
map
[
string
]
int
entri
es
[]
swarm
.
Address
index
map
[
string
]
int
referenc
es
[]
swarm
.
Address
}
// CreatePin implements pinning.Interface CreatePin method.
func
(
sm
*
ServiceMock
)
CreatePin
(
_
context
.
Context
,
addr
swarm
.
Address
,
_
bool
)
error
{
if
_
,
ok
:=
sm
.
index
[
addr
.
String
()];
ok
{
func
(
sm
*
ServiceMock
)
CreatePin
(
_
context
.
Context
,
ref
swarm
.
Address
,
_
bool
)
error
{
if
_
,
ok
:=
sm
.
index
[
ref
.
String
()];
ok
{
return
nil
}
sm
.
index
[
addr
.
String
()]
=
len
(
sm
.
entri
es
)
sm
.
entries
=
append
(
sm
.
entries
,
addr
)
sm
.
index
[
ref
.
String
()]
=
len
(
sm
.
referenc
es
)
sm
.
references
=
append
(
sm
.
references
,
ref
)
return
nil
}
// DeletePin implements pinning.Interface DeletePin method.
func
(
sm
*
ServiceMock
)
DeletePin
(
_
context
.
Context
,
addr
swarm
.
Address
)
error
{
i
,
ok
:=
sm
.
index
[
addr
.
String
()]
func
(
sm
*
ServiceMock
)
DeletePin
(
_
context
.
Context
,
ref
swarm
.
Address
)
error
{
i
,
ok
:=
sm
.
index
[
ref
.
String
()]
if
!
ok
{
return
nil
}
delete
(
sm
.
index
,
addr
.
String
())
sm
.
entries
=
append
(
sm
.
entries
[
:
i
],
sm
.
entri
es
[
i
+
1
:
]
...
)
delete
(
sm
.
index
,
ref
.
String
())
sm
.
references
=
append
(
sm
.
references
[
:
i
],
sm
.
referenc
es
[
i
+
1
:
]
...
)
return
nil
}
// HasPin implements pinning.Interface HasPin method.
func
(
sm
*
ServiceMock
)
HasPin
(
addr
swarm
.
Address
)
(
bool
,
error
)
{
_
,
ok
:=
sm
.
index
[
addr
.
String
()]
func
(
sm
*
ServiceMock
)
HasPin
(
ref
swarm
.
Address
)
(
bool
,
error
)
{
_
,
ok
:=
sm
.
index
[
ref
.
String
()]
return
ok
,
nil
}
// Pins implements pinning.Interface Pins method.
func
(
sm
*
ServiceMock
)
Pins
()
([]
swarm
.
Address
,
error
)
{
return
append
([]
swarm
.
Address
(
nil
),
sm
.
entries
...
),
nil
}
// Entries returns all pinned entries.
func
(
sm
*
ServiceMock
)
Entries
()
[]
swarm
.
Address
{
return
sm
.
entries
return
append
([]
swarm
.
Address
(
nil
),
sm
.
references
...
),
nil
}
pkg/pinning/pinning.go
View file @
f5aa73f8
...
...
@@ -21,25 +21,25 @@ var ErrTraversal = errors.New("traversal iteration failed")
// Interface defines pinning operations.
type
Interface
interface
{
// CreatePin creates a new pin for the given
address
.
// CreatePin creates a new pin for the given
reference
.
// The boolean arguments specifies whether all nodes
// in the tree should also be traversed and pinned.
// Repeating calls of this method are idempotent.
CreatePin
(
context
.
Context
,
swarm
.
Address
,
bool
)
error
// DeletePin deletes given
address
. All the existing
// DeletePin deletes given
reference
. All the existing
// nodes in the tree will also be traversed and un-pinned.
// Repeating calls of this method are idempotent.
DeletePin
(
context
.
Context
,
swarm
.
Address
)
error
// HasPin returns true if the given
address
has root pin.
// HasPin returns true if the given
reference
has root pin.
HasPin
(
swarm
.
Address
)
(
bool
,
error
)
// Pins return all pinned
address
es.
// Pins return all pinned
referenc
es.
Pins
()
([]
swarm
.
Address
,
error
)
}
const
storePrefix
=
"root-pin"
func
rootPinKey
(
addr
swarm
.
Address
)
string
{
return
fmt
.
Sprintf
(
"%s-%s"
,
storePrefix
,
addr
)
func
rootPinKey
(
ref
swarm
.
Address
)
string
{
return
fmt
.
Sprintf
(
"%s-%s"
,
storePrefix
,
ref
)
}
// NewService is a convenient constructor for Service.
...
...
@@ -63,62 +63,62 @@ type Service struct {
}
// CreatePin implements Interface.CreatePin method.
func
(
s
*
Service
)
CreatePin
(
ctx
context
.
Context
,
addr
swarm
.
Address
,
traverse
bool
)
error
{
func
(
s
*
Service
)
CreatePin
(
ctx
context
.
Context
,
ref
swarm
.
Address
,
traverse
bool
)
error
{
// iterFn is a pinning iterator function over the leaves of the root.
iterFn
:=
func
(
leaf
swarm
.
Address
)
error
{
switch
err
:=
s
.
pinStorage
.
Set
(
ctx
,
storage
.
ModeSetPin
,
leaf
);
{
case
errors
.
Is
(
err
,
storage
.
ErrNotFound
)
:
ch
,
err
:=
s
.
pinStorage
.
Get
(
ctx
,
storage
.
ModeGetRequestPin
,
leaf
)
if
err
!=
nil
{
return
fmt
.
Errorf
(
"unable to get pin for leaf %q of root %q: %w"
,
leaf
,
addr
,
err
)
return
fmt
.
Errorf
(
"unable to get pin for leaf %q of root %q: %w"
,
leaf
,
ref
,
err
)
}
_
,
err
=
s
.
pinStorage
.
Put
(
ctx
,
storage
.
ModePutRequestPin
,
ch
)
if
err
!=
nil
{
return
fmt
.
Errorf
(
"unable to put pin for leaf %q of root %q: %w"
,
leaf
,
addr
,
err
)
return
fmt
.
Errorf
(
"unable to put pin for leaf %q of root %q: %w"
,
leaf
,
ref
,
err
)
}
case
err
!=
nil
:
return
fmt
.
Errorf
(
"unable to set pin for leaf %q of root %q: %w"
,
leaf
,
addr
,
err
)
return
fmt
.
Errorf
(
"unable to set pin for leaf %q of root %q: %w"
,
leaf
,
ref
,
err
)
}
return
nil
}
if
traverse
{
if
err
:=
s
.
traverser
.
Traverse
(
ctx
,
addr
,
iterFn
);
err
!=
nil
{
return
fmt
.
Errorf
(
"traversal of %q failed: %w"
,
addr
,
err
)
if
err
:=
s
.
traverser
.
Traverse
(
ctx
,
ref
,
iterFn
);
err
!=
nil
{
return
fmt
.
Errorf
(
"traversal of %q failed: %w"
,
ref
,
err
)
}
}
key
:=
rootPinKey
(
addr
)
key
:=
rootPinKey
(
ref
)
switch
err
:=
s
.
rhStorage
.
Get
(
key
,
new
(
swarm
.
Address
));
{
case
errors
.
Is
(
err
,
storage
.
ErrNotFound
)
:
return
s
.
rhStorage
.
Put
(
key
,
addr
)
return
s
.
rhStorage
.
Put
(
key
,
ref
)
case
err
!=
nil
:
return
fmt
.
Errorf
(
"unable to pin %q: %w"
,
addr
,
err
)
return
fmt
.
Errorf
(
"unable to pin %q: %w"
,
ref
,
err
)
}
return
nil
}
// DeletePin implements Interface.DeletePin method.
func
(
s
*
Service
)
DeletePin
(
ctx
context
.
Context
,
addr
swarm
.
Address
)
error
{
func
(
s
*
Service
)
DeletePin
(
ctx
context
.
Context
,
ref
swarm
.
Address
)
error
{
var
iterErr
error
// iterFn is a unpinning iterator function over the leaves of the root.
iterFn
:=
func
(
leaf
swarm
.
Address
)
error
{
err
:=
s
.
pinStorage
.
Set
(
ctx
,
storage
.
ModeSetUnpin
,
leaf
)
if
err
!=
nil
{
iterErr
=
multierror
.
Append
(
err
,
fmt
.
Errorf
(
"unable to unpin the chunk for leaf %q of root %q: %w"
,
leaf
,
addr
,
err
))
iterErr
=
multierror
.
Append
(
err
,
fmt
.
Errorf
(
"unable to unpin the chunk for leaf %q of root %q: %w"
,
leaf
,
ref
,
err
))
// Continue un-pinning all chunks.
}
return
nil
}
if
err
:=
s
.
traverser
.
Traverse
(
ctx
,
addr
,
iterFn
);
err
!=
nil
{
return
fmt
.
Errorf
(
"traversal of %q failed: %w"
,
addr
,
multierror
.
Append
(
err
,
iterErr
))
if
err
:=
s
.
traverser
.
Traverse
(
ctx
,
ref
,
iterFn
);
err
!=
nil
{
return
fmt
.
Errorf
(
"traversal of %q failed: %w"
,
ref
,
multierror
.
Append
(
err
,
iterErr
))
}
if
iterErr
!=
nil
{
return
multierror
.
Append
(
ErrTraversal
,
iterErr
)
}
key
:=
rootPinKey
(
addr
)
key
:=
rootPinKey
(
ref
)
if
err
:=
s
.
rhStorage
.
Delete
(
key
);
err
!=
nil
{
return
fmt
.
Errorf
(
"unable to delete pin for key %q: %w"
,
key
,
err
)
}
...
...
@@ -126,30 +126,30 @@ func (s *Service) DeletePin(ctx context.Context, addr swarm.Address) error {
}
// HasPin implements Interface.HasPin method.
func
(
s
*
Service
)
HasPin
(
addr
swarm
.
Address
)
(
bool
,
error
)
{
key
,
val
:=
rootPinKey
(
addr
),
swarm
.
NewAddress
(
nil
)
func
(
s
*
Service
)
HasPin
(
ref
swarm
.
Address
)
(
bool
,
error
)
{
key
,
val
:=
rootPinKey
(
ref
),
swarm
.
NewAddress
(
nil
)
switch
err
:=
s
.
rhStorage
.
Get
(
key
,
&
val
);
{
case
errors
.
Is
(
err
,
storage
.
ErrNotFound
)
:
return
false
,
nil
case
err
!=
nil
:
return
false
,
fmt
.
Errorf
(
"unable to get pin for key %q: %w"
,
key
,
err
)
}
return
val
.
Equal
(
addr
),
nil
return
val
.
Equal
(
ref
),
nil
}
// Pins implements Interface.Pins method.
func
(
s
*
Service
)
Pins
()
([]
swarm
.
Address
,
error
)
{
var
addr
s
[]
swarm
.
Address
var
ref
s
[]
swarm
.
Address
err
:=
s
.
rhStorage
.
Iterate
(
storePrefix
,
func
(
key
,
val
[]
byte
)
(
stop
bool
,
err
error
)
{
var
addr
swarm
.
Address
if
err
:=
json
.
Unmarshal
(
val
,
&
addr
);
err
!=
nil
{
return
true
,
fmt
.
Errorf
(
"invalid
address
value %q: %w"
,
string
(
val
),
err
)
var
ref
swarm
.
Address
if
err
:=
json
.
Unmarshal
(
val
,
&
ref
);
err
!=
nil
{
return
true
,
fmt
.
Errorf
(
"invalid
reference
value %q: %w"
,
string
(
val
),
err
)
}
addrs
=
append
(
addrs
,
addr
)
refs
=
append
(
refs
,
ref
)
return
false
,
nil
})
if
err
!=
nil
{
return
nil
,
fmt
.
Errorf
(
"iteration failed: %w"
,
err
)
}
return
addr
s
,
nil
return
ref
s
,
nil
}
pkg/pinning/pinning_test.go
View file @
f5aa73f8
...
...
@@ -32,49 +32,49 @@ func TestPinningService(t *testing.T) {
)
pipe
:=
builder
.
NewPipelineBuilder
(
ctx
,
storerMock
,
storage
.
ModePutUpload
,
false
)
addr
,
err
:=
builder
.
FeedPipeline
(
ctx
,
pipe
,
strings
.
NewReader
(
content
),
int64
(
len
(
content
)))
ref
,
err
:=
builder
.
FeedPipeline
(
ctx
,
pipe
,
strings
.
NewReader
(
content
),
int64
(
len
(
content
)))
if
err
!=
nil
{
t
.
Fatal
(
err
)
}
t
.
Run
(
"create and list"
,
func
(
t
*
testing
.
T
)
{
if
err
:=
service
.
CreatePin
(
ctx
,
addr
,
false
);
err
!=
nil
{
if
err
:=
service
.
CreatePin
(
ctx
,
ref
,
false
);
err
!=
nil
{
t
.
Fatalf
(
"CreatePin(...): unexpected error: %v"
,
err
)
}
addr
s
,
err
:=
service
.
Pins
()
ref
s
,
err
:=
service
.
Pins
()
if
err
!=
nil
{
t
.
Fatalf
(
"Pins(...): unexpected error: %v"
,
err
)
}
if
have
,
want
:=
len
(
addr
s
),
1
;
have
!=
want
{
if
have
,
want
:=
len
(
ref
s
),
1
;
have
!=
want
{
t
.
Fatalf
(
"Pins(...): have %d; want %d"
,
have
,
want
)
}
if
have
,
want
:=
addrs
[
0
],
addr
;
!
have
.
Equal
(
want
)
{
t
.
Fatalf
(
"
address
mismatch: have %q; want %q"
,
have
,
want
)
if
have
,
want
:=
refs
[
0
],
ref
;
!
have
.
Equal
(
want
)
{
t
.
Fatalf
(
"
reference
mismatch: have %q; want %q"
,
have
,
want
)
}
})
t
.
Run
(
"create idempotent and list"
,
func
(
t
*
testing
.
T
)
{
if
err
:=
service
.
CreatePin
(
ctx
,
addr
,
false
);
err
!=
nil
{
if
err
:=
service
.
CreatePin
(
ctx
,
ref
,
false
);
err
!=
nil
{
t
.
Fatalf
(
"CreatePin(...): unexpected error: %v"
,
err
)
}
addr
s
,
err
:=
service
.
Pins
()
ref
s
,
err
:=
service
.
Pins
()
if
err
!=
nil
{
t
.
Fatalf
(
"Pins(...): unexpected error: %v"
,
err
)
}
if
have
,
want
:=
len
(
addr
s
),
1
;
have
!=
want
{
if
have
,
want
:=
len
(
ref
s
),
1
;
have
!=
want
{
t
.
Fatalf
(
"Pins(...): have %d; want %d"
,
have
,
want
)
}
if
have
,
want
:=
addrs
[
0
],
addr
;
!
have
.
Equal
(
want
)
{
t
.
Fatalf
(
"
address
mismatch: have %q; want %q"
,
have
,
want
)
if
have
,
want
:=
refs
[
0
],
ref
;
!
have
.
Equal
(
want
)
{
t
.
Fatalf
(
"
reference
mismatch: have %q; want %q"
,
have
,
want
)
}
})
t
.
Run
(
"delete and has"
,
func
(
t
*
testing
.
T
)
{
err
:=
service
.
DeletePin
(
ctx
,
addr
)
err
:=
service
.
DeletePin
(
ctx
,
ref
)
if
err
!=
nil
{
t
.
Fatalf
(
"DeletePin(...): unexpected error: %v"
,
err
)
}
has
,
err
:=
service
.
HasPin
(
addr
)
has
,
err
:=
service
.
HasPin
(
ref
)
if
err
!=
nil
{
t
.
Fatalf
(
"HasPin(...): unexpected error: %v"
,
err
)
}
...
...
@@ -84,11 +84,11 @@ func TestPinningService(t *testing.T) {
})
t
.
Run
(
"delete idempotent and has"
,
func
(
t
*
testing
.
T
)
{
err
:=
service
.
DeletePin
(
ctx
,
addr
)
err
:=
service
.
DeletePin
(
ctx
,
ref
)
if
err
!=
nil
{
t
.
Fatalf
(
"DeletePin(...): unexpected error: %v"
,
err
)
}
has
,
err
:=
service
.
HasPin
(
addr
)
has
,
err
:=
service
.
HasPin
(
ref
)
if
err
!=
nil
{
t
.
Fatalf
(
"HasPin(...): unexpected error: %v"
,
err
)
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment