Beispiel #1
0
 public BlockRepositoryApi(IPinApi pinApi, IBlockApi blockApi, IMigrationManager migrationManager, RepositoryOptions repositoryOptions)
 {
     _pinApi            = pinApi;
     _blockApi          = blockApi;
     _migrationManager  = migrationManager;
     _repositoryOptions = repositoryOptions;
 }
Beispiel #2
0
        static async Task <Stream> CreateDagProtoBufStreamAsync(
            Cid id,
            IBlockApi blockService,
            KeyChain keyChain,
            CancellationToken cancel)
        {
            var block = await blockService.GetAsync(id, cancel).ConfigureAwait(false);

            var dag = new DagNode(block.DataStream);
            var dm  = Serializer.Deserialize <DataMessage>(dag.DataStream);

            if (dm.Type != DataType.File)
            {
                throw new Exception($"'{id.Encode()}' is not a file.");
            }

            if (dm.Fanout.HasValue)
            {
                throw new NotImplementedException("files with a fanout");
            }

            // Is it a simple node?
            if (dm.BlockSizes == null && !dm.Fanout.HasValue)
            {
                return(new MemoryStream(buffer: dm.Data ?? emptyData, writable: false));
            }

            if (dm.BlockSizes != null)
            {
                return(new ChunkedStream(blockService, keyChain, dag));
            }

            throw new Exception($"Cannot determine the file format of '{id}'.");
        }
Beispiel #3
0
        private static async Task <Stream> CreateRawStreamAsync(Cid id,
                                                                IBlockApi blockService,
                                                                CancellationToken cancel)
        {
            var block = await blockService.GetAsync(id, cancel).ConfigureAwait(false);

            return(block.DataStream);
        }
Beispiel #4
0
 public UnixFsApi(IDhtApi dhtApi, IBlockApi blockApi, IKeyApi keyApi, INameApi nameApi, DfsState dfsState)
 {
     _dhtApi   = dhtApi;
     _blockApi = blockApi;
     _keyApi   = keyApi;
     _nameApi  = nameApi;
     _dfsState = dfsState;
 }
Beispiel #5
0
        public DfsService(IBitSwapApi bitSwapApi,
                          BitSwapService bitSwapService,
                          IBlockApi blockApi,
                          IBlockRepositoryApi blockRepositoryApi,
                          IBootstrapApi bootstrapApi,
                          IConfigApi configApi,
                          IDagApi dagApi,
                          IDhtApi dhtApi,
                          IDnsApi dnsApi,
                          KatDhtService dhtService,
                          IUnixFsApi unixFsApi,
                          IKeyApi keyApi,
                          INameApi nameApi,
                          IObjectApi objectApi,
                          IPinApi pinApi,
                          Ping1 pingService,
                          IPubSubApi pubSubApi,
                          PubSubService pubSubService,
                          IStatsApi statsApi,
                          ISwarmApi swarmApi,
                          SwarmService swarmService,
                          DfsOptions dfsOptions,
                          IHashProvider hashProvider,
                          DfsState dfsState,
                          IPasswordManager passwordManager,
                          IMigrationManager migrationManager,
                          Peer localPeer)
        {
            BitSwapApi         = bitSwapApi;
            BitSwapService     = bitSwapService;
            BlockApi           = blockApi;
            BlockRepositoryApi = blockRepositoryApi;
            BootstrapApi       = bootstrapApi;
            ConfigApi          = configApi;
            DagApi             = dagApi;
            DhtApi             = dhtApi;
            DhtService         = dhtService;
            UnixFsApi          = unixFsApi;
            KeyApi             = keyApi;
            NameApi            = nameApi;
            ObjectApi          = objectApi;
            PinApi             = pinApi;
            PingService        = pingService;
            PubSubApi          = pubSubApi;
            PubSubService      = pubSubService;
            StatsApi           = statsApi;
            SwarmApi           = swarmApi;
            SwarmService       = swarmService;
            Options            = dfsOptions;
            _hashProvider      = hashProvider;
            _dfsState          = dfsState;
            DnsApi             = dnsApi;
            MigrationManager   = migrationManager;
            LocalPeer          = localPeer;

            InitAsync().Wait();
        }
Beispiel #6
0
        static async Task <Stream> CreateRawStreamAsync(
            Cid id,
            IBlockApi blockService,
            KeyChain keyChain,
            CancellationToken cancel)
        {
            var block = await blockService.GetAsync(id, cancel);

            return(block.DataStream);
        }
