{"action":"created","comment":{"url":"https://api.github.com/repos/graft-project/graft-ng/pulls/comments/235472669","pull_request_review_id":177347028,"id":235472669,"node_id":"MDI0OlB1bGxSZXF1ZXN0UmV2aWV3Q29tbWVudDIzNTQ3MjY2OQ==","diff_hunk":"@@ -323,34 +325,17 @@ void WalletManager::createAccount(Context& context, const std::string& password,\n \n     registerWallet(context, wallet_id, wallet);\n \n-    rapidjson::Document json;\n-    json.SetObject();\n-    rapidjson::Value value(rapidjson::kStringType), result_value(rapidjson::kNumberType);\n+    WalletCreateAccountCallbackRequest out;\n \n-    result_value.SetInt(0);\n-    json.AddMember(\"Result\", result_value, json.GetAllocator());\n+    out.Result   = 0;","path":"src/walletnode/wallet_manager.cpp","position":330,"original_position":26,"commit_id":"12450fc2540577982ef66810bdc52252f68ef3b7","original_commit_id":"12450fc2540577982ef66810bdc52252f68ef3b7","user":{"login":"bitkis","id":36085298,"node_id":"MDQ6VXNlcjM2MDg1Mjk4","avatar_url":"https://avatars3.githubusercontent.com/u/36085298?v=4","gravatar_id":"","url":"https://api.github.com/users/bitkis","html_url":"https://github.com/bitkis","followers_url":"https://api.github.com/users/bitkis/followers","following_url":"https://api.github.com/users/bitkis/following{/other_user}","gists_url":"https://api.github.com/users/bitkis/gists{/gist_id}","starred_url":"https://api.github.com/users/bitkis/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/bitkis/subscriptions","organizations_url":"https://api.github.com/users/bitkis/orgs","repos_url":"https://api.github.com/users/bitkis/repos","events_url":"https://api.github.com/users/bitkis/events{/privacy}","received_events_url":"https://api.github.com/users/bitkis/received_events","type":"User","site_admin":false},"body":"initiation can be done in the macro","created_at":"2018-11-21T17:08:42Z","updated_at":"2018-11-21T17:08:57Z","html_url":"https://github.com/graft-project/graft-ng/pull/156#discussion_r235472669","pull_request_url":"https://api.github.com/repos/graft-project/graft-ng/pulls/156","author_association":"COLLABORATOR","_links":{"self":{"href":"https://api.github.com/repos/graft-project/graft-ng/pulls/comments/235472669"},"html":{"href":"https://github.com/graft-project/graft-ng/pull/156#discussion_r235472669"},"pull_request":{"href":"https://api.github.com/repos/graft-project/graft-ng/pulls/156"}}},"pull_request":{"url":"https://api.github.com/repos/graft-project/graft-ng/pulls/156","id":231560879,"node_id":"MDExOlB1bGxSZXF1ZXN0MjMxNTYwODc5","html_url":"https://github.com/graft-project/graft-ng/pull/156","diff_url":"https://github.com/graft-project/graft-ng/pull/156.diff","patch_url":"https://github.com/graft-project/graft-ng/pull/156.patch","issue_url":"https://api.github.com/repos/graft-project/graft-ng/issues/156","number":156,"state":"open","locked":false,"title":"Feature/wallet manager","user":{"login":"LenyKholodov","id":10838122,"node_id":"MDQ6VXNlcjEwODM4MTIy","avatar_url":"https://avatars0.githubusercontent.com/u/10838122?v=4","gravatar_id":"","url":"https://api.github.com/users/LenyKholodov","html_url":"https://github.com/LenyKholodov","followers_url":"https://api.github.com/users/LenyKholodov/followers","following_url":"https://api.github.com/users/LenyKholodov/following{/other_user}","gists_url":"https://api.github.com/users/LenyKholodov/gists{/gist_id}","starred_url":"https://api.github.com/users/LenyKholodov/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/LenyKholodov/subscriptions","organizations_url":"https://api.github.com/users/LenyKholodov/orgs","repos_url":"https://api.github.com/users/LenyKholodov/repos","events_url":"https://api.github.com/users/LenyKholodov/events{/privacy}","received_events_url":"https://api.github.com/users/LenyKholodov/received_events","type":"User","site_admin":false},"body":"**Summary**\r\n\r\nBasic wallet node implementation:\r\n- standalone wallet_server based on GraftServer;\r\n- REST API requests: /api/create_account, /api/restore_account, /api/wallet_balance, /api/prepare_transfer;\r\n- WebHook callback implementation for all wallet requests;\r\n- HTTP client fixes: reading HTTP headers and remote host/port;\r\n- WalletManager implementation with sorting requests based on particular wallet;\r\n- wallets disk caches flushing based on constant period (1 hour);\r\n- wallets memory caches flushing based on Context::Global functionality.\r\n\r\n**Implementation Overview**\r\n\r\nWallet node server is based on the same codebase as Supernode and works similar to it. The root class for the wallet node server is WalletServer. This class implements registering of endpoint routers, controls wallets management in memory and persistent storage, provides possibility for wallet node configuration. Communication with wallet node is implemented via HTTP REST with parameters in JSON within request's body.\r\n\r\nWalletServer uses thread pool to parallelize requests processing as well as Supernode. However, unlike Supernode WalletServer sorts requests to a particular wallet in a sequential order and prevents simultaneous access to a wallet from different threads. This logic is implemented on top of ThreadPool in Strand class (which is similar to boost::io_service::strand class).\r\n\r\nFor better cohesion wallet processing logic is isolated in WalletManager class which makes all work except of API requests processing. WalletManager solves following tasks:\r\n\r\ncontrols lifetime of wallet objects;\r\ncontrols simultaneous access to wallet objects;\r\nimplements target wallet API operations (like wallet creation, restoring, balance retrieving and others).\r\n\r\n**API Model**\r\n\r\nWallet node provides asynchronous API for its operations via REST. Since wallet operations may take long time, response from wallet node to clients is implemented using web hooks. So clients only initiates requests and gets formal status code based on requests parameters checking. Then wallet node queues request to wallet and processes it in sequential order (related to other transactions for this particular wallet). After finishing of transaction wallet node initiates HTTP request to callback URL (webhook) which was provided in the corresponding request.\r\n\r\n**Strand**\r\n\r\nCurrent implementation of thread pool does not allow to organise tasks in sequential order. So it is implied that any task may be executed independetly to other tasks in pool. However, it is required to execute some tasks simultaneously (tasks for different wallets) but some tasks sequentually (tasks for particular wallet). To provide such possibility new class Strand has been added. It contains queue of tasks and implements possibility to add proxy task in a thread pool which may be invoked from any thread pool's worker.\r\n\r\nStrand implements lock free algorithm of deferred calls counting. So each time when strand proxy function is invoked it checks if there is another invocation of same strand object in another thread which is executing. If there is no such task, strand starts executing first available task from strand's queue (based on FIFO queue). If another task is being processed, in another thread strand increments a counter of deferred calls and exits from invocation. So when another thread finishes task execution, it will check the deferred calls counter and execute yet one task from a queue (until queue is empty or the counter is zero).","created_at":"2018-11-16T15:11:28Z","updated_at":"2018-11-21T17:08:57Z","closed_at":null,"merged_at":null,"merge_commit_sha":"a89f6de47fa937f2f6e4798c5820950c80939cb7","assignee":null,"assignees":[],"requested_reviewers":[],"requested_teams":[],"labels":[],"milestone":null,"commits_url":"https://api.github.com/repos/graft-project/graft-ng/pulls/156/commits","review_comments_url":"https://api.github.com/repos/graft-project/graft-ng/pulls/156/comments","review_comment_url":"https://api.github.com/repos/graft-project/graft-ng/pulls/comments{/number}","comments_url":"https://api.github.com/repos/graft-project/graft-ng/issues/156/comments","statuses_url":"https://api.github.com/repos/graft-project/graft-ng/statuses/12450fc2540577982ef66810bdc52252f68ef3b7","head":{"label":"graft-project:feature/wallet_manager","ref":"feature/wallet_manager","sha":"12450fc2540577982ef66810bdc52252f68ef3b7","user":{"login":"graft-project","id":30155786,"node_id":"MDEyOk9yZ2FuaXphdGlvbjMwMTU1Nzg2","avatar_url":"https://avatars2.githubusercontent.com/u/30155786?v=4","gravatar_id":"","url":"https://api.github.com/users/graft-project","html_url":"https://github.com/graft-project","followers_url":"https://api.github.com/users/graft-project/followers","following_url":"https://api.github.com/users/graft-project/following{/other_user}","gists_url":"https://api.github.com/users/graft-project/gists{/gist_id}","starred_url":"https://api.github.com/users/graft-project/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/graft-project/subscriptions","organizations_url":"https://api.github.com/users/graft-project/orgs","repos_url":"https://api.github.com/users/graft-project/repos","events_url":"https://api.github.com/users/graft-project/events{/privacy}","received_events_url":"https://api.github.com/users/graft-project/received_events","type":"Organization","site_admin":false},"repo":{"id":128170663,"node_id":"MDEwOlJlcG9zaXRvcnkxMjgxNzA2NjM=","name":"graft-ng","full_name":"graft-project/graft-ng","private":false,"owner":{"login":"graft-project","id":30155786,"node_id":"MDEyOk9yZ2FuaXphdGlvbjMwMTU1Nzg2","avatar_url":"https://avatars2.githubusercontent.com/u/30155786?v=4","gravatar_id":"","url":"https://api.github.com/users/graft-project","html_url":"https://github.com/graft-project","followers_url":"https://api.github.com/users/graft-project/followers","following_url":"https://api.github.com/users/graft-project/following{/other_user}","gists_url":"https://api.github.com/users/graft-project/gists{/gist_id}","starred_url":"https://api.github.com/users/graft-project/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/graft-project/subscriptions","organizations_url":"https://api.github.com/users/graft-project/orgs","repos_url":"https://api.github.com/users/graft-project/repos","events_url":"https://api.github.com/users/graft-project/events{/privacy}","received_events_url":"https://api.github.com/users/graft-project/received_events","type":"Organization","site_admin":false},"html_url":"https://github.com/graft-project/graft-ng","description":null,"fork":false,"url":"https://api.github.com/repos/graft-project/graft-ng","forks_url":"https://api.github.com/repos/graft-project/graft-ng/forks","keys_url":"https://api.github.com/repos/graft-project/graft-ng/keys{/key_id}","collaborators_url":"https://api.github.com/repos/graft-project/graft-ng/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/graft-project/graft-ng/teams","hooks_url":"https://api.github.com/repos/graft-project/graft-ng/hooks","issue_events_url":"https://api.github.com/repos/graft-project/graft-ng/issues/events{/number}","events_url":"https://api.github.com/repos/graft-project/graft-ng/events","assignees_url":"https://api.github.com/repos/graft-project/graft-ng/assignees{/user}","branches_url":"https://api.github.com/repos/graft-project/graft-ng/branches{/branch}","tags_url":"https://api.github.com/repos/graft-project/graft-ng/tags","blobs_url":"https://api.github.com/repos/graft-project/graft-ng/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/graft-project/graft-ng/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/graft-project/graft-ng/git/refs{/sha}","trees_url":"https://api.github.com/repos/graft-project/graft-ng/git/trees{/sha}","statuses_url":"https://api.github.com/repos/graft-project/graft-ng/statuses/{sha}","languages_url":"https://api.github.com/repos/graft-project/graft-ng/languages","stargazers_url":"https://api.github.com/repos/graft-project/graft-ng/stargazers","contributors_url":"https://api.github.com/repos/graft-project/graft-ng/contributors","subscribers_url":"https://api.github.com/repos/graft-project/graft-ng/subscribers","subscription_url":"https://api.github.com/repos/graft-project/graft-ng/subscription","commits_url":"https://api.github.com/repos/graft-project/graft-ng/commits{/sha}","git_commits_url":"https://api.github.com/repos/graft-project/graft-ng/git/commits{/sha}","comments_url":"https://api.github.com/repos/graft-project/graft-ng/comments{/number}","issue_comment_url":"https://api.github.com/repos/graft-project/graft-ng/issues/comments{/number}","contents_url":"https://api.github.com/repos/graft-project/graft-ng/contents/{+path}","compare_url":"https://api.github.com/repos/graft-project/graft-ng/compare/{base}...{head}","merges_url":"https://api.github.com/repos/graft-project/graft-ng/merges","archive_url":"https://api.github.com/repos/graft-project/graft-ng/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/graft-project/graft-ng/downloads","issues_url":"https://api.github.com/repos/graft-project/graft-ng/issues{/number}","pulls_url":"https://api.github.com/repos/graft-project/graft-ng/pulls{/number}","milestones_url":"https://api.github.com/repos/graft-project/graft-ng/milestones{/number}","notifications_url":"https://api.github.com/repos/graft-project/graft-ng/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/graft-project/graft-ng/labels{/name}","releases_url":"https://api.github.com/repos/graft-project/graft-ng/releases{/id}","deployments_url":"https://api.github.com/repos/graft-project/graft-ng/deployments","created_at":"2018-04-05T07:04:54Z","updated_at":"2018-11-20T03:04:11Z","pushed_at":"2018-11-21T15:55:16Z","git_url":"git://github.com/graft-project/graft-ng.git","ssh_url":"git@github.com:graft-project/graft-ng.git","clone_url":"https://github.com/graft-project/graft-ng.git","svn_url":"https://github.com/graft-project/graft-ng","homepage":null,"size":1166,"stargazers_count":10,"watchers_count":10,"language":"C++","has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":5,"mirror_url":null,"archived":false,"open_issues_count":7,"license":null,"forks":5,"open_issues":7,"watchers":10,"default_branch":"master"}},"base":{"label":"graft-project:development/v.0.0.2","ref":"development/v.0.0.2","sha":"d338e832d52e854d5249f46d3de1835ea03e10d9","user":{"login":"graft-project","id":30155786,"node_id":"MDEyOk9yZ2FuaXphdGlvbjMwMTU1Nzg2","avatar_url":"https://avatars2.githubusercontent.com/u/30155786?v=4","gravatar_id":"","url":"https://api.github.com/users/graft-project","html_url":"https://github.com/graft-project","followers_url":"https://api.github.com/users/graft-project/followers","following_url":"https://api.github.com/users/graft-project/following{/other_user}","gists_url":"https://api.github.com/users/graft-project/gists{/gist_id}","starred_url":"https://api.github.com/users/graft-project/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/graft-project/subscriptions","organizations_url":"https://api.github.com/users/graft-project/orgs","repos_url":"https://api.github.com/users/graft-project/repos","events_url":"https://api.github.com/users/graft-project/events{/privacy}","received_events_url":"https://api.github.com/users/graft-project/received_events","type":"Organization","site_admin":false},"repo":{"id":128170663,"node_id":"MDEwOlJlcG9zaXRvcnkxMjgxNzA2NjM=","name":"graft-ng","full_name":"graft-project/graft-ng","private":false,"owner":{"login":"graft-project","id":30155786,"node_id":"MDEyOk9yZ2FuaXphdGlvbjMwMTU1Nzg2","avatar_url":"https://avatars2.githubusercontent.com/u/30155786?v=4","gravatar_id":"","url":"https://api.github.com/users/graft-project","html_url":"https://github.com/graft-project","followers_url":"https://api.github.com/users/graft-project/followers","following_url":"https://api.github.com/users/graft-project/following{/other_user}","gists_url":"https://api.github.com/users/graft-project/gists{/gist_id}","starred_url":"https://api.github.com/users/graft-project/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/graft-project/subscriptions","organizations_url":"https://api.github.com/users/graft-project/orgs","repos_url":"https://api.github.com/users/graft-project/repos","events_url":"https://api.github.com/users/graft-project/events{/privacy}","received_events_url":"https://api.github.com/users/graft-project/received_events","type":"Organization","site_admin":false},"html_url":"https://github.com/graft-project/graft-ng","description":null,"fork":false,"url":"https://api.github.com/repos/graft-project/graft-ng","forks_url":"https://api.github.com/repos/graft-project/graft-ng/forks","keys_url":"https://api.github.com/repos/graft-project/graft-ng/keys{/key_id}","collaborators_url":"https://api.github.com/repos/graft-project/graft-ng/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/graft-project/graft-ng/teams","hooks_url":"https://api.github.com/repos/graft-project/graft-ng/hooks","issue_events_url":"https://api.github.com/repos/graft-project/graft-ng/issues/events{/number}","events_url":"https://api.github.com/repos/graft-project/graft-ng/events","assignees_url":"https://api.github.com/repos/graft-project/graft-ng/assignees{/user}","branches_url":"https://api.github.com/repos/graft-project/graft-ng/branches{/branch}","tags_url":"https://api.github.com/repos/graft-project/graft-ng/tags","blobs_url":"https://api.github.com/repos/graft-project/graft-ng/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/graft-project/graft-ng/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/graft-project/graft-ng/git/refs{/sha}","trees_url":"https://api.github.com/repos/graft-project/graft-ng/git/trees{/sha}","statuses_url":"https://api.github.com/repos/graft-project/graft-ng/statuses/{sha}","languages_url":"https://api.github.com/repos/graft-project/graft-ng/languages","stargazers_url":"https://api.github.com/repos/graft-project/graft-ng/stargazers","contributors_url":"https://api.github.com/repos/graft-project/graft-ng/contributors","subscribers_url":"https://api.github.com/repos/graft-project/graft-ng/subscribers","subscription_url":"https://api.github.com/repos/graft-project/graft-ng/subscription","commits_url":"https://api.github.com/repos/graft-project/graft-ng/commits{/sha}","git_commits_url":"https://api.github.com/repos/graft-project/graft-ng/git/commits{/sha}","comments_url":"https://api.github.com/repos/graft-project/graft-ng/comments{/number}","issue_comment_url":"https://api.github.com/repos/graft-project/graft-ng/issues/comments{/number}","contents_url":"https://api.github.com/repos/graft-project/graft-ng/contents/{+path}","compare_url":"https://api.github.com/repos/graft-project/graft-ng/compare/{base}...{head}","merges_url":"https://api.github.com/repos/graft-project/graft-ng/merges","archive_url":"https://api.github.com/repos/graft-project/graft-ng/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/graft-project/graft-ng/downloads","issues_url":"https://api.github.com/repos/graft-project/graft-ng/issues{/number}","pulls_url":"https://api.github.com/repos/graft-project/graft-ng/pulls{/number}","milestones_url":"https://api.github.com/repos/graft-project/graft-ng/milestones{/number}","notifications_url":"https://api.github.com/repos/graft-project/graft-ng/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/graft-project/graft-ng/labels{/name}","releases_url":"https://api.github.com/repos/graft-project/graft-ng/releases{/id}","deployments_url":"https://api.github.com/repos/graft-project/graft-ng/deployments","created_at":"2018-04-05T07:04:54Z","updated_at":"2018-11-20T03:04:11Z","pushed_at":"2018-11-21T15:55:16Z","git_url":"git://github.com/graft-project/graft-ng.git","ssh_url":"git@github.com:graft-project/graft-ng.git","clone_url":"https://github.com/graft-project/graft-ng.git","svn_url":"https://github.com/graft-project/graft-ng","homepage":null,"size":1166,"stargazers_count":10,"watchers_count":10,"language":"C++","has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":5,"mirror_url":null,"archived":false,"open_issues_count":7,"license":null,"forks":5,"open_issues":7,"watchers":10,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/graft-project/graft-ng/pulls/156"},"html":{"href":"https://github.com/graft-project/graft-ng/pull/156"},"issue":{"href":"https://api.github.com/repos/graft-project/graft-ng/issues/156"},"comments":{"href":"https://api.github.com/repos/graft-project/graft-ng/issues/156/comments"},"review_comments":{"href":"https://api.github.com/repos/graft-project/graft-ng/pulls/156/comments"},"review_comment":{"href":"https://api.github.com/repos/graft-project/graft-ng/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/graft-project/graft-ng/pulls/156/commits"},"statuses":{"href":"https://api.github.com/repos/graft-project/graft-ng/statuses/12450fc2540577982ef66810bdc52252f68ef3b7"}},"author_association":"NONE"}}
{"actor":{"display_login":"bitkis"}}