{"action":"created","comment":{"url":"https://api.github.com/repos/solana-labs/solana/pulls/comments/209764705","pull_request_review_id":145839172,"id":209764705,"node_id":"MDI0OlB1bGxSZXF1ZXN0UmV2aWV3Q29tbWVudDIwOTc2NDcwNQ==","diff_hunk":"@@ -37,154 +37,175 @@ version 0.1\n \n In Figure 1 an untrusted client, creates a program in the front-end language of her choice, (like C/C++/Rust/Lua), and compiles it with LLVM to a position independent shared object ELF, targeting BPF bytecode. Solana will safely load and execute the ELF.\n \n-## Bytecode\n-\n-Our bytecode is based on Berkley Packet Filter. The requirements for BPF overlap almost exactly with the requirements we have:\n-\n-1. Deterministic amount of time to execute the code\n-2. Bytecode that is portable between machine instruction sets\n-3. Verified memory accesses\n-4. Fast to load the object, verify the bytecode and JIT to local machine instruction set\n-\n-For 1, that means that loops are unrolled, and for any jumps back we can guard them with a check against the number of instruction that have been executed at this point.  If the limit is reached, the program yields its execution.  This involves saving the stack and current instruction index.\n-\n-For 2, the BPF bytecode already easily maps to x86–64, arm64 and other instruction sets. \n-\n-For 3, every load and store that is relative can be checked to be within the expected memory that is passed into the ELF.  Dynamic load and stores can do a runtime check against available memory, these will be slow and should be avoided.\n-\n-For 4, Fully linked PIC ELF with just a single RX segment. Effectively we are linking a shared object with `-fpic -target bpf` and with a linker script to collect everything into a single RX segment. Writable globals are not supported.\n-\n-### Address Checks\n-\n-The interface to the module takes a `&mut Vec<Vec<u8>>` in rust, or a `int sz, void* data[sz], int szs[sz]` in `C`.  Given the module's bytecode, for each method, we need to analyze the bounds on load and stores into each buffer the module uses.  This check needs to be done `on chain`, and after those bounds are computed we can verify that the user supplied array of buffers will not cause a memory fault.  For load and stores that we cannot analyze, we can replace with a `safe_load` and `safe_store` instruction that will check the table for access.\n-\n-## Loader\n-The loader is our first smart contract. The job of this contract is to load the actual program with its own instance data.  The loader will verify the bytecode and that the object implements the expected entry points.\n-\n-Since there is only one RX segment, the context for the contract instance is passed into each entry point as well as the event data for that entry point.\n-\n-A client will create a transaction to create a new loader instance:\n-\n-`Solana_NewLoader(Loader Instance PubKey, proof of key ownership, space I need for my elf)`\n-\n-A client will then do a bunch of transactions to load its elf into the loader instance they created:\n-\n-`Loader_UploadElf(Loader Instance PubKey, proof of key ownership, pos start, pos end, data)`\n-\n-At this point the client can create a new instance of the module with its own instance address:\n-\n-`Loader_NewInstance(Loader Instance PubKey, proof of key ownership, Instance PubKey, proof of key ownership)`\n-\n-Once the instance has been created, the client may need to upload more user data to solana to configure this instance:\n-\n-`Instance_UploadModuleData(Instance PubKey, proof of key ownership, pos start, pos end, data)`\n-\n-Now clients can `start` the instance:\n-\n-`Instance_Start(Instance PubKey, proof of key ownership)`\n-\n ## Runtime\n \n-Our goal with the runtime is to have a general purpose execution environment that is highly parallelizable and doesn't require dynamic resource management. We want to execute as many contracts as we can in parallel, and have them pass or fail without a destructive state change.\n-\n-### State and Entry Point\n-\n-State is addressed by an account which is at the moment simply the PubKey.  Our goal is to eliminate dynamic memory allocation in the smart contract itself, so the contract is a function that takes a mapping of [(PubKey,State)] and returns [(PubKey, State')].  The output of keys is a subset of the input.  Three basic kinds of state exist:\n+The goal with the runtime is to have a general purpose execution environment that is highly parallelizeable and doesn't require dynamic resource management. The goal is to execute as many contracts as possible in parallel, and have them pass or fail without a destructive state change.\n \n-* Instance State\n-* Participant State\n-* Caller State\n \n-There isn't any difference in how each is implemented, but conceptually Participant State is memory that is allocated for each participant in the contract.  Instance State is memory that is allocated for the contract itself, and Caller State is memory that the transactions caller has allocated.\n+### State\n \n+State is addressed by an account which is at the moment simply the PubKey.  Our goal is to eliminate dynamic memory allocation in the smart contract itself, so the contract is a function that takes a mapping of [(PubKey,State)] and returns [(PubKey, State')].\n \n-### Call\n-\n+### Call Structure\n ```\n-void call(\n-    const struct instance_data *data,\n-    const uint8_t kind[],  //instance|participant|caller|read|write\n-    const uint8_t *keys[],\n-    uint8_t *data[],\n-    int num,\n-    uint8_t dirty[],        //dirty memory bits\n-    uint8_t *userdata,      //current transaction data\n-);\n+/// Call definition\n+/// Signed portion\n+#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone)]\n+pub struct CallData {\n+    /// number of keys to load, aka the to key\n+    /// keys[0] is the caller's key\n+    pub keys: Vec<PublicKey>,\n+\n+    /// the set of PublicKeys that are required to have a proof\n+    pub required_proofs: Vec<u8>,\n+\n+    /// PoH data\n+    /// last id PoH observed by the sender\n+    pub last_count: u64,\n+    /// last PoH hash observed by the sender\n+    pub last_hash: Hash,\n+\n+    /// Program\n+    /// the address of the program we want to call\n+    pub contract: ContractId,\n+    /// OS scheduling fee\n+    pub fee: i64,\n+    /// struct version to prevent duplicate spends\n+    /// Calls with a version <= Page.version are rejected\n+    pub version: u64,\n+    /// method to call in the contract\n+    pub method: u8,\n+    /// usedata in bytes\n+    pub user_data: Vec<u8>,\n+}\n+\n+#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone)]\n+pub struct Call {\n+    /// Signatures and Keys\n+    /// (signature, key index)\n+    /// This vector contains a tuple of signatures, and the key index the signature is for\n+    /// proofs[0] is always key[0]\n+    pub proofs: Vec<Signature>,\n+    pub data: CallData,\n+}\n ```\n \n-To call this operation, the transaction that is destined to the contract instance specifies what keyed state it should present to the `call` function.  To allocate the state memory or a call context, the client has to first call a function on the contract with the designed address that will own the state.\n-\n-At its core, this is a system call that requires cryptographic proof of ownership of memory regions instead of an OS that checks page tables for access rights.\n-\n-* `Instance_AllocateContext(Instance PubKey, My PubKey, Proof of key ownership)`\n-\n-Any transaction can then call `call` on the contract with a set of keys.  It's up to the contract itself to manage ownership:\n-\n-* `Instance_Call(Instance PubKey, [Context PubKeys], proofs of ownership, userdata...)`\n+At it's core, this is just a set of PublicKeys and Signatures with a bit of metadata.  The contract PublicKey routes this transaction into that contracts entry point.  `version` is used for dropping retransmitted requests.\n \n Contracts should be able to read any state that is part of solana, but only write to state that the contract allocated.\n \n-#### Caller State\n-\n-Caller `state` is memory allocated for the `call` that belongs to the public key that is issuing the `call`.  This is the caller's context.\n-\n-#### Instance State\n-\n-Instance `state` is memory that belongs to this contract instance.  We may also need module-wide `state` as well.\n-\n-#### Participant State\n+### Execution\n \n-Participant `state` is any other memory.  In some cases it may make sense to have these allocated as part of the call by the caller.\n+Calls batched and processed in a pipeline\n \n-### Reduce\n+```\n++-----------+    +-------------+    +--------------+    +--------------------+    \n+| sigverify |--->| lock memory |--->| validate fee |--->| allocate new pages |--->\n++-----------+    +-------------+    +--------------+    +--------------------+    \n+                                \n+    +------------+    +---------+    +--------------+    +-=------------+   \n+--->| load pages |--->| execute |--->|unlock memory |--->| commit pages |   \n+    +------------+    +---------+    +--------------+    +--------------+   \n \n-Some operations on the contract will require iteration over all the keys.  To make this parallelizable the iteration is broken up into reduce calls which are combined.\n+```\n \n+At the `execute` stage, the loaded pages have no data dependencies, so all the contracts can be executed in parallel. \n+## Memory Management\n ```\n-void reduce_m(\n-    const struct instance_data *data,\n-    const uint8_t *keys[],\n-    const uint8_t *data[],\n-    int num,\n-    uint8_t *reduce_data,\n-);\n-\n-void reduce_r(\n-    const struct instance_data *data,\n-    const uint8_t *reduce_data[],\n-    int num,\n-    uint8_t *reduce_data,\n-);\n+pub struct Page {\n+    /// key that indexes this page\n+    /// proove ownership of this key to spend from this Page\n+    owner: PublicKey,\n+    /// contract that owns this page\n+    /// contract can write to the data that is pointed to by `pointer`\n+    contract: PublicKey,\n+    /// balance that belongs to owner\n+    balance: u64,\n+    /// version of the structure, public for testing\n+    version: u64,\n+    /// hash of the page data\n+    memhash: Hash,","path":"rfcs/rfc-001-smart-contracts-engine.md","position":201,"original_position":201,"commit_id":"5d1dcfa93c3c577b0abb94df560068ec86f8c70d","original_commit_id":"5d1dcfa93c3c577b0abb94df560068ec86f8c70d","user":{"login":"garious","id":55449,"node_id":"MDQ6VXNlcjU1NDQ5","avatar_url":"https://avatars1.githubusercontent.com/u/55449?v=4","gravatar_id":"","url":"https://api.github.com/users/garious","html_url":"https://github.com/garious","followers_url":"https://api.github.com/users/garious/followers","following_url":"https://api.github.com/users/garious/following{/other_user}","gists_url":"https://api.github.com/users/garious/gists{/gist_id}","starred_url":"https://api.github.com/users/garious/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/garious/subscriptions","organizations_url":"https://api.github.com/users/garious/orgs","repos_url":"https://api.github.com/users/garious/repos","events_url":"https://api.github.com/users/garious/events{/privacy}","received_events_url":"https://api.github.com/users/garious/received_events","type":"User","site_admin":false},"body":"`page_hash`?","created_at":"2018-08-13T21:25:43Z","updated_at":"2018-08-13T21:37:21Z","html_url":"https://github.com/solana-labs/solana/pull/954#discussion_r209764705","pull_request_url":"https://api.github.com/repos/solana-labs/solana/pulls/954","author_association":"MEMBER","_links":{"self":{"href":"https://api.github.com/repos/solana-labs/solana/pulls/comments/209764705"},"html":{"href":"https://github.com/solana-labs/solana/pull/954#discussion_r209764705"},"pull_request":{"href":"https://api.github.com/repos/solana-labs/solana/pulls/954"}}},"pull_request":{"url":"https://api.github.com/repos/solana-labs/solana/pulls/954","id":207867591,"node_id":"MDExOlB1bGxSZXF1ZXN0MjA3ODY3NTkx","html_url":"https://github.com/solana-labs/solana/pull/954","diff_url":"https://github.com/solana-labs/solana/pull/954.diff","patch_url":"https://github.com/solana-labs/solana/pull/954.patch","issue_url":"https://api.github.com/repos/solana-labs/solana/issues/954","number":954,"state":"open","locked":false,"title":"Accounts with state","user":{"login":"aeyakovenko","id":1029046,"node_id":"MDQ6VXNlcjEwMjkwNDY=","avatar_url":"https://avatars0.githubusercontent.com/u/1029046?v=4","gravatar_id":"","url":"https://api.github.com/users/aeyakovenko","html_url":"https://github.com/aeyakovenko","followers_url":"https://api.github.com/users/aeyakovenko/followers","following_url":"https://api.github.com/users/aeyakovenko/following{/other_user}","gists_url":"https://api.github.com/users/aeyakovenko/gists{/gist_id}","starred_url":"https://api.github.com/users/aeyakovenko/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/aeyakovenko/subscriptions","organizations_url":"https://api.github.com/users/aeyakovenko/orgs","repos_url":"https://api.github.com/users/aeyakovenko/repos","events_url":"https://api.github.com/users/aeyakovenko/events{/privacy}","received_events_url":"https://api.github.com/users/aeyakovenko/received_events","type":"User","site_admin":false},"body":"Part 1 of #953\r\n\r\n* Add an Account type with user_data.  \r\n* Add user_data to `Transaction`. \r\n* If `Transaction` user_data is set, its written into its Account's user_data.\r\n","created_at":"2018-08-13T04:31:21Z","updated_at":"2018-08-13T21:37:21Z","closed_at":null,"merged_at":null,"merge_commit_sha":"815f4d7fd6e4efd88755c7b0fbafe876d5584c5b","assignee":null,"assignees":[],"requested_reviewers":[{"login":"mvines","id":1281082,"node_id":"MDQ6VXNlcjEyODEwODI=","avatar_url":"https://avatars1.githubusercontent.com/u/1281082?v=4","gravatar_id":"","url":"https://api.github.com/users/mvines","html_url":"https://github.com/mvines","followers_url":"https://api.github.com/users/mvines/followers","following_url":"https://api.github.com/users/mvines/following{/other_user}","gists_url":"https://api.github.com/users/mvines/gists{/gist_id}","starred_url":"https://api.github.com/users/mvines/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mvines/subscriptions","organizations_url":"https://api.github.com/users/mvines/orgs","repos_url":"https://api.github.com/users/mvines/repos","events_url":"https://api.github.com/users/mvines/events{/privacy}","received_events_url":"https://api.github.com/users/mvines/received_events","type":"User","site_admin":false},{"login":"CriesofCarrots","id":3030561,"node_id":"MDQ6VXNlcjMwMzA1NjE=","avatar_url":"https://avatars1.githubusercontent.com/u/3030561?v=4","gravatar_id":"","url":"https://api.github.com/users/CriesofCarrots","html_url":"https://github.com/CriesofCarrots","followers_url":"https://api.github.com/users/CriesofCarrots/followers","following_url":"https://api.github.com/users/CriesofCarrots/following{/other_user}","gists_url":"https://api.github.com/users/CriesofCarrots/gists{/gist_id}","starred_url":"https://api.github.com/users/CriesofCarrots/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/CriesofCarrots/subscriptions","organizations_url":"https://api.github.com/users/CriesofCarrots/orgs","repos_url":"https://api.github.com/users/CriesofCarrots/repos","events_url":"https://api.github.com/users/CriesofCarrots/events{/privacy}","received_events_url":"https://api.github.com/users/CriesofCarrots/received_events","type":"User","site_admin":false}],"requested_teams":[],"labels":[],"milestone":null,"commits_url":"https://api.github.com/repos/solana-labs/solana/pulls/954/commits","review_comments_url":"https://api.github.com/repos/solana-labs/solana/pulls/954/comments","review_comment_url":"https://api.github.com/repos/solana-labs/solana/pulls/comments{/number}","comments_url":"https://api.github.com/repos/solana-labs/solana/issues/954/comments","statuses_url":"https://api.github.com/repos/solana-labs/solana/statuses/5d1dcfa93c3c577b0abb94df560068ec86f8c70d","head":{"label":"aeyakovenko:accounts_with_state","ref":"accounts_with_state","sha":"5d1dcfa93c3c577b0abb94df560068ec86f8c70d","user":{"login":"aeyakovenko","id":1029046,"node_id":"MDQ6VXNlcjEwMjkwNDY=","avatar_url":"https://avatars0.githubusercontent.com/u/1029046?v=4","gravatar_id":"","url":"https://api.github.com/users/aeyakovenko","html_url":"https://github.com/aeyakovenko","followers_url":"https://api.github.com/users/aeyakovenko/followers","following_url":"https://api.github.com/users/aeyakovenko/following{/other_user}","gists_url":"https://api.github.com/users/aeyakovenko/gists{/gist_id}","starred_url":"https://api.github.com/users/aeyakovenko/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/aeyakovenko/subscriptions","organizations_url":"https://api.github.com/users/aeyakovenko/orgs","repos_url":"https://api.github.com/users/aeyakovenko/repos","events_url":"https://api.github.com/users/aeyakovenko/events{/privacy}","received_events_url":"https://api.github.com/users/aeyakovenko/received_events","type":"User","site_admin":false},"repo":{"id":124140461,"node_id":"MDEwOlJlcG9zaXRvcnkxMjQxNDA0NjE=","name":"solana","full_name":"aeyakovenko/solana","owner":{"login":"aeyakovenko","id":1029046,"node_id":"MDQ6VXNlcjEwMjkwNDY=","avatar_url":"https://avatars0.githubusercontent.com/u/1029046?v=4","gravatar_id":"","url":"https://api.github.com/users/aeyakovenko","html_url":"https://github.com/aeyakovenko","followers_url":"https://api.github.com/users/aeyakovenko/followers","following_url":"https://api.github.com/users/aeyakovenko/following{/other_user}","gists_url":"https://api.github.com/users/aeyakovenko/gists{/gist_id}","starred_url":"https://api.github.com/users/aeyakovenko/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/aeyakovenko/subscriptions","organizations_url":"https://api.github.com/users/aeyakovenko/orgs","repos_url":"https://api.github.com/users/aeyakovenko/repos","events_url":"https://api.github.com/users/aeyakovenko/events{/privacy}","received_events_url":"https://api.github.com/users/aeyakovenko/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/aeyakovenko/solana","description":"a high performance blockchain","fork":true,"url":"https://api.github.com/repos/aeyakovenko/solana","forks_url":"https://api.github.com/repos/aeyakovenko/solana/forks","keys_url":"https://api.github.com/repos/aeyakovenko/solana/keys{/key_id}","collaborators_url":"https://api.github.com/repos/aeyakovenko/solana/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/aeyakovenko/solana/teams","hooks_url":"https://api.github.com/repos/aeyakovenko/solana/hooks","issue_events_url":"https://api.github.com/repos/aeyakovenko/solana/issues/events{/number}","events_url":"https://api.github.com/repos/aeyakovenko/solana/events","assignees_url":"https://api.github.com/repos/aeyakovenko/solana/assignees{/user}","branches_url":"https://api.github.com/repos/aeyakovenko/solana/branches{/branch}","tags_url":"https://api.github.com/repos/aeyakovenko/solana/tags","blobs_url":"https://api.github.com/repos/aeyakovenko/solana/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/aeyakovenko/solana/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/aeyakovenko/solana/git/refs{/sha}","trees_url":"https://api.github.com/repos/aeyakovenko/solana/git/trees{/sha}","statuses_url":"https://api.github.com/repos/aeyakovenko/solana/statuses/{sha}","languages_url":"https://api.github.com/repos/aeyakovenko/solana/languages","stargazers_url":"https://api.github.com/repos/aeyakovenko/solana/stargazers","contributors_url":"https://api.github.com/repos/aeyakovenko/solana/contributors","subscribers_url":"https://api.github.com/repos/aeyakovenko/solana/subscribers","subscription_url":"https://api.github.com/repos/aeyakovenko/solana/subscription","commits_url":"https://api.github.com/repos/aeyakovenko/solana/commits{/sha}","git_commits_url":"https://api.github.com/repos/aeyakovenko/solana/git/commits{/sha}","comments_url":"https://api.github.com/repos/aeyakovenko/solana/comments{/number}","issue_comment_url":"https://api.github.com/repos/aeyakovenko/solana/issues/comments{/number}","contents_url":"https://api.github.com/repos/aeyakovenko/solana/contents/{+path}","compare_url":"https://api.github.com/repos/aeyakovenko/solana/compare/{base}...{head}","merges_url":"https://api.github.com/repos/aeyakovenko/solana/merges","archive_url":"https://api.github.com/repos/aeyakovenko/solana/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/aeyakovenko/solana/downloads","issues_url":"https://api.github.com/repos/aeyakovenko/solana/issues{/number}","pulls_url":"https://api.github.com/repos/aeyakovenko/solana/pulls{/number}","milestones_url":"https://api.github.com/repos/aeyakovenko/solana/milestones{/number}","notifications_url":"https://api.github.com/repos/aeyakovenko/solana/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/aeyakovenko/solana/labels{/name}","releases_url":"https://api.github.com/repos/aeyakovenko/solana/releases{/id}","deployments_url":"https://api.github.com/repos/aeyakovenko/solana/deployments","created_at":"2018-03-06T21:24:10Z","updated_at":"2018-08-13T04:40:05Z","pushed_at":"2018-08-13T05:20:07Z","git_url":"git://github.com/aeyakovenko/solana.git","ssh_url":"git@github.com:aeyakovenko/solana.git","clone_url":"https://github.com/aeyakovenko/solana.git","svn_url":"https://github.com/aeyakovenko/solana","homepage":"https://solana.com","size":10737,"stargazers_count":0,"watchers_count":0,"language":"Rust","has_issues":false,"has_projects":true,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":0,"mirror_url":null,"archived":false,"open_issues_count":0,"license":{"key":"other","name":"Other","spdx_id":null,"url":null,"node_id":"MDc6TGljZW5zZTA="},"forks":0,"open_issues":0,"watchers":0,"default_branch":"master"}},"base":{"label":"solana-labs:master","ref":"master","sha":"288ed7a8ea161dbe88ce10dff23e221b30a3b787","user":{"login":"solana-labs","id":35608259,"node_id":"MDEyOk9yZ2FuaXphdGlvbjM1NjA4MjU5","avatar_url":"https://avatars3.githubusercontent.com/u/35608259?v=4","gravatar_id":"","url":"https://api.github.com/users/solana-labs","html_url":"https://github.com/solana-labs","followers_url":"https://api.github.com/users/solana-labs/followers","following_url":"https://api.github.com/users/solana-labs/following{/other_user}","gists_url":"https://api.github.com/users/solana-labs/gists{/gist_id}","starred_url":"https://api.github.com/users/solana-labs/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/solana-labs/subscriptions","organizations_url":"https://api.github.com/users/solana-labs/orgs","repos_url":"https://api.github.com/users/solana-labs/repos","events_url":"https://api.github.com/users/solana-labs/events{/privacy}","received_events_url":"https://api.github.com/users/solana-labs/received_events","type":"Organization","site_admin":false},"repo":{"id":121470383,"node_id":"MDEwOlJlcG9zaXRvcnkxMjE0NzAzODM=","name":"solana","full_name":"solana-labs/solana","owner":{"login":"solana-labs","id":35608259,"node_id":"MDEyOk9yZ2FuaXphdGlvbjM1NjA4MjU5","avatar_url":"https://avatars3.githubusercontent.com/u/35608259?v=4","gravatar_id":"","url":"https://api.github.com/users/solana-labs","html_url":"https://github.com/solana-labs","followers_url":"https://api.github.com/users/solana-labs/followers","following_url":"https://api.github.com/users/solana-labs/following{/other_user}","gists_url":"https://api.github.com/users/solana-labs/gists{/gist_id}","starred_url":"https://api.github.com/users/solana-labs/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/solana-labs/subscriptions","organizations_url":"https://api.github.com/users/solana-labs/orgs","repos_url":"https://api.github.com/users/solana-labs/repos","events_url":"https://api.github.com/users/solana-labs/events{/privacy}","received_events_url":"https://api.github.com/users/solana-labs/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/solana-labs/solana","description":"Blockchain, Rebuilt for Scale","fork":false,"url":"https://api.github.com/repos/solana-labs/solana","forks_url":"https://api.github.com/repos/solana-labs/solana/forks","keys_url":"https://api.github.com/repos/solana-labs/solana/keys{/key_id}","collaborators_url":"https://api.github.com/repos/solana-labs/solana/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/solana-labs/solana/teams","hooks_url":"https://api.github.com/repos/solana-labs/solana/hooks","issue_events_url":"https://api.github.com/repos/solana-labs/solana/issues/events{/number}","events_url":"https://api.github.com/repos/solana-labs/solana/events","assignees_url":"https://api.github.com/repos/solana-labs/solana/assignees{/user}","branches_url":"https://api.github.com/repos/solana-labs/solana/branches{/branch}","tags_url":"https://api.github.com/repos/solana-labs/solana/tags","blobs_url":"https://api.github.com/repos/solana-labs/solana/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/solana-labs/solana/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/solana-labs/solana/git/refs{/sha}","trees_url":"https://api.github.com/repos/solana-labs/solana/git/trees{/sha}","statuses_url":"https://api.github.com/repos/solana-labs/solana/statuses/{sha}","languages_url":"https://api.github.com/repos/solana-labs/solana/languages","stargazers_url":"https://api.github.com/repos/solana-labs/solana/stargazers","contributors_url":"https://api.github.com/repos/solana-labs/solana/contributors","subscribers_url":"https://api.github.com/repos/solana-labs/solana/subscribers","subscription_url":"https://api.github.com/repos/solana-labs/solana/subscription","commits_url":"https://api.github.com/repos/solana-labs/solana/commits{/sha}","git_commits_url":"https://api.github.com/repos/solana-labs/solana/git/commits{/sha}","comments_url":"https://api.github.com/repos/solana-labs/solana/comments{/number}","issue_comment_url":"https://api.github.com/repos/solana-labs/solana/issues/comments{/number}","contents_url":"https://api.github.com/repos/solana-labs/solana/contents/{+path}","compare_url":"https://api.github.com/repos/solana-labs/solana/compare/{base}...{head}","merges_url":"https://api.github.com/repos/solana-labs/solana/merges","archive_url":"https://api.github.com/repos/solana-labs/solana/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/solana-labs/solana/downloads","issues_url":"https://api.github.com/repos/solana-labs/solana/issues{/number}","pulls_url":"https://api.github.com/repos/solana-labs/solana/pulls{/number}","milestones_url":"https://api.github.com/repos/solana-labs/solana/milestones{/number}","notifications_url":"https://api.github.com/repos/solana-labs/solana/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/solana-labs/solana/labels{/name}","releases_url":"https://api.github.com/repos/solana-labs/solana/releases{/id}","deployments_url":"https://api.github.com/repos/solana-labs/solana/deployments","created_at":"2018-02-14T04:26:27Z","updated_at":"2018-08-13T19:44:33Z","pushed_at":"2018-08-13T21:23:48Z","git_url":"git://github.com/solana-labs/solana.git","ssh_url":"git@github.com:solana-labs/solana.git","clone_url":"https://github.com/solana-labs/solana.git","svn_url":"https://github.com/solana-labs/solana","homepage":"https://solana.com","size":10262,"stargazers_count":303,"watchers_count":303,"language":"Rust","has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":false,"has_pages":true,"forks_count":50,"mirror_url":null,"archived":false,"open_issues_count":94,"license":{"key":"other","name":"Other","spdx_id":null,"url":null,"node_id":"MDc6TGljZW5zZTA="},"forks":50,"open_issues":94,"watchers":303,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/solana-labs/solana/pulls/954"},"html":{"href":"https://github.com/solana-labs/solana/pull/954"},"issue":{"href":"https://api.github.com/repos/solana-labs/solana/issues/954"},"comments":{"href":"https://api.github.com/repos/solana-labs/solana/issues/954/comments"},"review_comments":{"href":"https://api.github.com/repos/solana-labs/solana/pulls/954/comments"},"review_comment":{"href":"https://api.github.com/repos/solana-labs/solana/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/solana-labs/solana/pulls/954/commits"},"statuses":{"href":"https://api.github.com/repos/solana-labs/solana/statuses/5d1dcfa93c3c577b0abb94df560068ec86f8c70d"}},"author_association":"MEMBER"}}
{"actor":{"display_login":"garious"}}