Beispiel #7
0
        private static async Task <Stream> CreateCmsStreamAsync(Cid id,
                                                                IBlockApi blockService,
                                                                IKeyApi keyChain,
                                                                CancellationToken cancel)
        {
            var block = await blockService.GetAsync(id, cancel).ConfigureAwait(false);

            var plain = await keyChain.ReadProtectedDataAsync(block.DataBytes, cancel).ConfigureAwait(false);

            return(new MemoryStream(plain, false));
        }
        /// <summary>
        ///   Creates a new instance of the <see cref="ChunkedStream"/> class with
        ///   the specified <see cref="IBlockApi"/> and <see cref="DagNode"/>.
        /// </summary>
        /// <param name="blockService"></param>
        /// <param name="keyChain"></param>
        /// <param name="dag"></param>
        public ChunkedStream(IBlockApi blockService, KeyChain keyChain, DagNode dag)
        {
            BlockService = blockService;
            KeyChain     = keyChain;
            var links = dag.Links.ToArray();
            var dm    = Serializer.Deserialize <DataMessage>(dag.DataStream);

            fileSize = (long)dm.FileSize;
            ulong position = 0;

            for (int i = 0; i < dm.BlockSizes.Length; ++i)
            {
                blocks.Add(new BlockInfo
                {
                    Id       = links[i].Id,
                    Position = (long)position
                });
                position += dm.BlockSizes[i];
            }
        }
Beispiel #9
0
        /// <summary>
        ///   Creates a stream that can read the supplied <see cref="Cid"/>.
        /// </summary>
        /// <param name="id">
        ///   The identifier of some content.
        /// </param>
        /// <param name="blockService">
        ///   The source of the cid's data.
        /// </param>
        /// <param name="keyChain">
        ///   Used to decypt the protected data blocks.
        /// </param>
        /// <param name="cancel">
        ///   Is used to stop the task.  When cancelled, the <see cref="TaskCanceledException"/> is raised.
        /// </param>
        /// <returns>
        ///   A task that represents the asynchronous operation. The task's value is
        ///   a <see cref="Stream"/> that produces the content of the <paramref name="id"/>.
        /// </returns>
        /// <remarks>
        ///  The id's <see cref="Cid.ContentType"/> is used to determine how to read
        ///  the conent.
        /// </remarks>
        public static Task <Stream> CreateReadStreamAsync(Cid id,
                                                          IBlockApi blockService,
                                                          IKeyApi keyChain,
                                                          CancellationToken cancel)
        {
            switch (id.ContentType)
            {
            // TODO: A content-type registry should be used.
            case "dag-pb":
                return(CreateDagProtoBufStreamAsync(id, blockService, keyChain, cancel));

            case "raw":
                return(CreateRawStreamAsync(id, blockService, cancel));

            case "cms":
                return(CreateCmsStreamAsync(id, blockService, keyChain, cancel));

            default:
                throw new NotSupportedException($"Cannot read content type '{id.ContentType}'.");
            }
        }
Beispiel #10
0
 /// <summary>
 ///   Creates a stream that can read the supplied <see cref="Cid"/>.
 /// </summary>
 /// <param name="id">
 ///   The identifier of some content.
 /// </param>
 /// <param name="blockService">
 ///   The source of the cid's data.
 /// </param>
 /// <param name="keyChain">
 ///   Used to decypt the protected data blocks.
 /// </param>
 /// <param name="cancel">
 ///   Is used to stop the task.  When cancelled, the <see cref="TaskCanceledException"/> is raised.
 /// </param>
 /// <returns>
 ///   A task that represents the asynchronous operation. The task's value is
 ///   a <see cref="Stream"/> that produces the content of the <paramref name="id"/>.
 /// </returns>
 /// <remarks>
 ///  The id's <see cref="Cid.ContentType"/> is used to determine how to read
 ///  the conent.
 /// </remarks>
 public static Task <Stream> CreateReadStream(
     Cid id,
     IBlockApi blockService,
     KeyChain keyChain,
     CancellationToken cancel)
 {
     // TODO: A content-type registry should be used.
     if (id.ContentType == "dag-pb")
     {
         return(CreateDagProtoBufStreamAsync(id, blockService, keyChain, cancel));
     }
     else if (id.ContentType == "raw")
     {
         return(CreateRawStreamAsync(id, blockService, keyChain, cancel));
     }
     else if (id.ContentType == "cms")
     {
         return(CreateCmsStreamAsync(id, blockService, keyChain, cancel));
     }
     else
     {
         throw new NotSupportedException($"Cannot read content type '{id.ContentType}'.");
     }
 }
Beispiel #11
0
        /// <summary>
        ///     Creates a new instance of the <see cref="ChunkedStream" /> class with
        ///     the specified <see cref="IBlockApi" /> and <see cref="DagNode" />.
        /// </summary>
        /// <param name="blockService"></param>
        /// <param name="keyChain"></param>
        /// <param name="dag"></param>
        internal ChunkedStream(IBlockApi blockService, IKeyApi keyChain, IDagNode dag)
        {
            BlockService = blockService;
            KeyChain     = keyChain;
            var links = dag.Links.ToArray();
            var dm    = Serializer.Deserialize <DataMessage>(dag.DataStream);

            if (dm.FileSize != null)
            {
                Length = (long)dm.FileSize;
            }

            ulong position = 0;

            for (var i = 0; i < dm.BlockSizes.Length; ++i)
            {
                blocks.Add(new BlockInfo
                {
                    Id       = links[i].Id,
                    Position = (long)position
                });
                position += dm.BlockSizes[i];
            }
        }
