mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-08-18 09:53:48 +00:00
swarm/api: Implement encrypted manifest creation and update
This commit is contained in:
parent
ca6b22ee7c
commit
3e304ce36c
6 changed files with 40 additions and 28 deletions
|
|
@ -379,7 +379,7 @@ func (self *Api) Modify(key storage.Key, path, contentHash, contentType string)
|
||||||
apiModifyFail.Inc(1)
|
apiModifyFail.Inc(1)
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return trie.hash, nil
|
return trie.ref, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *Api) AddFile(mhash, path, fname string, content []byte, nameresolver bool) (storage.Key, string, error) {
|
func (self *Api) AddFile(mhash, path, fname string, content []byte, nameresolver bool) (storage.Key, string, error) {
|
||||||
|
|
|
||||||
|
|
@ -164,7 +164,7 @@ func (self *FileSystem) Upload(lpath, index string, toEncrypt bool) (string, err
|
||||||
err2 := trie.recalcAndStore()
|
err2 := trie.recalcAndStore()
|
||||||
var hs string
|
var hs string
|
||||||
if err2 == nil {
|
if err2 == nil {
|
||||||
hs = trie.hash.Hex()
|
hs = trie.ref.Hex()
|
||||||
}
|
}
|
||||||
awg.Wait()
|
awg.Wait()
|
||||||
return hs, err2
|
return hs, err2
|
||||||
|
|
|
||||||
|
|
@ -177,8 +177,13 @@ func (s *Server) HandlePostFiles(w http.ResponseWriter, r *Request) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
toEncrypt := false
|
||||||
|
if r.uri.Addr == "encrypt" {
|
||||||
|
toEncrypt = true
|
||||||
|
}
|
||||||
|
|
||||||
var key storage.Key
|
var key storage.Key
|
||||||
if r.uri.Addr != "" {
|
if r.uri.Addr != "" && r.uri.Addr != "encrypt" {
|
||||||
key, err = s.api.Resolve(r.uri)
|
key, err = s.api.Resolve(r.uri)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
postFilesFail.Inc(1)
|
postFilesFail.Inc(1)
|
||||||
|
|
@ -187,7 +192,7 @@ func (s *Server) HandlePostFiles(w http.ResponseWriter, r *Request) {
|
||||||
}
|
}
|
||||||
log.Debug("resolved key", "ruid", r.ruid, "key", key)
|
log.Debug("resolved key", "ruid", r.ruid, "key", key)
|
||||||
} else {
|
} else {
|
||||||
key, err = s.api.NewManifest(false)
|
key, err = s.api.NewManifest(toEncrypt)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
postFilesFail.Inc(1)
|
postFilesFail.Inc(1)
|
||||||
Respond(w, r, err.Error(), http.StatusInternalServerError)
|
Respond(w, r, err.Error(), http.StatusInternalServerError)
|
||||||
|
|
@ -376,7 +381,7 @@ func (s *Server) HandlePostResource(w http.ResponseWriter, r *Request) {
|
||||||
Respond(w, r, err2.Error(), code)
|
Respond(w, r, err2.Error(), code)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
m, err := s.api.NewResourceManifest(r.uri.Addr, false)
|
m, err := s.api.NewResourceManifest(r.uri.Addr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
Respond(w, r, fmt.Sprintf("failed to create resource manifest: %v", err), http.StatusInternalServerError)
|
Respond(w, r, fmt.Sprintf("failed to create resource manifest: %v", err), http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
|
|
|
||||||
|
|
@ -218,8 +218,8 @@ func TestBzzResource(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestBzzGetPath(t *testing.T) {
|
func TestBzzGetPath(t *testing.T) {
|
||||||
// testBzzGetPath(false, t)
|
testBzzGetPath(false, t)
|
||||||
testBzzGetPath(true, t)
|
// testBzzGetPath(true, t)
|
||||||
}
|
}
|
||||||
|
|
||||||
func testBzzGetPath(encrypted bool, t *testing.T) {
|
func testBzzGetPath(encrypted bool, t *testing.T) {
|
||||||
|
|
|
||||||
|
|
@ -72,7 +72,7 @@ func (a *Api) NewManifest(toEncrypt bool) (storage.Key, error) {
|
||||||
|
|
||||||
// Manifest hack for supporting Mutable Resource Updates from the bzz: scheme
|
// Manifest hack for supporting Mutable Resource Updates from the bzz: scheme
|
||||||
// see swarm/api/api.go:Api.Get() for more information
|
// see swarm/api/api.go:Api.Get() for more information
|
||||||
func (a *Api) NewResourceManifest(resourceKey string, toEncrypt bool) (storage.Key, error) {
|
func (a *Api) NewResourceManifest(resourceKey string) (storage.Key, error) {
|
||||||
var manifest Manifest
|
var manifest Manifest
|
||||||
entry := ManifestEntry{
|
entry := ManifestEntry{
|
||||||
Hash: resourceKey,
|
Hash: resourceKey,
|
||||||
|
|
@ -83,7 +83,7 @@ func (a *Api) NewResourceManifest(resourceKey string, toEncrypt bool) (storage.K
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
key, _, err := a.Store(bytes.NewReader(data), int64(len(data)), toEncrypt)
|
key, _, err := a.Store(bytes.NewReader(data), int64(len(data)), false)
|
||||||
return key, err
|
return key, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -105,9 +105,7 @@ func (a *Api) NewManifestWriter(key storage.Key, quitC chan bool) (*ManifestWrit
|
||||||
// AddEntry stores the given data and adds the resulting key to the manifest
|
// AddEntry stores the given data and adds the resulting key to the manifest
|
||||||
func (m *ManifestWriter) AddEntry(data io.Reader, e *ManifestEntry) (storage.Key, error) {
|
func (m *ManifestWriter) AddEntry(data io.Reader, e *ManifestEntry) (storage.Key, error) {
|
||||||
|
|
||||||
toEncrypt := (len(m.trie.hash) > m.trie.dpa.HashSize())
|
key, _, err := m.api.Store(data, e.Size, m.trie.encrypted)
|
||||||
|
|
||||||
key, _, err := m.api.Store(data, e.Size, toEncrypt)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
@ -125,7 +123,7 @@ func (m *ManifestWriter) RemoveEntry(path string) error {
|
||||||
|
|
||||||
// Store stores the manifest, returning the resulting storage key
|
// Store stores the manifest, returning the resulting storage key
|
||||||
func (m *ManifestWriter) Store() (storage.Key, error) {
|
func (m *ManifestWriter) Store() (storage.Key, error) {
|
||||||
return m.trie.hash, m.trie.recalcAndStore()
|
return m.trie.ref, m.trie.recalcAndStore()
|
||||||
}
|
}
|
||||||
|
|
||||||
// ManifestWalker is used to recursively walk the entries in the manifest and
|
// ManifestWalker is used to recursively walk the entries in the manifest and
|
||||||
|
|
@ -187,7 +185,8 @@ func (m *ManifestWalker) walk(trie *manifestTrie, prefix string, walkFn WalkFn)
|
||||||
type manifestTrie struct {
|
type manifestTrie struct {
|
||||||
dpa *storage.DPA
|
dpa *storage.DPA
|
||||||
entries [257]*manifestTrieEntry // indexed by first character of basePath, entries[256] is the empty basePath entry
|
entries [257]*manifestTrieEntry // indexed by first character of basePath, entries[256] is the empty basePath entry
|
||||||
hash storage.Key // if hash != nil, it is stored
|
ref storage.Key // if ref != nil, it is stored
|
||||||
|
encrypted bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func newManifestTrieEntry(entry *ManifestEntry, subtrie *manifestTrie) *manifestTrieEntry {
|
func newManifestTrieEntry(entry *ManifestEntry, subtrie *manifestTrie) *manifestTrieEntry {
|
||||||
|
|
@ -231,7 +230,7 @@ func readManifest(manifestReader storage.LazySectionReader, hash storage.Key, dp
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Trace("manifest retrieved", "key", hash)
|
log.Debug("manifest retrieved", "key", hash)
|
||||||
var man struct {
|
var man struct {
|
||||||
Entries []*manifestTrieEntry `json:"entries"`
|
Entries []*manifestTrieEntry `json:"entries"`
|
||||||
}
|
}
|
||||||
|
|
@ -246,6 +245,7 @@ func readManifest(manifestReader storage.LazySectionReader, hash storage.Key, dp
|
||||||
|
|
||||||
trie = &manifestTrie{
|
trie = &manifestTrie{
|
||||||
dpa: dpa,
|
dpa: dpa,
|
||||||
|
encrypted: (len(hash) > dpa.HashSize()),
|
||||||
}
|
}
|
||||||
for _, entry := range man.Entries {
|
for _, entry := range man.Entries {
|
||||||
trie.addEntry(entry, quitC)
|
trie.addEntry(entry, quitC)
|
||||||
|
|
@ -254,7 +254,7 @@ func readManifest(manifestReader storage.LazySectionReader, hash storage.Key, dp
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *manifestTrie) addEntry(entry *manifestTrieEntry, quitC chan bool) {
|
func (self *manifestTrie) addEntry(entry *manifestTrieEntry, quitC chan bool) {
|
||||||
self.hash = nil // trie modified, hash needs to be re-calculated on demand
|
self.ref = nil // trie modified, hash needs to be re-calculated on demand
|
||||||
|
|
||||||
if len(entry.Path) == 0 {
|
if len(entry.Path) == 0 {
|
||||||
self.entries[256] = entry
|
self.entries[256] = entry
|
||||||
|
|
@ -287,6 +287,7 @@ func (self *manifestTrie) addEntry(entry *manifestTrieEntry, quitC chan bool) {
|
||||||
|
|
||||||
subtrie := &manifestTrie{
|
subtrie := &manifestTrie{
|
||||||
dpa: self.dpa,
|
dpa: self.dpa,
|
||||||
|
encrypted: self.encrypted,
|
||||||
}
|
}
|
||||||
entry.Path = entry.Path[cpl:]
|
entry.Path = entry.Path[cpl:]
|
||||||
oldentry.Path = oldentry.Path[cpl:]
|
oldentry.Path = oldentry.Path[cpl:]
|
||||||
|
|
@ -310,7 +311,7 @@ func (self *manifestTrie) getCountLast() (cnt int, entry *manifestTrieEntry) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *manifestTrie) deleteEntry(path string, quitC chan bool) {
|
func (self *manifestTrie) deleteEntry(path string, quitC chan bool) {
|
||||||
self.hash = nil // trie modified, hash needs to be re-calculated on demand
|
self.ref = nil // trie modified, hash needs to be re-calculated on demand
|
||||||
|
|
||||||
if len(path) == 0 {
|
if len(path) == 0 {
|
||||||
self.entries[256] = nil
|
self.entries[256] = nil
|
||||||
|
|
@ -346,7 +347,7 @@ func (self *manifestTrie) deleteEntry(path string, quitC chan bool) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *manifestTrie) recalcAndStore() error {
|
func (self *manifestTrie) recalcAndStore() error {
|
||||||
if self.hash != nil {
|
if self.ref != nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -361,7 +362,7 @@ func (self *manifestTrie) recalcAndStore() error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
entry.Hash = entry.subtrie.hash.Hex()
|
entry.Hash = entry.subtrie.ref.Hex()
|
||||||
}
|
}
|
||||||
list.Entries = append(list.Entries, entry.ManifestEntry)
|
list.Entries = append(list.Entries, entry.ManifestEntry)
|
||||||
}
|
}
|
||||||
|
|
@ -374,9 +375,9 @@ func (self *manifestTrie) recalcAndStore() error {
|
||||||
}
|
}
|
||||||
|
|
||||||
sr := bytes.NewReader(manifest)
|
sr := bytes.NewReader(manifest)
|
||||||
key, wait, err2 := self.dpa.Store(sr, int64(len(manifest)), false)
|
key, wait, err2 := self.dpa.Store(sr, int64(len(manifest)), self.encrypted)
|
||||||
wait()
|
wait()
|
||||||
self.hash = key
|
self.ref = key
|
||||||
return err2
|
return err2
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -42,7 +42,9 @@ func manifest(paths ...string) (manifestReader storage.LazySectionReader) {
|
||||||
|
|
||||||
func testGetEntry(t *testing.T, path, match string, multiple bool, paths ...string) *manifestTrie {
|
func testGetEntry(t *testing.T, path, match string, multiple bool, paths ...string) *manifestTrie {
|
||||||
quitC := make(chan bool)
|
quitC := make(chan bool)
|
||||||
trie, err := readManifest(manifest(paths...), nil, nil, quitC)
|
dpa := storage.NewDPA(nil, storage.NewDPAParams())
|
||||||
|
ref := make([]byte, dpa.HashSize())
|
||||||
|
trie, err := readManifest(manifest(paths...), ref, dpa, quitC)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("unexpected error making manifest: %v", err)
|
t.Errorf("unexpected error making manifest: %v", err)
|
||||||
}
|
}
|
||||||
|
|
@ -97,7 +99,9 @@ func TestGetEntry(t *testing.T) {
|
||||||
func TestExactMatch(t *testing.T) {
|
func TestExactMatch(t *testing.T) {
|
||||||
quitC := make(chan bool)
|
quitC := make(chan bool)
|
||||||
mf := manifest("shouldBeExactMatch.css", "shouldBeExactMatch.css.map")
|
mf := manifest("shouldBeExactMatch.css", "shouldBeExactMatch.css.map")
|
||||||
trie, err := readManifest(mf, nil, nil, quitC)
|
dpa := storage.NewDPA(nil, storage.NewDPAParams())
|
||||||
|
ref := make([]byte, dpa.HashSize())
|
||||||
|
trie, err := readManifest(mf, ref, dpa, quitC)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("unexpected error making manifest: %v", err)
|
t.Errorf("unexpected error making manifest: %v", err)
|
||||||
}
|
}
|
||||||
|
|
@ -128,7 +132,9 @@ func TestAddFileWithManifestPath(t *testing.T) {
|
||||||
reader := &storage.LazyTestSectionReader{
|
reader := &storage.LazyTestSectionReader{
|
||||||
SectionReader: io.NewSectionReader(bytes.NewReader(manifest), 0, int64(len(manifest))),
|
SectionReader: io.NewSectionReader(bytes.NewReader(manifest), 0, int64(len(manifest))),
|
||||||
}
|
}
|
||||||
trie, err := readManifest(reader, nil, nil, nil)
|
dpa := storage.NewDPA(nil, storage.NewDPAParams())
|
||||||
|
ref := make([]byte, dpa.HashSize())
|
||||||
|
trie, err := readManifest(reader, ref, dpa, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue