public ContainerID PutContainer(CancellationToken context, Container.Container container, CallOptions options = null)
        {
            var container_client = new ContainerService.ContainerServiceClient(channel);
            var opts             = DefaultCallOptions.ApplyCustomOptions(options);

            container.Version = Refs.Version.SDKVersion();
            if (container.OwnerId is null)
            {
                container.OwnerId = key.ToOwnerID();
            }
            var req = new PutRequest
            {
                Body = new PutRequest.Types.Body
                {
                    Container = container,
                    Signature = container.SignMessagePart(key),
                }
            };

            req.MetaHeader = opts.GetRequestMetaHeader();
            req.SignRequest(key);
            var resp = container_client.Put(req, cancellationToken: context);

            if (!resp.VerifyResponse())
            {
                throw new InvalidOperationException("invalid container put response");
            }
            return(resp.Body.ContainerId);
        }
Пример #2
0
        public async Task AnnounceIntermediateTrust(ulong epoch, uint iter, PeerToPeerTrust trust, CallOptions options = null, CancellationToken context = default)
        {
            var opts = DefaultCallOptions.ApplyCustomOptions(options);

            CheckOptions(opts);
            if (trust is null)
            {
                throw new ArgumentNullException(nameof(trust));
            }
            var req = new AnnounceIntermediateResultRequest
            {
                Body = new AnnounceIntermediateResultRequest.Types.Body
                {
                    Epoch     = epoch,
                    Iteration = iter,
                    Trust     = trust,
                }
            };

            req.MetaHeader = opts.GetRequestMetaHeader();
            opts.Key.Sign(req);
            var resp = await ReputationClient.AnnounceIntermediateResultAsync(req, cancellationToken : context);

            if (!resp.Verify())
            {
                throw new FormatException("invalid announce intermediate trust response");
            }
            CheckStatus(resp);
        }
Пример #3
0
        public async Task <ContainerID> PutContainer(Container.Container container, CallOptions options = null, CancellationToken context = default)
        {
            if (container is null)
            {
                throw new ArgumentNullException(nameof(container));
            }
            var opts = DefaultCallOptions.ApplyCustomOptions(options);

            CheckOptions(opts);
            container.Version = Refs.Version.SDKVersion();
            if (container.OwnerId is null)
            {
                container.OwnerId = OwnerID.FromScriptHash(opts.Key.PublicKey().PublicKeyToScriptHash());
            }
            var req = new PutRequest
            {
                Body = new PutRequest.Types.Body
                {
                    Container = container,
                    Signature = opts.Key.SignRFC6979(container),
                }
            };

            req.MetaHeader = opts.GetRequestMetaHeader();
            opts.Key.Sign(req);

            return(await PutContainer(req, opts.Deadline, context));
        }
Пример #4
0
        public async Task DeleteContainer(ContainerID cid, CallOptions options = null, CancellationToken context = default)
        {
            if (cid is null)
            {
                throw new ArgumentNullException(nameof(cid));
            }
            var opts = DefaultCallOptions.ApplyCustomOptions(options);

            CheckOptions(opts);
            var body = new DeleteRequest.Types.Body
            {
                ContainerId = cid,
            };
            var req = new DeleteRequest();

            body.Signature = new()
            {
                Key  = ByteString.CopyFrom(key.PublicKey()),
                Sign = ByteString.CopyFrom(opts.Key.SignRFC6979(cid.Value.ToByteArray())),
            };
            req.Body       = body;
            req.MetaHeader = opts.GetRequestMetaHeader();
            opts.Key.Sign(req);

            await DeleteContainer(req, opts.Deadline, context);
        }
Пример #5
0
        public async Task AnnounceTrust(ulong epoch, List <Trust> trusts, CallOptions options = null, CancellationToken context = default)
        {
            var opts = DefaultCallOptions.ApplyCustomOptions(options);

            CheckOptions(opts);
            if (trusts is null)
            {
                throw new ArgumentNullException(nameof(trusts));
            }
            var req = new AnnounceLocalTrustRequest
            {
                Body = new AnnounceLocalTrustRequest.Types.Body
                {
                    Epoch = epoch,
                }
            };

            req.Body.Trusts.AddRange(trusts);
            req.MetaHeader = opts.GetRequestMetaHeader();
            opts.Key.Sign(req);
            var resp = await ReputationClient.AnnounceLocalTrustAsync(req, cancellationToken : context);

            if (!resp.Verify())
            {
                throw new FormatException("invalid announce trust response");
            }
            CheckStatus(resp);
        }
        public EAclWithSignature GetEAclWithSignature(CancellationToken context, ContainerID cid, CallOptions options = null)
        {
            var container_client = new ContainerService.ContainerServiceClient(channel);
            var opts             = DefaultCallOptions.ApplyCustomOptions(options);
            var req = new GetExtendedACLRequest
            {
                Body = new GetExtendedACLRequest.Types.Body
                {
                    ContainerId = cid
                }
            };

            req.MetaHeader = opts.GetRequestMetaHeader();
            req.SignRequest(key);

            var resp = container_client.GetExtendedACL(req, cancellationToken: context);

            if (!resp.VerifyResponse())
            {
                throw new InvalidOperationException("invalid container put response");
            }
            var eacl = resp.Body.Eacl;
            var sig  = resp.Body.Signature;

            if (!eacl.VerifyMessagePart(sig))
            {
                throw new InvalidOperationException("invalid eacl");
            }
            return(new EAclWithSignature
            {
                Table = eacl,
                Signature = sig,
            });
        }