Beispiel #12
0
        /// <summary>
        ///     Performs the chunking.
        /// </summary>
        /// <param name="stream">
        ///     The data source.
        /// </param>
        /// <param name="name">
        ///     A name for the data.
        /// </param>
        /// <param name="options">
        ///     The options when adding data to the IPFS file system.
        /// </param>
        /// <param name="blockService">
        ///     The destination for the chunked data block(s).
        /// </param>
        /// <param name="keyChain">
        ///     Used to protect the chunked data blocks(s).
        /// </param>
        /// <param name="cancel">
        ///     Is used to stop the task.  When cancelled, the <see cref="TaskCanceledException" /> is raised.
        /// </param>
        /// <returns>
        ///     A task that represents the asynchronous operation. The task's value is
        ///     the sequence of file system nodes of the added data blocks.
        /// </returns>
        public async Task <List <UnixFsNode> > ChunkAsync(Stream stream,
                                                          string name,
                                                          AddFileOptions options,
                                                          IBlockApi blockService,
                                                          IKeyApi keyChain,
                                                          CancellationToken cancel)
        {
            var protecting = !string.IsNullOrWhiteSpace(options.ProtectionKey);
            var nodes      = new List <UnixFsNode>();
            var chunkSize  = options.ChunkSize;
            var chunk      = new byte[chunkSize];
            var chunking   = true;
            var totalBytes = 0UL;

            while (chunking)
            {
                // Get an entire chunk.
                var length = 0;
                while (length < chunkSize)
                {
                    var n = await stream.ReadAsync(chunk, length, chunkSize - length, cancel).ConfigureAwait(false);

                    if (n < 1)
                    {
                        chunking = false;
                        break;
                    }

                    length     += n;
                    totalBytes += (uint)n;
                }

                //  Only generate empty block, when the stream is empty.
                if (length != 0 || nodes.Count <= 0)
                {
                    options.Progress?.Report(new TransferProgress
                    {
                        Name  = name,
                        Bytes = totalBytes
                    });

                    // if protected data, then get CMS structure.
                    if (protecting)
                    {
                        // TODO: Inefficent to copy chunk, use ArraySegment in DataMessage.Data
                        var plain = new byte[length];
                        Array.Copy(chunk, plain, length);
                        var cipher = await keyChain.CreateProtectedDataAsync(options.ProtectionKey, plain, cancel)
                                     .ConfigureAwait(false);

                        var cid = await blockService.PutAsync(
                            cipher,
                            "cms",
                            options.Hash,
                            options.Encoding,
                            options.Pin,
                            cancel).ConfigureAwait(false);

                        nodes.Add(new UnixFsNode
                        {
                            Id      = cid,
                            Size    = length,
                            DagSize = cipher.Length,
                            Links   = UnixFsLink.None
                        });
                    }
                    else if (options.RawLeaves)
                    {
                        // TODO: Inefficent to copy chunk, use ArraySegment in DataMessage.Data
                        var data = new byte[length];
                        Array.Copy(chunk, data, length);
                        var cid = await blockService.PutAsync(
                            data,
                            "raw",
                            options.Hash,
                            options.Encoding,
                            options.Pin,
                            cancel).ConfigureAwait(false);

                        nodes.Add(new UnixFsNode
                        {
                            Id      = cid,
                            Size    = length,
                            DagSize = length,
                            Links   = UnixFsLink.None
                        });
                    }
                    else
                    {
                        // Build the DAG.
                        var dm = new DataMessage
                        {
                            Type     = DataType.File,
                            FileSize = (ulong)length
                        };
                        if (length > 0)
                        {
                            // TODO: Inefficent to copy chunk, use ArraySegment in DataMessage.Data
                            var data = new byte[length];
                            Array.Copy(chunk, data, length);
                            dm.Data = data;
                        }

                        var pb = new MemoryStream();
                        Serializer.Serialize(pb, dm);
                        var dag = new DagNode(pb.ToArray(), null, options.Hash);

                        // Save it.
                        dag.Id = await blockService.PutAsync(
                            dag.ToArray(),
                            multiHash : options.Hash,
                            encoding : options.Encoding,
                            pin : options.Pin,
                            cancel : cancel).ConfigureAwait(false);

                        var node = new UnixFsNode
                        {
                            Id      = dag.Id,
                            Size    = length,
                            DagSize = dag.Size,
                            Links   = UnixFsLink.None
                        };
                        nodes.Add(node);
                    }
                }
            }

            return(nodes);
        }
Beispiel #13
0
 public DagApi(IBlockApi blockApi)
 {
     _blockApi = blockApi;
 }
Beispiel #14
0
 public ObjectApi(IBlockApi blockApi)
 {
     _blockApi = blockApi;
 }