forked from neo-project/neo-modules
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request neo-project#4 from joeqian10/NeoFsStorageNode
Initial commit
- Loading branch information
Showing
56 changed files
with
3,613 additions
and
6 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
namespace Neo.Fs.Core.Netmap | ||
{ | ||
public interface IState | ||
{ | ||
ulong CurrentEpoch(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
using NeoFS.API.v2.Netmap; | ||
|
||
namespace Neo.Fs.Core.Netmap | ||
{ | ||
// Source is an interface that wraps | ||
// basic network map receiving method. | ||
public interface ISource | ||
{ | ||
// GetNetMap reads the diff-th past network map from the storage. | ||
// Calling with zero diff returns latest network map. | ||
// It returns the pointer to requested network map and any error encountered. | ||
// | ||
// GetNetMap must return exactly one non-nil value. | ||
// GetNetMap must return ErrNotFound if the network map is not in storage. | ||
// | ||
// Implementations must not retain the network map pointer and modify | ||
// the network map through it. | ||
|
||
NetMap GetNetMap(ulong diff); | ||
} | ||
|
||
public static class Helper | ||
{ | ||
public static NetMap GetLatestNetworkMap(this ISource src) | ||
{ | ||
return src.GetNetMap(0); | ||
} | ||
|
||
public static NetMap GetPreviousNetworkMap(this ISource src) | ||
{ | ||
return src.GetNetMap(1); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,101 @@ | ||
using Google.Protobuf; | ||
using Neo.Cryptography.ECC; | ||
using Neo.IO; | ||
using Neo.SmartContract; | ||
using NeoFS.API.v2.Object; | ||
using NeoFS.API.v2.Refs; | ||
using System; | ||
using V2Object = NeoFS.API.v2.Object.Object; | ||
|
||
namespace Neo.Fs.Core.Object | ||
{ | ||
public interface IDeleteHandler | ||
{ | ||
void DeleteObjects(params Address[] objAddrs); | ||
} | ||
|
||
public class Cfg | ||
{ | ||
private IDeleteHandler deleteHandler; | ||
} | ||
|
||
public class FormatValidator | ||
{ | ||
private Cfg cfg; | ||
|
||
public FormatValidator(FormatValidatorOption[] opts) | ||
{ | ||
var c = new Cfg(); | ||
|
||
foreach (var opt in opts) | ||
{ | ||
opt(c); | ||
} | ||
|
||
this.cfg = c; | ||
} | ||
|
||
public void Validate(V2Object obj) | ||
{ | ||
if (obj is null) | ||
throw new ArgumentNullException("object is null"); | ||
else if (obj.ObjectId is null) | ||
throw new ArgumentException("missing identifier"); | ||
else if (obj.Header is null || obj.Header.ContainerId is null) | ||
throw new ArgumentException("missing container identifier"); | ||
|
||
while (obj != null) | ||
{ | ||
|
||
|
||
|
||
} | ||
} | ||
|
||
private void ValidateSignatureKey(V2Object obj) | ||
{ | ||
var token = obj.Header.SessionToken; | ||
var key = obj.Signature.Key; | ||
|
||
if (token is null || !token.Body.SessionKey.Equals(key)) | ||
CheckOwnerKey(obj.Header.OwnerId, obj.Signature.Key.ToByteArray()); | ||
|
||
// TODO: perform token verification | ||
} | ||
|
||
private void CheckOwnerKey(OwnerID id, byte[] key) | ||
{ | ||
var pubKey = ECPoint.FromBytes(key, ECCurve.Secp256r1); | ||
var scriptHash = pubKey.EncodePoint(true).ToScriptHash(); | ||
var w = scriptHash.ToArray()[..25]; | ||
|
||
var id2 = new OwnerID() { Value = ByteString.CopyFrom(w) }; | ||
|
||
if (id.ToByteString() != id2.ToByteString()) | ||
throw new Exception(string.Format("different owner identifiers: {0}, {1}", id.ToByteString(), id2.ToByteString())); | ||
} | ||
|
||
public void ValidateContent(ObjectType t, byte[] payload) | ||
{ | ||
switch (t) | ||
{ | ||
case ObjectType.Regular: | ||
break; | ||
case ObjectType.Tombstone: | ||
if (payload.Length == 0) | ||
throw new Exception("empty payload in tombstone"); | ||
break; | ||
case ObjectType.StorageGroup: | ||
break; | ||
default: | ||
break; | ||
} | ||
|
||
} | ||
|
||
} | ||
|
||
public delegate void FormatValidatorOption(Cfg cfg); | ||
|
||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
using NeoFS.API.v2.Refs; | ||
|
||
namespace Neo.Fs.Core.Object | ||
{ | ||
public class TombstoneContent | ||
{ | ||
//private Address[] addrList; | ||
|
||
public Address[] AddrList { get; set; } | ||
|
||
//public byte[] StableMarshal(byte[] buf) | ||
//{ | ||
// if (buf is null) | ||
// buf = new byte[0]; | ||
|
||
// var offset = 0; | ||
// foreach (var addr in AddrList) | ||
// { | ||
// proto | ||
// } | ||
//} | ||
} | ||
} |
106 changes: 106 additions & 0 deletions
106
NeoFsStorageNode/LocalObjectStorage/Bucket/DbBucket/DbBucket.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,106 @@ | ||
using Neo.IO.Data.LevelDB; | ||
using System; | ||
using System.Linq; | ||
using System.Text; | ||
using LevelDbOptions = Neo.IO.Data.LevelDB.Options; | ||
|
||
namespace Neo.Fs.LocalObjectStorage.Bucket | ||
{ | ||
public class DbBucket:IBucket | ||
{ | ||
private readonly DB db; | ||
public byte[] Name { get; set; } | ||
|
||
// TBD | ||
public DbBucket(Options opts) | ||
{ | ||
this.db = DB.Open(opts.Path, opts.LevelDbOptions); | ||
} | ||
|
||
public byte[] Get(byte[] key) | ||
{ | ||
return db.Get(ReadOptions.Default, key); | ||
} | ||
|
||
public void Set(byte[] key, byte[] value) | ||
{ | ||
db.Put(WriteOptions.Default, key, value); | ||
} | ||
|
||
public void Del(byte[] key) | ||
{ | ||
db.Delete(WriteOptions.Default, key); | ||
} | ||
|
||
public bool Has(byte[] key) | ||
{ | ||
var r = db.Get(ReadOptions.Default, key); | ||
return !(r is null) && r.Length != 0; | ||
} | ||
|
||
public long Size() | ||
{ | ||
//throw new NotImplementedException(); | ||
long size = 0; | ||
ReadOptions opt = new ReadOptions { FillCache = false }; | ||
using (Iterator it = db.NewIterator(opt)) | ||
{ | ||
for (it.SeekToFirst(); it.Valid(); it.Next()) | ||
{ | ||
size += it.Value().Length; | ||
} | ||
} | ||
return size; | ||
} | ||
|
||
public byte[][] List() | ||
{ | ||
byte[][] r = new byte[][] { }; | ||
ReadOptions opt = new ReadOptions { FillCache = false }; | ||
using (Iterator it = db.NewIterator(opt)) | ||
{ | ||
for (it.SeekToFirst(); it.Valid(); it.Next()) | ||
{ | ||
r = r.Append(it.Value()).ToArray(); | ||
} | ||
} | ||
return r; | ||
} | ||
|
||
public void Iterate(FilterHandler handler) | ||
{ | ||
if (handler is null) | ||
throw new ArgumentException("handler cannot be null"); | ||
ReadOptions opt = new ReadOptions { FillCache = false }; | ||
using (Iterator it = db.NewIterator(opt)) | ||
{ | ||
for (it.SeekToFirst(); it.Valid(); it.Next()) | ||
{ | ||
if (!handler(it.Key(), it.Value())) | ||
throw new Exception("iteration aborted"); | ||
} | ||
} | ||
} | ||
|
||
public void Close() | ||
{ | ||
db.Dispose(); | ||
} | ||
} | ||
|
||
public class Options | ||
{ | ||
public LevelDbOptions LevelDbOptions { get; set; } | ||
public byte[] Name { get; set; } | ||
public string Path { get; set; } | ||
//public uint Perm { get; set; } // FileMode | ||
|
||
public Options(string path, LevelDbOptions levelDbOptions) | ||
{ | ||
this.Name = Encoding.ASCII.GetBytes("leveldb"); | ||
this.Path = path; | ||
//this.Perm = 0777; | ||
this.LevelDbOptions = levelDbOptions; | ||
} | ||
} | ||
} |
114 changes: 114 additions & 0 deletions
114
NeoFsStorageNode/LocalObjectStorage/Bucket/FsBucket/Bucket.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,114 @@ | ||
using System; | ||
using System.IO; | ||
using System.Linq; | ||
|
||
namespace Neo.Fs.LocalObjectStorage.Bucket | ||
{ | ||
public class Bucket : IBucket | ||
{ | ||
public string Dir { get; set; } | ||
public uint Perm { get; set; } // FileMode | ||
|
||
//public Bucket(string prefix, ) | ||
//{ | ||
|
||
//} | ||
|
||
public byte[] Get(byte[] key) | ||
{ | ||
var p = Path.Join(this.Dir, Helper.StringifyKey(key)); | ||
if (!File.Exists(p)) | ||
throw new ArgumentException("key not found"); | ||
return File.ReadAllBytes(p); | ||
} | ||
|
||
public void Set(byte[] key, byte[] value) | ||
{ | ||
var p = Path.Join(this.Dir, Helper.StringifyKey(key)); | ||
File.WriteAllBytes(p, value); | ||
} | ||
|
||
public void Del(byte[] key) | ||
{ | ||
var p = Path.Join(this.Dir, Helper.StringifyKey(key)); | ||
if (!File.Exists(p)) | ||
throw new ArgumentException("key not found"); | ||
File.Delete(p); | ||
} | ||
|
||
public bool Has(byte[] key) | ||
{ | ||
var p = Path.Join(this.Dir, Helper.StringifyKey(key)); | ||
return File.Exists(p); | ||
} | ||
|
||
private delegate void Fn(string path); // process file | ||
|
||
private static void Listing(string root, Fn fn) | ||
{ | ||
if (fn == null) | ||
return; | ||
if (File.Exists(root)) // path is a file | ||
{ | ||
fn(root); | ||
} | ||
else if (Directory.Exists(root)) // path is a directory | ||
{ | ||
string[] files = Directory.GetFiles(root); | ||
foreach (string file in files) | ||
fn(file); | ||
|
||
string[] dirs = Directory.GetDirectories(root); | ||
foreach (string dir in dirs) | ||
Listing(dir, fn); | ||
} | ||
else | ||
{ | ||
throw new ArgumentException(); | ||
} | ||
} | ||
|
||
public long Size() | ||
{ | ||
long size = 0; | ||
Fn fn = p => | ||
{ | ||
FileInfo info = new FileInfo(p); | ||
size += info.Length; | ||
}; | ||
Listing(this.Dir, fn); | ||
return size; | ||
} | ||
|
||
public byte[][] List() | ||
{ | ||
var buckets = new byte[][] { }; | ||
Fn fn = p => | ||
{ | ||
FileInfo info = new FileInfo(p); | ||
buckets = buckets.Append(Helper.DecodeKey(info.Name)).ToArray(); | ||
}; | ||
Listing(this.Dir, fn); | ||
return buckets; | ||
} | ||
|
||
public void Iterate(FilterHandler handler) | ||
{ | ||
Fn fn = p => | ||
{ | ||
FileInfo info = new FileInfo(p); | ||
var key = Helper.DecodeKey(info.Name); | ||
var value = File.ReadAllBytes(p); | ||
if (!handler(key, value)) | ||
throw new Exception("iteration aborted"); | ||
}; | ||
Listing(this.Dir, fn); | ||
} | ||
|
||
// delete all files in this bucket | ||
public void Close() | ||
{ | ||
Directory.Delete(Dir, true); | ||
} | ||
} | ||
} |
Oops, something went wrong.