Пример #7
0
        public async Task <ObjectID> PutObject(Header header, Stream reader, CallOptions options = null, CancellationToken context = default)
        {
            if (header is null)
            {
                throw new ArgumentNullException(nameof(header));
            }
            var opts = DefaultCallOptions.ApplyCustomOptions(options);

            CheckOptions(opts);
            var req = new PutRequest
            {
                Body = new()
            };
            var meta = opts.GetRequestMetaHeader();

            req.MetaHeader = meta;
            var init = new PutRequest.Types.Body.Types.Init
            {
                Header = header,
            };

            req.Body.Init = init;
            opts.Key.Sign(req);

            using var stream = await PutObject(req, context : context);

            var block = new byte[Object.Object.ChunkSize];
            var count = reader.Read(block, 0, Object.Object.ChunkSize);

            while (count > 0)
            {
                var chunk_body = new PutRequest.Types.Body
                {
                    Chunk = ByteString.CopyFrom(block[..count]),
Пример #8
0
        public async Task <Object.Object> GetObject(Address address, bool raw = false, CallOptions options = null, CancellationToken context = default)
        {
            if (address is null)
            {
                throw new ArgumentNullException(nameof(address));
            }
            var opts = DefaultCallOptions.ApplyCustomOptions(options);

            CheckOptions(opts);
            var req = new GetRequest
            {
                Body = new GetRequest.Types.Body
                {
                    Raw     = raw,
                    Address = address,
                }
            };
            var meta = opts.GetRequestMetaHeader();

            AttachObjectSessionToken(opts, meta, address, ObjectSessionContext.Types.Verb.Get);
            req.MetaHeader = meta;
            opts.Key.Sign(req);

            return(await GetObject(req, opts.Deadline, context));
        }
Пример #9
0
        public async Task <ulong> Epoch(CallOptions options = null, CancellationToken context = default)
        {
            var opts = DefaultCallOptions.ApplyCustomOptions(options);

            CheckOptions(opts);
            var req = new LocalNodeInfoRequest
            {
                Body = new LocalNodeInfoRequest.Types.Body {
                }
            };

            req.MetaHeader = opts.GetRequestMetaHeader();
            opts.Key.Sign(req);

            return(await Epoch(req, opts.Deadline, context));
        }
Пример #10
0
        public async Task <SessionToken> CreateSession(ulong expiration, CallOptions options = null, CancellationToken context = default)
        {
            var opts = DefaultCallOptions.ApplyCustomOptions(options);

            CheckOptions(opts);
            var req = new CreateRequest
            {
                Body = new CreateRequest.Types.Body
                {
                    OwnerId    = OwnerID.FromScriptHash(opts.Key.PublicKey().PublicKeyToScriptHash()),
                    Expiration = expiration,
                }
            };

            req.MetaHeader = opts?.GetRequestMetaHeader() ?? RequestMetaHeader.Default;
            opts.Key.Sign(req);

            return(await CreateSession(req, opts.Deadline, context));
        }
Пример #11
0
        public NodeInfo LocalNodeInfo(CancellationToken context, CallOptions options = null)
        {
            var netmap_client = new NetmapService.NetmapServiceClient(channel);
            var opts          = DefaultCallOptions.ApplyCustomOptions(options);
            var req           = new LocalNodeInfoRequest
            {
                Body = new LocalNodeInfoRequest.Types.Body {
                }
            };

            req.MetaHeader = opts.GetRequestMetaHeader();
            req.SignRequest(key);
            var resp = netmap_client.LocalNodeInfo(req, cancellationToken: context);

            if (!resp.VerifyResponse())
            {
                throw new FormatException(nameof(LocalNodeInfo) + " invalid LocalNodeInfo response");
            }
            return(resp.Body.NodeInfo);
        }
Пример #12
0
        public async Task <Accounting.Decimal> GetBalance(OwnerID owner = null, CallOptions options = null, CancellationToken context = default)
        {
            var opts = DefaultCallOptions.ApplyCustomOptions(options);

            CheckOptions(opts);
            if (owner is null)
            {
                owner = OwnerID.FromScriptHash(opts.Key.PublicKey().PublicKeyToScriptHash());
            }
            var req = new BalanceRequest
            {
                Body = new BalanceRequest.Types.Body
                {
                    OwnerId = owner,
                }
            };

            req.MetaHeader = opts.GetRequestMetaHeader();
            opts.Key.Sign(req);
            return(await GetBalance(req, opts.Deadline, context));
        }
Пример #13
0
        public void AnnounceContainerUsedSpace(CancellationToken context, List <UsedSpaceAnnouncement> announcements, CallOptions options = null)
        {
            var container_client = new ContainerService.ContainerServiceClient(channel);
            var opts             = DefaultCallOptions.ApplyCustomOptions(options);
            var body             = new AnnounceUsedSpaceRequest.Types.Body();

            body.Announcements.AddRange(announcements);
            var req = new AnnounceUsedSpaceRequest
            {
                Body = body,
            };

            req.MetaHeader = opts.GetRequestMetaHeader();
            req.SignRequest(key);

            var resp = container_client.AnnounceUsedSpace(req, cancellationToken: context);

            if (!resp.VerifyResponse())
            {
                throw new InvalidOperationException("invalid announce used space response");
            }
        }
Пример #14
0
        public async Task <ObjectID> PutObject(CancellationToken context, PutObjectParams param, CallOptions options = null)
        {
            var object_client = new ObjectService.ObjectServiceClient(channel);
            var obj           = param.Object;
            var call          = object_client.Put(cancellationToken: context);
            var opts          = DefaultCallOptions.ApplyCustomOptions(options);
            var req_stream    = call.RequestStream;

            var req  = new PutRequest();
            var body = new PutRequest.Types.Body();

            req.Body = body;
            var address = new Address
            {
                ContainerId = obj.Header.ContainerId,
                ObjectId    = obj.ObjectId,
            };
            var meta = opts.GetRequestMetaHeader();

            AttachObjectSessionToken(opts, meta, address, ObjectSessionContext.Types.Verb.Put);
            req.MetaHeader = meta;
            var init = new PutRequest.Types.Body.Types.Init
            {
                ObjectId  = obj.ObjectId,
                Signature = obj.Signature,
                Header    = obj.Header,
            };

            req.Body.Init = init;
            req.SignRequest(key);

            await req_stream.WriteAsync(req);

            int offset = 0;

            while (offset < obj.Payload.Length)
            {
                var end        = offset + Object.Object.ChunkSize > obj.Payload.Length ? obj.Payload.Length : offset + Object.Object.ChunkSize;
                var chunk      = ByteString.CopyFrom(obj.Payload.ToByteArray()[offset..end]);
Пример #15
0
        public async Task AnnounceContainerUsedSpace(List <UsedSpaceAnnouncement> announcements, CallOptions options = null, CancellationToken context = default)
        {
            if (announcements is null)
            {
                throw new ArgumentNullException(nameof(announcements));
            }
            var opts = DefaultCallOptions.ApplyCustomOptions(options);

            CheckOptions(opts);
            var body = new AnnounceUsedSpaceRequest.Types.Body();

            body.Announcements.AddRange(announcements);
            var req = new AnnounceUsedSpaceRequest
            {
                Body = body,
            };

            req.MetaHeader = opts.GetRequestMetaHeader();
            opts.Key.Sign(req);

            await AnnounceContainerUsedSpace(req, opts.Deadline, context);
        }
Пример #16
0
        public async Task <EAclWithSignature> GetEAcl(ContainerID cid, CallOptions options = null, CancellationToken context = default)
        {
            if (cid is null)
            {
                throw new ArgumentNullException(nameof(cid));
            }
            var opts = DefaultCallOptions.ApplyCustomOptions(options);

            CheckOptions(opts);
            var req = new GetExtendedACLRequest
            {
                Body = new GetExtendedACLRequest.Types.Body
                {
                    ContainerId = cid
                }
            };

            req.MetaHeader = opts.GetRequestMetaHeader();
            opts.Key.Sign(req);

            return(await GetEAcl(req, opts.Deadline, context));
        }
Пример #17
0
        public Accounting.Decimal GetBalance(OwnerID owner, CallOptions options = null)
        {
            var account_client = new AccountingService.AccountingServiceClient(channel);
            var opts           = DefaultCallOptions.ApplyCustomOptions(options);
            var req            = new BalanceRequest
            {
                Body = new BalanceRequest.Types.Body
                {
                    OwnerId = owner,
                }
            };

            req.MetaHeader = opts.GetRequestMetaHeader();
            req.SignRequest(key);
            var resp = account_client.Balance(req);

            if (!resp.VerifyResponse())
            {
                throw new FormatException("invalid balance response");
            }
            return(resp.Body.Balance);
        }
Пример #18
0
        public async Task <NetworkInfo> NetworkInfo(CallOptions options = null, CancellationToken context = default)
        {
            var opts = DefaultCallOptions.ApplyCustomOptions(options);

            CheckOptions(opts);
            var req = new NetworkInfoRequest
            {
                Body = new NetworkInfoRequest.Types.Body {
                }
            };

            req.MetaHeader = opts.GetRequestMetaHeader();
            opts.Key.Sign(req);
            var resp = await NetmapClient.NetworkInfoAsync(req, cancellationToken : context);

            if (!resp.Verify())
            {
                throw new FormatException(nameof(LocalNodeInfo) + " invalid LocalNodeInfo response");
            }
            CheckStatus(resp);
            return(resp.Body.NetworkInfo);
        }
Пример #19
0
        public void DeleteContainer(CancellationToken context, ContainerID cid, CallOptions options = null)
        {
            var container_client = new ContainerService.ContainerServiceClient(channel);
            var opts             = DefaultCallOptions.ApplyCustomOptions(options);
            var req = new DeleteRequest
            {
                Body = new DeleteRequest.Types.Body
                {
                    ContainerId = cid,
                }
            };

            req.Body.Signature = req.Body.SignMessagePart(key);
            req.MetaHeader     = opts.GetRequestMetaHeader();
            req.SignRequest(key);

            var resp = container_client.Delete(req, cancellationToken: context);

            if (!resp.VerifyResponse())
            {
                throw new InvalidOperationException("invalid container put response");
            }
        }
Пример #20
0
        public Container.Container GetContainer(CancellationToken context, ContainerID cid, CallOptions options = null)
        {
            var container_client = new ContainerService.ContainerServiceClient(channel);
            var opts             = DefaultCallOptions.ApplyCustomOptions(options);
            var req = new GetRequest
            {
                Body = new GetRequest.Types.Body
                {
                    ContainerId = cid
                }
            };

            req.MetaHeader = opts.GetRequestMetaHeader();
            req.SignRequest(key);

            var resp = container_client.Get(req, cancellationToken: context);

            if (!resp.VerifyResponse())
            {
                throw new InvalidOperationException("invalid container get response");
            }
            return(resp.Body.Container);
        }
Пример #21
0
        public void SetEACL(CancellationToken context, EACLTable eacl, CallOptions options = null)
        {
            var container_client = new ContainerService.ContainerServiceClient(channel);
            var opts             = DefaultCallOptions.ApplyCustomOptions(options);
            var req = new SetExtendedACLRequest
            {
                Body = new SetExtendedACLRequest.Types.Body
                {
                    Eacl      = eacl,
                    Signature = eacl.SignMessagePart(key),
                }
            };

            req.MetaHeader = opts.GetRequestMetaHeader();
            req.SignRequest(key);

            var resp = container_client.SetExtendedACL(req, cancellationToken: context);

            if (!resp.VerifyResponse())
            {
                throw new InvalidOperationException("invalid container put response");
            }
        }
Пример #22
0
        public List <ContainerID> ListContainers(CancellationToken context, OwnerID owner, CallOptions options = null)
        {
            var container_client = new ContainerService.ContainerServiceClient(channel);
            var opts             = DefaultCallOptions.ApplyCustomOptions(options);
            var req = new ListRequest
            {
                Body = new ListRequest.Types.Body
                {
                    OwnerId = owner
                }
            };

            req.MetaHeader = opts.GetRequestMetaHeader();
            req.SignRequest(key);

            var resp = container_client.List(req, cancellationToken: context);

            if (!resp.VerifyResponse())
            {
                throw new InvalidOperationException("invalid container put response");
            }
            return(resp.Body.ContainerIds.ToList());
        }
Пример #23
0
        public async Task SetEACL(EACLTable eacl, CallOptions options = null, CancellationToken context = default)
        {
            if (eacl is null)
            {
                throw new ArgumentNullException(nameof(eacl));
            }
            var opts = DefaultCallOptions.ApplyCustomOptions(options);

            CheckOptions(opts);
            eacl.Version = Refs.Version.SDKVersion();
            var req = new SetExtendedACLRequest
            {
                Body = new SetExtendedACLRequest.Types.Body
                {
                    Eacl      = eacl,
                    Signature = opts.Key.SignRFC6979(eacl),
                }
            };

            req.MetaHeader = opts.GetRequestMetaHeader();
            opts.Key.Sign(req);

            await SetEACL(req, opts.Deadline, context);
        }
Пример #24
0
        public async Task <Object.Object> GetObject(Address address, Stream writer, bool raw = false, CallOptions options = null, CancellationToken context = default)
        {
            if (address is null)
            {
                throw new ArgumentNullException(nameof(address));
            }
            var opts = DefaultCallOptions.ApplyCustomOptions(options);

            CheckOptions(opts);
            var req = new GetRequest
            {
                Body = new GetRequest.Types.Body
                {
                    Raw     = raw,
                    Address = address,
                }
            };
            var meta = opts.GetRequestMetaHeader();

            AttachObjectSessionToken(opts, meta, address, ObjectSessionContext.Types.Verb.Get);
            req.MetaHeader = meta;
            opts.Key.Sign(req);
            using var call = ObjectClient.Get(req, cancellationToken: context);
            var obj    = new Object.Object();
            int offset = 0;

            while (await call.ResponseStream.MoveNext())
            {
                var resp = call.ResponseStream.Current;
                if (!resp.Verify())
                {
                    throw new InvalidOperationException("invalid object get response");
                }
                CheckStatus(resp);
                switch (resp.Body.ObjectPartCase)
                {
                case GetResponse.Types.Body.ObjectPartOneofCase.Init:
                {
                    obj.ObjectId  = resp.Body.Init.ObjectId;
                    obj.Signature = resp.Body.Init.Signature;
                    obj.Header    = resp.Body.Init.Header;
                    break;
                }

                case GetResponse.Types.Body.ObjectPartOneofCase.Chunk:
                {
                    if (obj.Header is null)
                    {
                        throw new InvalidOperationException("missing init");
                    }
                    var chunk = resp.Body.Chunk.ToByteArray();
                    if (obj.PayloadSize < (ulong)(offset + chunk.Length))
                    {
                        throw new InvalidOperationException("data exceeds PayloadSize");
                    }
                    writer.Write(chunk, 0, chunk.Length);
                    offset += chunk.Length;
                    break;
                }

                case GetResponse.Types.Body.ObjectPartOneofCase.SplitInfo:
                {
                    throw new SplitInfoException(resp.Body.SplitInfo);
                }

                default:
                    throw new FormatException("malformed object get reponse");
                }
            }
            if ((ulong)offset < obj.PayloadSize)
            {
                throw new InvalidOperationException("data is less than PayloadSize");
            }
            return(obj);
        }
Пример #25
0
        public async Task <Object.Object> GetObject(CancellationToken context, GetObjectParams param, CallOptions options = null)
        {
            var object_client  = new ObjectService.ObjectServiceClient(channel);
            var object_address = param.Address;
            var opts           = DefaultCallOptions.ApplyCustomOptions(options);
            var req            = new GetRequest
            {
                Body = new GetRequest.Types.Body
                {
                    Raw     = param.Raw,
                    Address = object_address,
                }
            };
            var meta = opts.GetRequestMetaHeader();

            AttachObjectSessionToken(opts, meta, object_address, ObjectSessionContext.Types.Verb.Get);
            req.MetaHeader = meta;
            req.SignRequest(key);

            var stream  = object_client.Get(req, cancellationToken: context).ResponseStream;
            var obj     = new Object.Object();
            var payload = new byte[] { };
            int offset  = 0;

            while (await stream.MoveNext())
            {
                var resp = stream.Current;
                if (!resp.VerifyResponse())
                {
                    throw new InvalidOperationException("invalid object get response");
                }
                switch (resp.Body.ObjectPartCase)
                {
                case GetResponse.Types.Body.ObjectPartOneofCase.Init:
                {
                    obj.ObjectId  = resp.Body.Init.ObjectId;
                    obj.Signature = resp.Body.Init.Signature;
                    obj.Header    = resp.Body.Init.Header;
                    payload       = new byte[obj.Header.PayloadLength];
                    break;
                }

                case GetResponse.Types.Body.ObjectPartOneofCase.Chunk:
                {
                    resp.Body.Chunk.CopyTo(payload, offset);
                    offset += resp.Body.Chunk.Length;
                    break;
                }

                case GetResponse.Types.Body.ObjectPartOneofCase.SplitInfo:
                {
                    throw new SplitInfoException(resp.Body.SplitInfo);
                }

                default:
                    throw new FormatException("malformed object get reponse");
                }
            }
            obj.Payload = ByteString.CopyFrom(payload);
            return(obj);
        }