Skip to content

Commit

Permalink
Merge pull request neo-project#4 from joeqian10/NeoFsStorageNode
Browse files Browse the repository at this point in the history
Initial commit
  • Loading branch information
ZhangTao authored Nov 25, 2020
2 parents 3dd7765 + 9ec597f commit 2a19dfd
Show file tree
Hide file tree
Showing 56 changed files with 3,613 additions and 6 deletions.
7 changes: 7 additions & 0 deletions NeoFsStorageNode/Core/Netmap/IState.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
namespace Neo.Fs.Core.Netmap
{
public interface IState
{
ulong CurrentEpoch();
}
}
34 changes: 34 additions & 0 deletions NeoFsStorageNode/Core/Netmap/Storage.cs
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);
}
}
}
101 changes: 101 additions & 0 deletions NeoFsStorageNode/Core/Object/Fmt.cs
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);


}
23 changes: 23 additions & 0 deletions NeoFsStorageNode/Core/Object/Tombstone.cs
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 NeoFsStorageNode/LocalObjectStorage/Bucket/DbBucket/DbBucket.cs
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 NeoFsStorageNode/LocalObjectStorage/Bucket/FsBucket/Bucket.cs
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);
}
}
}
Loading

0 comments on commit 2a19dfd

Please sign in to comment.