{"action":"created","comment":{"url":"https://api.github.com/repos/stratisproject/StratisBitcoinFullNode/pulls/comments/222261174","pull_request_review_id":161101946,"id":222261174,"node_id":"MDI0OlB1bGxSZXF1ZXN0UmV2aWV3Q29tbWVudDIyMjI2MTE3NA==","diff_hunk":"@@ -0,0 +1,374 @@\n+﻿using System;\n+using System.Collections.Concurrent;\n+using System.Collections.Generic;\n+using System.Linq;\n+using System.Text;\n+using System.Threading.Tasks;\n+using Microsoft.Extensions.Logging;\n+using NBitcoin;\n+using Stratis.Bitcoin.Base;\n+using Stratis.Bitcoin.Features.Consensus.CoinViews;\n+using Stratis.Bitcoin.Utilities;\n+\n+namespace Stratis.Bitcoin.Features.Consensus.ProvenBlockHeaders\n+{\n+    public class ProvenBlockHeaderStore : IProvenBlockHeaderStore, IDisposable\n+    {\n+        /// <summary>Instance logger.</summary>\n+        private readonly ILogger logger;\n+\n+        /// <summary>Allows consumers to perform clean-up during a graceful shutdown.</summary>\n+        private readonly INodeLifetime nodeLifetime;\n+\n+        /// <summary>Thread safe class representing a chain of headers from genesis.</summary>\n+        private readonly ConcurrentChain chain;\n+\n+        /// <summary>Database repository storing <see cref=\"ProvenBlockHeader\"></see>s.</summary>\n+        private readonly IProvenBlockHeaderRepository provenBlockHeaderRepository;\n+\n+        /// <summary>Lock object to protect access to <see cref=\"ProvenBlockHeader\"/>.</summary>\n+        private readonly AsyncLock lockobj;\n+\n+        /// <summary>Performance counter to measure performance of the save and query operation.</summary>\n+        private readonly BackendPerformanceCounter performanceCounter;\n+\n+        private BackendPerformanceSnapshot latestPerformanceSnapShot;\n+\n+        /// <summary>Current block tip hash and height that the <see cref= \"ProvenBlockHeader\"/> belongs to.</summary>\n+        public HashHeightPair CurrentTipHashHeight { get; private set; }\n+\n+        /// <summary>Pending - not yet saved to disk - block tip hash and height that the <see cref= \"ProvenBlockHeader\"/> belongs to.</summary>\n+        private HashHeightPair pendingTipHashHeight;\n+\n+        /// <summary>The async loop we wait upon.</summary>\n+        private IAsyncLoop asyncLoop;\n+\n+        /// <summary>Factory for creating background async loop tasks.</summary>\n+        private readonly IAsyncLoopFactory asyncLoopFactory;\n+\n+        /// <summary>Maximum number of items to cache.</summary>\n+        private const int CacheMaxItemsCount = 1_000;\n+\n+        /// <summary>Limit <see cref=\"Cache\"/> size to 100MB.</summary>\n+        private readonly int MaxMemoryCacheSizeInBytes = 100 * 1024 * 1024;\n+\n+        /// <summary>Cache of pending <see cref= \"ProvenBlockHeader\"/> items.</summary>\n+        /// <remarks>Pending <see cref= \"ProvenBlockHeader\"/> items will be saved to disk every minute.</remarks>\n+        public ConcurrentDictionary<int, ProvenBlockHeader> PendingCache { get; }\n+\n+        /// <summary>Store Cache of <see cref= \"ProvenBlockHeader\"/> items.</summary>\n+        /// <remarks>Items are added to this cache when the caller asks for a <see cref= \"ProvenBlockHeader\"/>.</remarks>\n+        public MemoryCache<int, ProvenBlockHeader> Cache { get; }\n+\n+        /// <summary>\n+        /// Initializes a new instance of the object.\n+        /// </summary>\n+        /// <param name=\"chain\">Thread safe class representing a chain of headers from genesis</param>\n+        /// <param name=\"dateTimeProvider\">Provider of time functions.</param>\n+        /// <param name=\"loggerFactory\">Factory to create a logger for this type.</param>\n+        /// <param name=\"provenBlockHeaderRepository\">Persistent interface of the <see cref=\"ProvenBlockHeader\"></see> DBreeze repository.</param>\n+        /// <param name=\"nodeLifetime\">Allows consumers to perform clean-up during a graceful shutdown.</param>\n+        /// <param name=\"nodeStats\">Registers an action used to append node stats when collected.</param>\n+        /// <param name=\"asyncLoopFactory\">Factory for creating and also possibly starting application defined tasks inside async loop.</param>\n+        public ProvenBlockHeaderStore(\n+            ConcurrentChain chain, \n+            IDateTimeProvider dateTimeProvider, \n+            ILoggerFactory loggerFactory, \n+            IProvenBlockHeaderRepository provenBlockHeaderRepository,\n+            INodeLifetime nodeLifetime,\n+            INodeStats nodeStats,\n+            IAsyncLoopFactory asyncLoopFactory)\n+        {\n+            Guard.NotNull(chain, nameof(chain));\n+            Guard.NotNull(loggerFactory, nameof(loggerFactory));\n+            Guard.NotNull(provenBlockHeaderRepository, nameof(provenBlockHeaderRepository));\n+            Guard.NotNull(nodeLifetime, nameof(nodeLifetime));\n+            Guard.NotNull(nodeStats, nameof(nodeStats));\n+            Guard.NotNull(asyncLoopFactory, nameof(asyncLoopFactory));\n+\n+            this.logger = loggerFactory.CreateLogger(this.GetType().FullName);\n+            this.chain = chain;\n+            this.provenBlockHeaderRepository = provenBlockHeaderRepository;\n+            this.nodeLifetime = nodeLifetime;\n+            this.lockobj = new AsyncLock();\n+\n+            this.PendingCache = new ConcurrentDictionary<int, ProvenBlockHeader>();\n+            this.Cache = new MemoryCache<int, ProvenBlockHeader>(CacheMaxItemsCount);\n+\n+            this.asyncLoopFactory = asyncLoopFactory;\n+\n+            this.performanceCounter = new BackendPerformanceCounter(dateTimeProvider);\n+            nodeStats.RegisterStats(this.AddBenchStats, StatsType.Benchmark, 400);\n+        }\n+\n+        /// <inheritdoc />\n+        public async Task InitializeAsync()\n+        {\n+            await this.provenBlockHeaderRepository.InitializeAsync().ConfigureAwait(false);\n+\n+            this.CurrentTipHashHeight = await this.CurrentTipHashHeightAsync().ConfigureAwait(false);\n+\n+            this.logger.LogDebug(\"Initialized ProvenBlockHader block tip at '{0}'.\", this.CurrentTipHashHeight);\n+\n+            this.asyncLoop = this.asyncLoopFactory.Run(\"ProvenBlockHeaders job\", token =>\n+            {\n+                this.logger.LogTrace(\"()\");\n+\n+                // Save pending items.\n+                this.SaveAsync().ConfigureAwait(false);\n+\n+                // Check and make sure the store cache limit isn't breached.\n+                this.ManangeCacheSize();\n+\n+                this.logger.LogTrace(\"(-)[IN_ASYNC_LOOP]\");\n+\n+                return Task.CompletedTask;\n+            },\n+            this.nodeLifetime.ApplicationStopping,\n+            repeatEvery: TimeSpan.FromMinutes(1),\n+            startAfter: TimeSpan.FromMinutes(1));\n+        }\n+\n+        /// <inheritdoc />\n+        public async Task<ProvenBlockHeader> GetAsync(int blockHeight)\n+        {\n+            ProvenBlockHeader header = null;\n+\n+            using (new StopwatchDisposable(o => this.performanceCounter.AddQueryTime(o)))\n+            {\n+                // Check pending cache first.\n+                header = this.GetHeaderFromPendingCache(blockHeight);\n+\n+                if (header == null)\n+                {\n+                    // Check store cache next.\n+                    header = this.GetHeaderFromStoreCache(blockHeight);\n+\n+                    if (header == null)\n+                    {\n+                        // Check the repository (DBreeze).\n+                        header = await this.provenBlockHeaderRepository.GetAsync(blockHeight).ConfigureAwait(false);\n+\n+                        // Add the item to the store cache.\n+                        this.Cache.AddOrUpdate(blockHeight, header);\n+                    }\n+                }\n+            }\n+\n+            if (header != null)\n+                this.logger.LogTrace(\"(-):*.{0}='{1}'\", nameof(header), header);\n+            else\n+                this.logger.LogTrace(\"(-):null\");\n+\n+            return header;\n+        }\n+\n+        /// <inheritdoc />\n+        public async Task<List<ProvenBlockHeader>> GetAsync(int fromBlockHeight, int toBlockHeight)\n+        {\n+            var cachedHeaders = new List<ProvenBlockHeader>();            \n+\n+            using (new StopwatchDisposable(o => this.performanceCounter.AddQueryTime(o)))\n+            {\n+                int heightKey = fromBlockHeight;\n+\n+                // Check if the items exist in the store cache before checking the repository.\n+                ProvenBlockHeader headerCache = null;\n+\n+                var blockHeightList = new List<int>();\n+\n+                do\n+                {\n+                    headerCache = this.GetHeaderFromStoreCache(heightKey);\n+\n+                    if (headerCache != null)\n+                        cachedHeaders.Add(headerCache);","path":"src/Stratis.Bitcoin.Features.Consensus/ProvenBlockHeaders/ProvenBlockHeaderStore.cs","position":185,"original_position":185,"commit_id":"dc7de550439c3a4b45f7659cdd7a742359f3c765","original_commit_id":"dc7de550439c3a4b45f7659cdd7a742359f3c765","user":{"login":"dangershony","id":7487930,"node_id":"MDQ6VXNlcjc0ODc5MzA=","avatar_url":"https://avatars2.githubusercontent.com/u/7487930?v=4","gravatar_id":"","url":"https://api.github.com/users/dangershony","html_url":"https://github.com/dangershony","followers_url":"https://api.github.com/users/dangershony/followers","following_url":"https://api.github.com/users/dangershony/following{/other_user}","gists_url":"https://api.github.com/users/dangershony/gists{/gist_id}","starred_url":"https://api.github.com/users/dangershony/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/dangershony/subscriptions","organizations_url":"https://api.github.com/users/dangershony/orgs","repos_url":"https://api.github.com/users/dangershony/repos","events_url":"https://api.github.com/users/dangershony/events{/privacy}","received_events_url":"https://api.github.com/users/dangershony/received_events","type":"User","site_admin":false},"body":"Perhaps a more correct name for the lists are headersInCache and headersNotInCache","created_at":"2018-10-03T10:35:45Z","updated_at":"2018-10-03T10:35:45Z","html_url":"https://github.com/stratisproject/StratisBitcoinFullNode/pull/2276#discussion_r222261174","pull_request_url":"https://api.github.com/repos/stratisproject/StratisBitcoinFullNode/pulls/2276","author_association":"CONTRIBUTOR","_links":{"self":{"href":"https://api.github.com/repos/stratisproject/StratisBitcoinFullNode/pulls/comments/222261174"},"html":{"href":"https://github.com/stratisproject/StratisBitcoinFullNode/pull/2276#discussion_r222261174"},"pull_request":{"href":"https://api.github.com/repos/stratisproject/StratisBitcoinFullNode/pulls/2276"}}},"pull_request":{"url":"https://api.github.com/repos/stratisproject/StratisBitcoinFullNode/pulls/2276","id":217960934,"node_id":"MDExOlB1bGxSZXF1ZXN0MjE3OTYwOTM0","html_url":"https://github.com/stratisproject/StratisBitcoinFullNode/pull/2276","diff_url":"https://github.com/stratisproject/StratisBitcoinFullNode/pull/2276.diff","patch_url":"https://github.com/stratisproject/StratisBitcoinFullNode/pull/2276.patch","issue_url":"https://api.github.com/repos/stratisproject/StratisBitcoinFullNode/issues/2276","number":2276,"state":"open","locked":false,"title":"[PH] 2142 proven block header store","user":{"login":"ferdeen","id":16000683,"node_id":"MDQ6VXNlcjE2MDAwNjgz","avatar_url":"https://avatars3.githubusercontent.com/u/16000683?v=4","gravatar_id":"","url":"https://api.github.com/users/ferdeen","html_url":"https://github.com/ferdeen","followers_url":"https://api.github.com/users/ferdeen/followers","following_url":"https://api.github.com/users/ferdeen/following{/other_user}","gists_url":"https://api.github.com/users/ferdeen/gists{/gist_id}","starred_url":"https://api.github.com/users/ferdeen/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ferdeen/subscriptions","organizations_url":"https://api.github.com/users/ferdeen/orgs","repos_url":"https://api.github.com/users/ferdeen/repos","events_url":"https://api.github.com/users/ferdeen/events{/privacy}","received_events_url":"https://api.github.com/users/ferdeen/received_events","type":"User","site_admin":false},"body":"Related to #2142.\r\n\r\nI've created the `ProvenBlockHeaderRepository` which allows you to persist `ProvenBlockHeader` items.  With related tests.\r\n\r\nI've started on the `ProvenBlockHeaderStore` - which follows the AsyncQueue pattern and calls into `ProvenBlockHeaderRepository`.  This will require more unit tests.  I'll hold of creating these until `ProvenBlockHeaderStore` contains logic for caching, which will be part of #2143.\r\n\r\nThis code is not integrated into any other code logic - it's stand alone and is executed against its unit tests.\r\n\r\nThe next related task we can add these components in `ConsensusFeature.cs` (`FeatureServices` - line number 81).\r\n\r\nThanks.","created_at":"2018-09-25T12:26:41Z","updated_at":"2018-10-03T10:35:45Z","closed_at":null,"merged_at":null,"merge_commit_sha":"b6301b3e696cc8f8a62160eb8bd6838d999ede48","assignee":null,"assignees":[],"requested_reviewers":[],"requested_teams":[],"labels":[],"milestone":null,"commits_url":"https://api.github.com/repos/stratisproject/StratisBitcoinFullNode/pulls/2276/commits","review_comments_url":"https://api.github.com/repos/stratisproject/StratisBitcoinFullNode/pulls/2276/comments","review_comment_url":"https://api.github.com/repos/stratisproject/StratisBitcoinFullNode/pulls/comments{/number}","comments_url":"https://api.github.com/repos/stratisproject/StratisBitcoinFullNode/issues/2276/comments","statuses_url":"https://api.github.com/repos/stratisproject/StratisBitcoinFullNode/statuses/dc7de550439c3a4b45f7659cdd7a742359f3c765","head":{"label":"ferdeen:2142_ProvenBlockHeader_Store","ref":"2142_ProvenBlockHeader_Store","sha":"dc7de550439c3a4b45f7659cdd7a742359f3c765","user":{"login":"ferdeen","id":16000683,"node_id":"MDQ6VXNlcjE2MDAwNjgz","avatar_url":"https://avatars3.githubusercontent.com/u/16000683?v=4","gravatar_id":"","url":"https://api.github.com/users/ferdeen","html_url":"https://github.com/ferdeen","followers_url":"https://api.github.com/users/ferdeen/followers","following_url":"https://api.github.com/users/ferdeen/following{/other_user}","gists_url":"https://api.github.com/users/ferdeen/gists{/gist_id}","starred_url":"https://api.github.com/users/ferdeen/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ferdeen/subscriptions","organizations_url":"https://api.github.com/users/ferdeen/orgs","repos_url":"https://api.github.com/users/ferdeen/repos","events_url":"https://api.github.com/users/ferdeen/events{/privacy}","received_events_url":"https://api.github.com/users/ferdeen/received_events","type":"User","site_admin":false},"repo":{"id":123270487,"node_id":"MDEwOlJlcG9zaXRvcnkxMjMyNzA0ODc=","name":"StratisBitcoinFullNode","full_name":"ferdeen/StratisBitcoinFullNode","private":false,"owner":{"login":"ferdeen","id":16000683,"node_id":"MDQ6VXNlcjE2MDAwNjgz","avatar_url":"https://avatars3.githubusercontent.com/u/16000683?v=4","gravatar_id":"","url":"https://api.github.com/users/ferdeen","html_url":"https://github.com/ferdeen","followers_url":"https://api.github.com/users/ferdeen/followers","following_url":"https://api.github.com/users/ferdeen/following{/other_user}","gists_url":"https://api.github.com/users/ferdeen/gists{/gist_id}","starred_url":"https://api.github.com/users/ferdeen/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ferdeen/subscriptions","organizations_url":"https://api.github.com/users/ferdeen/orgs","repos_url":"https://api.github.com/users/ferdeen/repos","events_url":"https://api.github.com/users/ferdeen/events{/privacy}","received_events_url":"https://api.github.com/users/ferdeen/received_events","type":"User","site_admin":false},"html_url":"https://github.com/ferdeen/StratisBitcoinFullNode","description":"Bitcoin full node in C#","fork":true,"url":"https://api.github.com/repos/ferdeen/StratisBitcoinFullNode","forks_url":"https://api.github.com/repos/ferdeen/StratisBitcoinFullNode/forks","keys_url":"https://api.github.com/repos/ferdeen/StratisBitcoinFullNode/keys{/key_id}","collaborators_url":"https://api.github.com/repos/ferdeen/StratisBitcoinFullNode/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/ferdeen/StratisBitcoinFullNode/teams","hooks_url":"https://api.github.com/repos/ferdeen/StratisBitcoinFullNode/hooks","issue_events_url":"https://api.github.com/repos/ferdeen/StratisBitcoinFullNode/issues/events{/number}","events_url":"https://api.github.com/repos/ferdeen/StratisBitcoinFullNode/events","assignees_url":"https://api.github.com/repos/ferdeen/StratisBitcoinFullNode/assignees{/user}","branches_url":"https://api.github.com/repos/ferdeen/StratisBitcoinFullNode/branches{/branch}","tags_url":"https://api.github.com/repos/ferdeen/StratisBitcoinFullNode/tags","blobs_url":"https://api.github.com/repos/ferdeen/StratisBitcoinFullNode/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/ferdeen/StratisBitcoinFullNode/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/ferdeen/StratisBitcoinFullNode/git/refs{/sha}","trees_url":"https://api.github.com/repos/ferdeen/StratisBitcoinFullNode/git/trees{/sha}","statuses_url":"https://api.github.com/repos/ferdeen/StratisBitcoinFullNode/statuses/{sha}","languages_url":"https://api.github.com/repos/ferdeen/StratisBitcoinFullNode/languages","stargazers_url":"https://api.github.com/repos/ferdeen/StratisBitcoinFullNode/stargazers","contributors_url":"https://api.github.com/repos/ferdeen/StratisBitcoinFullNode/contributors","subscribers_url":"https://api.github.com/repos/ferdeen/StratisBitcoinFullNode/subscribers","subscription_url":"https://api.github.com/repos/ferdeen/StratisBitcoinFullNode/subscription","commits_url":"https://api.github.com/repos/ferdeen/StratisBitcoinFullNode/commits{/sha}","git_commits_url":"https://api.github.com/repos/ferdeen/StratisBitcoinFullNode/git/commits{/sha}","comments_url":"https://api.github.com/repos/ferdeen/StratisBitcoinFullNode/comments{/number}","issue_comment_url":"https://api.github.com/repos/ferdeen/StratisBitcoinFullNode/issues/comments{/number}","contents_url":"https://api.github.com/repos/ferdeen/StratisBitcoinFullNode/contents/{+path}","compare_url":"https://api.github.com/repos/ferdeen/StratisBitcoinFullNode/compare/{base}...{head}","merges_url":"https://api.github.com/repos/ferdeen/StratisBitcoinFullNode/merges","archive_url":"https://api.github.com/repos/ferdeen/StratisBitcoinFullNode/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/ferdeen/StratisBitcoinFullNode/downloads","issues_url":"https://api.github.com/repos/ferdeen/StratisBitcoinFullNode/issues{/number}","pulls_url":"https://api.github.com/repos/ferdeen/StratisBitcoinFullNode/pulls{/number}","milestones_url":"https://api.github.com/repos/ferdeen/StratisBitcoinFullNode/milestones{/number}","notifications_url":"https://api.github.com/repos/ferdeen/StratisBitcoinFullNode/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/ferdeen/StratisBitcoinFullNode/labels{/name}","releases_url":"https://api.github.com/repos/ferdeen/StratisBitcoinFullNode/releases{/id}","deployments_url":"https://api.github.com/repos/ferdeen/StratisBitcoinFullNode/deployments","created_at":"2018-02-28T10:40:08Z","updated_at":"2018-10-03T08:14:24Z","pushed_at":"2018-10-03T09:54:28Z","git_url":"git://github.com/ferdeen/StratisBitcoinFullNode.git","ssh_url":"git@github.com:ferdeen/StratisBitcoinFullNode.git","clone_url":"https://github.com/ferdeen/StratisBitcoinFullNode.git","svn_url":"https://github.com/ferdeen/StratisBitcoinFullNode","homepage":"https://stratisplatform.com","size":33826,"stargazers_count":1,"watchers_count":1,"language":"C#","has_issues":false,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"archived":false,"open_issues_count":0,"license":{"key":"mit","name":"MIT License","spdx_id":"MIT","url":"https://api.github.com/licenses/mit","node_id":"MDc6TGljZW5zZTEz"},"forks":0,"open_issues":0,"watchers":1,"default_branch":"master"}},"base":{"label":"stratisproject:master","ref":"master","sha":"bbef6468be414522cb7244279db8de162cca3167","user":{"login":"stratisproject","id":15229748,"node_id":"MDEyOk9yZ2FuaXphdGlvbjE1MjI5NzQ4","avatar_url":"https://avatars0.githubusercontent.com/u/15229748?v=4","gravatar_id":"","url":"https://api.github.com/users/stratisproject","html_url":"https://github.com/stratisproject","followers_url":"https://api.github.com/users/stratisproject/followers","following_url":"https://api.github.com/users/stratisproject/following{/other_user}","gists_url":"https://api.github.com/users/stratisproject/gists{/gist_id}","starred_url":"https://api.github.com/users/stratisproject/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/stratisproject/subscriptions","organizations_url":"https://api.github.com/users/stratisproject/orgs","repos_url":"https://api.github.com/users/stratisproject/repos","events_url":"https://api.github.com/users/stratisproject/events{/privacy}","received_events_url":"https://api.github.com/users/stratisproject/received_events","type":"Organization","site_admin":false},"repo":{"id":67271290,"node_id":"MDEwOlJlcG9zaXRvcnk2NzI3MTI5MA==","name":"StratisBitcoinFullNode","full_name":"stratisproject/StratisBitcoinFullNode","private":false,"owner":{"login":"stratisproject","id":15229748,"node_id":"MDEyOk9yZ2FuaXphdGlvbjE1MjI5NzQ4","avatar_url":"https://avatars0.githubusercontent.com/u/15229748?v=4","gravatar_id":"","url":"https://api.github.com/users/stratisproject","html_url":"https://github.com/stratisproject","followers_url":"https://api.github.com/users/stratisproject/followers","following_url":"https://api.github.com/users/stratisproject/following{/other_user}","gists_url":"https://api.github.com/users/stratisproject/gists{/gist_id}","starred_url":"https://api.github.com/users/stratisproject/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/stratisproject/subscriptions","organizations_url":"https://api.github.com/users/stratisproject/orgs","repos_url":"https://api.github.com/users/stratisproject/repos","events_url":"https://api.github.com/users/stratisproject/events{/privacy}","received_events_url":"https://api.github.com/users/stratisproject/received_events","type":"Organization","site_admin":false},"html_url":"https://github.com/stratisproject/StratisBitcoinFullNode","description":"Bitcoin full node in C#","fork":false,"url":"https://api.github.com/repos/stratisproject/StratisBitcoinFullNode","forks_url":"https://api.github.com/repos/stratisproject/StratisBitcoinFullNode/forks","keys_url":"https://api.github.com/repos/stratisproject/StratisBitcoinFullNode/keys{/key_id}","collaborators_url":"https://api.github.com/repos/stratisproject/StratisBitcoinFullNode/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/stratisproject/StratisBitcoinFullNode/teams","hooks_url":"https://api.github.com/repos/stratisproject/StratisBitcoinFullNode/hooks","issue_events_url":"https://api.github.com/repos/stratisproject/StratisBitcoinFullNode/issues/events{/number}","events_url":"https://api.github.com/repos/stratisproject/StratisBitcoinFullNode/events","assignees_url":"https://api.github.com/repos/stratisproject/StratisBitcoinFullNode/assignees{/user}","branches_url":"https://api.github.com/repos/stratisproject/StratisBitcoinFullNode/branches{/branch}","tags_url":"https://api.github.com/repos/stratisproject/StratisBitcoinFullNode/tags","blobs_url":"https://api.github.com/repos/stratisproject/StratisBitcoinFullNode/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/stratisproject/StratisBitcoinFullNode/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/stratisproject/StratisBitcoinFullNode/git/refs{/sha}","trees_url":"https://api.github.com/repos/stratisproject/StratisBitcoinFullNode/git/trees{/sha}","statuses_url":"https://api.github.com/repos/stratisproject/StratisBitcoinFullNode/statuses/{sha}","languages_url":"https://api.github.com/repos/stratisproject/StratisBitcoinFullNode/languages","stargazers_url":"https://api.github.com/repos/stratisproject/StratisBitcoinFullNode/stargazers","contributors_url":"https://api.github.com/repos/stratisproject/StratisBitcoinFullNode/contributors","subscribers_url":"https://api.github.com/repos/stratisproject/StratisBitcoinFullNode/subscribers","subscription_url":"https://api.github.com/repos/stratisproject/StratisBitcoinFullNode/subscription","commits_url":"https://api.github.com/repos/stratisproject/StratisBitcoinFullNode/commits{/sha}","git_commits_url":"https://api.github.com/repos/stratisproject/StratisBitcoinFullNode/git/commits{/sha}","comments_url":"https://api.github.com/repos/stratisproject/StratisBitcoinFullNode/comments{/number}","issue_comment_url":"https://api.github.com/repos/stratisproject/StratisBitcoinFullNode/issues/comments{/number}","contents_url":"https://api.github.com/repos/stratisproject/StratisBitcoinFullNode/contents/{+path}","compare_url":"https://api.github.com/repos/stratisproject/StratisBitcoinFullNode/compare/{base}...{head}","merges_url":"https://api.github.com/repos/stratisproject/StratisBitcoinFullNode/merges","archive_url":"https://api.github.com/repos/stratisproject/StratisBitcoinFullNode/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/stratisproject/StratisBitcoinFullNode/downloads","issues_url":"https://api.github.com/repos/stratisproject/StratisBitcoinFullNode/issues{/number}","pulls_url":"https://api.github.com/repos/stratisproject/StratisBitcoinFullNode/pulls{/number}","milestones_url":"https://api.github.com/repos/stratisproject/StratisBitcoinFullNode/milestones{/number}","notifications_url":"https://api.github.com/repos/stratisproject/StratisBitcoinFullNode/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/stratisproject/StratisBitcoinFullNode/labels{/name}","releases_url":"https://api.github.com/repos/stratisproject/StratisBitcoinFullNode/releases{/id}","deployments_url":"https://api.github.com/repos/stratisproject/StratisBitcoinFullNode/deployments","created_at":"2016-09-03T04:32:51Z","updated_at":"2018-10-03T09:04:59Z","pushed_at":"2018-10-03T10:05:34Z","git_url":"git://github.com/stratisproject/StratisBitcoinFullNode.git","ssh_url":"git@github.com:stratisproject/StratisBitcoinFullNode.git","clone_url":"https://github.com/stratisproject/StratisBitcoinFullNode.git","svn_url":"https://github.com/stratisproject/StratisBitcoinFullNode","homepage":"https://stratisplatform.com","size":34124,"stargazers_count":581,"watchers_count":581,"language":"C#","has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":252,"mirror_url":null,"archived":false,"open_issues_count":180,"license":{"key":"mit","name":"MIT License","spdx_id":"MIT","url":"https://api.github.com/licenses/mit","node_id":"MDc6TGljZW5zZTEz"},"forks":252,"open_issues":180,"watchers":581,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/stratisproject/StratisBitcoinFullNode/pulls/2276"},"html":{"href":"https://github.com/stratisproject/StratisBitcoinFullNode/pull/2276"},"issue":{"href":"https://api.github.com/repos/stratisproject/StratisBitcoinFullNode/issues/2276"},"comments":{"href":"https://api.github.com/repos/stratisproject/StratisBitcoinFullNode/issues/2276/comments"},"review_comments":{"href":"https://api.github.com/repos/stratisproject/StratisBitcoinFullNode/pulls/2276/comments"},"review_comment":{"href":"https://api.github.com/repos/stratisproject/StratisBitcoinFullNode/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/stratisproject/StratisBitcoinFullNode/pulls/2276/commits"},"statuses":{"href":"https://api.github.com/repos/stratisproject/StratisBitcoinFullNode/statuses/dc7de550439c3a4b45f7659cdd7a742359f3c765"}},"author_association":"CONTRIBUTOR"}}
{"actor":{"display_login":"dangershony"}}