{"action":"created","comment":{"url":"https://api.github.com/repos/dedis/cothority/pulls/comments/77492475","id":77492475,"diff_hunk":"@@ -0,0 +1,459 @@\n+package network\n+\n+import (\n+\t\"errors\"\n+\t\"fmt\"\n+\t\"golang.org/x/net/context\"\n+\t\"reflect\"\n+\t\"sync\"\n+\t\"time\"\n+)\n+\n+// NewLocalRouter returns a fresh router which uses local connections. It takes\n+// the default context.\n+func NewLocalRouter(sid *ServerIdentity) (*Router, error) {\n+\treturn NewLocalRouterWithContext(defaultLocalContext, sid)\n+}\n+\n+// NewLocalRouterWithContext is the same as NewLocalRouter but takes a specific\n+// LocalContext. This is useful to run parallel different local overlays.\n+func NewLocalRouterWithContext(ctx *LocalContext, sid *ServerIdentity) (*Router, error) {\n+\th, err := NewLocalHostWithContext(ctx, sid.Address)\n+\tif err != nil {\n+\t\treturn nil, err\n+\t}\n+\treturn NewRouter(sid, h), nil\n+}\n+\n+// LocalContext keeps reference to all opened local connections\n+// It also keeps tracks of who is \"listening\", so it's possible to mimics\n+// Conn & Listener.\n+type LocalContext struct {\n+\t// queues maps a remote endpoint to its packet queue. It's the main\n+\t//stucture used to communicate.\n+\tqueues map[endpoint]*connQueue\n+\tsync.Mutex\n+\tlistening map[Address]func(Conn)\n+\n+\tbaseUID uint64\n+}\n+\n+// NewLocalContext returns a fresh new context that can be used by LocalConn,\n+// LocalListener & LocalHost.\n+func NewLocalContext() *LocalContext {\n+\treturn &LocalContext{\n+\t\tqueues:    make(map[endpoint]*connQueue),\n+\t\tlistening: make(map[Address]func(Conn)),\n+\t}\n+}\n+\n+var defaultLocalContext = NewLocalContext()\n+\n+// endpoint represents one endpoint of a connection.\n+type endpoint struct {\n+\taddr Address\n+\t// uid is a unique identifier of the remote endpoint\n+\t// it's unique  for each direction:\n+\t// 127.0.0.1:2000 -> 127.0.0.1:2000 => 14\n+\t// 127.0.0.1:2000 <- 127.0.0.1:2000 => 15\n+\tuid uint64\n+}\n+\n+// LocalReset reset the whole map of connections + listener so it is like\n+// a fresh defaultLocalContext.\n+func LocalReset() {\n+\tdefaultLocalContext = NewLocalContext()\n+\n+}\n+\n+// IsListening returns true if the remote address is listening \"virtually\"\n+func (ccc *LocalContext) IsListening(remote Address) bool {\n+\tccc.Lock()\n+\tdefer ccc.Unlock()\n+\t_, ok := ccc.listening[remote]\n+\treturn ok\n+}\n+\n+// Listening put the address as \"listening\" mode. If a user connects to this\n+// addr, this function will be called.\n+func (ccc *LocalContext) Listening(addr Address, fn func(Conn)) {\n+\tccc.Lock()\n+\tdefer ccc.Unlock()\n+\tccc.listening[addr] = fn\n+}\n+\n+// StopListening remove the address from the \"listening\" mode\n+func (ccc *LocalContext) StopListening(addr Address) {\n+\tccc.Lock()\n+\tdefer ccc.Unlock()\n+\tdelete(ccc.listening, addr)\n+}\n+\n+// Connect will check if the remote address is listening, if yes it creates\n+// the two connections, and launch the listening function in a go routine.\n+// It returns the outgoing connection with any error.\n+func (ccc *LocalContext) Connect(local, remote Address) (*LocalConn, error) {\n+\tccc.Lock()\n+\tdefer ccc.Unlock()\n+\n+\tfn, ok := ccc.listening[remote]\n+\tif !ok {\n+\t\treturn nil, fmt.Errorf(\"%s can't connect to %s: it's not listening\", local, remote)\n+\t}\n+\n+\toutEndpoint := endpoint{local, ccc.baseUID}\n+\tccc.baseUID++\n+\n+\tincEndpoint := endpoint{remote, ccc.baseUID}\n+\tccc.baseUID++\n+\n+\toutgoing := newLocalConn(ccc, outEndpoint, incEndpoint)\n+\tincoming := newLocalConn(ccc, incEndpoint, outEndpoint)\n+\n+\t// outgoing knows how to store packet into the incoming's queue\n+\tccc.queues[outEndpoint] = outgoing.connQueue\n+\t// incoming knows how to store packet into the outgoing's queue\n+\tccc.queues[incEndpoint] = incoming.connQueue\n+\n+\tgo fn(incoming)\n+\treturn outgoing, nil\n+}\n+\n+// Send will get the connection denoted by this endpoint and will call queueMsg\n+// with the packet as argument on it. It returns ErrClosed if it does not find\n+// the connection.\n+func (ccc *LocalContext) Send(e endpoint, nm Packet) error {\n+\tccc.Lock()\n+\tdefer ccc.Unlock()\n+\tq, ok := ccc.queues[e]\n+\tif !ok {\n+\t\treturn ErrClosed\n+\t}\n+\n+\tq.Push(nm)\n+\treturn nil\n+}\n+\n+// Close will get the connection denoted by this endpoint and will Close it if\n+// present.\n+func (ccc *LocalContext) Close(conn *LocalConn) {\n+\tccc.Lock()\n+\tdefer ccc.Unlock()\n+\t// delete this conn\n+\tdelete(ccc.queues, conn.local)\n+\t// and delete the remote one + close it\n+\tremote, ok := ccc.queues[conn.remote]\n+\tif !ok {\n+\t\treturn\n+\t}\n+\tdelete(ccc.queues, conn.remote)\n+\tremote.Close()\n+}\n+\n+// Len returns how many local connections is there\n+func (ccc *LocalContext) Len() int {\n+\tccc.Lock()\n+\tdefer ccc.Unlock()\n+\treturn len(ccc.queues)\n+}\n+\n+// LocalConn is a connection that send and receive messages through channels\n+type LocalConn struct {\n+\tlocal  endpoint\n+\tremote endpoint\n+\n+\t// connQueue is the part that is accesible from the LocalContext (i.e. is\n+\t// shared). Reason why we can't directly share LocalConn is because go test\n+\t// -race detects as data race (while it's *protected*)\n+\t*connQueue\n+\n+\tctx *LocalContext\n+}\n+\n+// newLocalConn simply init the fields of a LocalConn but do not try to\n+// connect. It should not be used as-is, most user wants to call NewLocalConn.\n+func newLocalConn(ctx *LocalContext, local, remote endpoint) *LocalConn {\n+\treturn &LocalConn{\n+\t\tremote:    remote,\n+\t\tlocal:     local,\n+\t\tconnQueue: newConnQueue(),\n+\t\tctx:       ctx,\n+\t}\n+}\n+\n+// NewLocalConn returns a new channel connection from local to remote\n+// Mimics the behavior of NewTCPConn => tries connecting right away.\n+// It uses the default local context.\n+func NewLocalConn(local, remote Address) (*LocalConn, error) {\n+\treturn NewLocalConnWithContext(defaultLocalContext, local, remote)\n+}\n+\n+// NewLocalConnWithContext is similar to NewLocalConn but takes a specific\n+// LocalContext.\n+func NewLocalConnWithContext(ctx *LocalContext, local, remote Address) (*LocalConn, error) {\n+\treturn ctx.Connect(local, remote)\n+}\n+\n+// Send implements the Conn interface.\n+func (cc LocalConn) Send(ctx context.Context, msg Body) error {\n+\n+\tvar body Body\n+\tvar val = reflect.ValueOf(msg)\n+\tif val.Kind() == reflect.Ptr {\n+\t\tval = val.Elem()\n+\t}\n+\tbody = val.Interface()\n+\n+\tvar typ = TypeFromData(body)\n+\tnm := Packet{\n+\t\tMsgType: typ,\n+\t\tMsg:     body,\n+\t}\n+\treturn cc.ctx.Send(cc.remote, nm)\n+}\n+\n+// Receive implements the Conn interface.\n+func (cc *LocalConn) Receive(ctx context.Context) (Packet, error) {\n+\treturn cc.Pop()\n+}\n+\n+// Local implements the Conn interface\n+func (cc *LocalConn) Local() Address {\n+\treturn cc.local.addr\n+}\n+\n+// Remote implements the Conn interface\n+func (cc *LocalConn) Remote() Address {\n+\treturn cc.remote.addr\n+}\n+\n+// Close implements the Conn interface\n+func (cc *LocalConn) Close() error {\n+\tcc.connQueue.Close()\n+\t// close the remote conn also\n+\tcc.ctx.Close(cc)\n+\treturn nil\n+}\n+\n+// Rx implements the Conn interface\n+func (cc *LocalConn) Rx() uint64 {\n+\treturn 0\n+}\n+\n+// Tx implements the Conn interface\n+func (cc *LocalConn) Tx() uint64 {\n+\treturn 0\n+}\n+\n+// Type implements the Conn interface\n+func (cc *LocalConn) Type() ConnType {\n+\treturn Local\n+}\n+\n+type connQueue struct {\n+\t*sync.Cond\n+\tqueue    []Packet\n+\tisClosed bool\n+}\n+\n+func newConnQueue() *connQueue {\n+\treturn &connQueue{\n+\t\tCond: sync.NewCond(&sync.Mutex{}),\n+\t}\n+}\n+\n+func (c *connQueue) Push(p Packet) {\n+\tc.L.Lock()\n+\tdefer c.L.Unlock()\n+\tif c.isClosed {\n+\t\treturn\n+\t}\n+\tc.queue = append(c.queue, p)\n+\tc.Signal()\n+}\n+\n+func (c *connQueue) Pop() (Packet, error) {\n+\tc.L.Lock()\n+\tdefer c.L.Unlock()\n+\tfor len(c.queue) == 0 {\n+\t\tif c.isClosed {\n+\t\t\treturn EmptyApplicationPacket, ErrClosed\n+\t\t}\n+\t\tc.Wait()\n+\t}\n+\tif c.isClosed {\n+\t\treturn EmptyApplicationPacket, ErrClosed\n+\t}\n+\tnm := c.queue[0]\n+\tc.queue = c.queue[1:]\n+\treturn nm, nil\n+}\n+\n+func (c *connQueue) Close() {\n+\tc.L.Lock()\n+\tdefer c.L.Unlock()\n+\tc.isClosed = true\n+\tc.Signal()\n+}\n+\n+// LocalListener is a Listener that uses LocalConn to communicate. It tries to\n+// behave as much as possible as a real golang net.Listener but using LocalConn\n+// as the underlying communication layer.\n+type LocalListener struct {\n+\t// addr is the addr we're listening to + mut","path":"network/local.go","position":303,"original_position":303,"commit_id":"86357eeaf02445c8532833b973faeb506905a233","original_commit_id":"86357eeaf02445c8532833b973faeb506905a233","user":{"login":"ineiti","id":1545067,"avatar_url":"https://avatars.githubusercontent.com/u/1545067?v=3","gravatar_id":"","url":"https://api.github.com/users/ineiti","html_url":"https://github.com/ineiti","followers_url":"https://api.github.com/users/ineiti/followers","following_url":"https://api.github.com/users/ineiti/following{/other_user}","gists_url":"https://api.github.com/users/ineiti/gists{/gist_id}","starred_url":"https://api.github.com/users/ineiti/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ineiti/subscriptions","organizations_url":"https://api.github.com/users/ineiti/orgs","repos_url":"https://api.github.com/users/ineiti/repos","events_url":"https://api.github.com/users/ineiti/events{/privacy}","received_events_url":"https://api.github.com/users/ineiti/received_events","type":"User","site_admin":false},"body":"What is `mut` here?","created_at":"2016-09-05T09:18:56Z","updated_at":"2016-09-05T09:18:56Z","html_url":"https://github.com/dedis/cothority/pull/568#discussion_r77492475","pull_request_url":"https://api.github.com/repos/dedis/cothority/pulls/568","_links":{"self":{"href":"https://api.github.com/repos/dedis/cothority/pulls/comments/77492475"},"html":{"href":"https://github.com/dedis/cothority/pull/568#discussion_r77492475"},"pull_request":{"href":"https://api.github.com/repos/dedis/cothority/pulls/568"}}},"pull_request":{"url":"https://api.github.com/repos/dedis/cothority/pulls/568","id":83767460,"html_url":"https://github.com/dedis/cothority/pull/568","diff_url":"https://github.com/dedis/cothority/pull/568.diff","patch_url":"https://github.com/dedis/cothority/pull/568.patch","issue_url":"https://api.github.com/repos/dedis/cothority/issues/568","number":568,"state":"open","locked":false,"title":"[2/7] Refactor network - interfaces + Local network","user":{"login":"nikkolasg","id":2564747,"avatar_url":"https://avatars.githubusercontent.com/u/2564747?v=3","gravatar_id":"","url":"https://api.github.com/users/nikkolasg","html_url":"https://github.com/nikkolasg","followers_url":"https://api.github.com/users/nikkolasg/followers","following_url":"https://api.github.com/users/nikkolasg/following{/other_user}","gists_url":"https://api.github.com/users/nikkolasg/gists{/gist_id}","starred_url":"https://api.github.com/users/nikkolasg/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/nikkolasg/subscriptions","organizations_url":"https://api.github.com/users/nikkolasg/orgs","repos_url":"https://api.github.com/users/nikkolasg/repos","events_url":"https://api.github.com/users/nikkolasg/events{/privacy}","received_events_url":"https://api.github.com/users/nikkolasg/received_events","type":"User","site_admin":false},"body":"This PR implements the local communication part using signaling and queues..\r\nThis PR comes with the basic interface definitions which are used throughout the network library such as `Conn`, `Listener`  & `Host`","created_at":"2016-09-02T09:01:27Z","updated_at":"2016-09-05T09:18:56Z","closed_at":null,"merged_at":null,"merge_commit_sha":"eb0c2af6dc182b599aa92a26c44ad9c9d7f19333","assignee":{"login":"nikkolasg","id":2564747,"avatar_url":"https://avatars.githubusercontent.com/u/2564747?v=3","gravatar_id":"","url":"https://api.github.com/users/nikkolasg","html_url":"https://github.com/nikkolasg","followers_url":"https://api.github.com/users/nikkolasg/followers","following_url":"https://api.github.com/users/nikkolasg/following{/other_user}","gists_url":"https://api.github.com/users/nikkolasg/gists{/gist_id}","starred_url":"https://api.github.com/users/nikkolasg/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/nikkolasg/subscriptions","organizations_url":"https://api.github.com/users/nikkolasg/orgs","repos_url":"https://api.github.com/users/nikkolasg/repos","events_url":"https://api.github.com/users/nikkolasg/events{/privacy}","received_events_url":"https://api.github.com/users/nikkolasg/received_events","type":"User","site_admin":false},"assignees":[{"login":"nikkolasg","id":2564747,"avatar_url":"https://avatars.githubusercontent.com/u/2564747?v=3","gravatar_id":"","url":"https://api.github.com/users/nikkolasg","html_url":"https://github.com/nikkolasg","followers_url":"https://api.github.com/users/nikkolasg/followers","following_url":"https://api.github.com/users/nikkolasg/following{/other_user}","gists_url":"https://api.github.com/users/nikkolasg/gists{/gist_id}","starred_url":"https://api.github.com/users/nikkolasg/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/nikkolasg/subscriptions","organizations_url":"https://api.github.com/users/nikkolasg/orgs","repos_url":"https://api.github.com/users/nikkolasg/repos","events_url":"https://api.github.com/users/nikkolasg/events{/privacy}","received_events_url":"https://api.github.com/users/nikkolasg/received_events","type":"User","site_admin":false}],"milestone":null,"commits_url":"https://api.github.com/repos/dedis/cothority/pulls/568/commits","review_comments_url":"https://api.github.com/repos/dedis/cothority/pulls/568/comments","review_comment_url":"https://api.github.com/repos/dedis/cothority/pulls/comments{/number}","comments_url":"https://api.github.com/repos/dedis/cothority/issues/568/comments","statuses_url":"https://api.github.com/repos/dedis/cothority/statuses/86357eeaf02445c8532833b973faeb506905a233","head":{"label":"dedis:refactor_mocking_local","ref":"refactor_mocking_local","sha":"86357eeaf02445c8532833b973faeb506905a233","user":{"login":"dedis","id":3638331,"avatar_url":"https://avatars.githubusercontent.com/u/3638331?v=3","gravatar_id":"","url":"https://api.github.com/users/dedis","html_url":"https://github.com/dedis","followers_url":"https://api.github.com/users/dedis/followers","following_url":"https://api.github.com/users/dedis/following{/other_user}","gists_url":"https://api.github.com/users/dedis/gists{/gist_id}","starred_url":"https://api.github.com/users/dedis/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/dedis/subscriptions","organizations_url":"https://api.github.com/users/dedis/orgs","repos_url":"https://api.github.com/users/dedis/repos","events_url":"https://api.github.com/users/dedis/events{/privacy}","received_events_url":"https://api.github.com/users/dedis/received_events","type":"Organization","site_admin":false},"repo":{"id":41791684,"name":"cothority","full_name":"dedis/cothority","owner":{"login":"dedis","id":3638331,"avatar_url":"https://avatars.githubusercontent.com/u/3638331?v=3","gravatar_id":"","url":"https://api.github.com/users/dedis","html_url":"https://github.com/dedis","followers_url":"https://api.github.com/users/dedis/followers","following_url":"https://api.github.com/users/dedis/following{/other_user}","gists_url":"https://api.github.com/users/dedis/gists{/gist_id}","starred_url":"https://api.github.com/users/dedis/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/dedis/subscriptions","organizations_url":"https://api.github.com/users/dedis/orgs","repos_url":"https://api.github.com/users/dedis/repos","events_url":"https://api.github.com/users/dedis/events{/privacy}","received_events_url":"https://api.github.com/users/dedis/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/dedis/cothority","description":"Scalable collective authority prototype","fork":false,"url":"https://api.github.com/repos/dedis/cothority","forks_url":"https://api.github.com/repos/dedis/cothority/forks","keys_url":"https://api.github.com/repos/dedis/cothority/keys{/key_id}","collaborators_url":"https://api.github.com/repos/dedis/cothority/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/dedis/cothority/teams","hooks_url":"https://api.github.com/repos/dedis/cothority/hooks","issue_events_url":"https://api.github.com/repos/dedis/cothority/issues/events{/number}","events_url":"https://api.github.com/repos/dedis/cothority/events","assignees_url":"https://api.github.com/repos/dedis/cothority/assignees{/user}","branches_url":"https://api.github.com/repos/dedis/cothority/branches{/branch}","tags_url":"https://api.github.com/repos/dedis/cothority/tags","blobs_url":"https://api.github.com/repos/dedis/cothority/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/dedis/cothority/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/dedis/cothority/git/refs{/sha}","trees_url":"https://api.github.com/repos/dedis/cothority/git/trees{/sha}","statuses_url":"https://api.github.com/repos/dedis/cothority/statuses/{sha}","languages_url":"https://api.github.com/repos/dedis/cothority/languages","stargazers_url":"https://api.github.com/repos/dedis/cothority/stargazers","contributors_url":"https://api.github.com/repos/dedis/cothority/contributors","subscribers_url":"https://api.github.com/repos/dedis/cothority/subscribers","subscription_url":"https://api.github.com/repos/dedis/cothority/subscription","commits_url":"https://api.github.com/repos/dedis/cothority/commits{/sha}","git_commits_url":"https://api.github.com/repos/dedis/cothority/git/commits{/sha}","comments_url":"https://api.github.com/repos/dedis/cothority/comments{/number}","issue_comment_url":"https://api.github.com/repos/dedis/cothority/issues/comments{/number}","contents_url":"https://api.github.com/repos/dedis/cothority/contents/{+path}","compare_url":"https://api.github.com/repos/dedis/cothority/compare/{base}...{head}","merges_url":"https://api.github.com/repos/dedis/cothority/merges","archive_url":"https://api.github.com/repos/dedis/cothority/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/dedis/cothority/downloads","issues_url":"https://api.github.com/repos/dedis/cothority/issues{/number}","pulls_url":"https://api.github.com/repos/dedis/cothority/pulls{/number}","milestones_url":"https://api.github.com/repos/dedis/cothority/milestones{/number}","notifications_url":"https://api.github.com/repos/dedis/cothority/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/dedis/cothority/labels{/name}","releases_url":"https://api.github.com/repos/dedis/cothority/releases{/id}","deployments_url":"https://api.github.com/repos/dedis/cothority/deployments","created_at":"2015-09-02T09:13:57Z","updated_at":"2016-08-29T00:58:40Z","pushed_at":"2016-09-05T09:07:20Z","git_url":"git://github.com/dedis/cothority.git","ssh_url":"git@github.com:dedis/cothority.git","clone_url":"https://github.com/dedis/cothority.git","svn_url":"https://github.com/dedis/cothority","homepage":"","size":59959,"stargazers_count":113,"watchers_count":113,"language":"Go","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":11,"mirror_url":null,"open_issues_count":95,"forks":11,"open_issues":95,"watchers":113,"default_branch":"master"}},"base":{"label":"dedis:refactor_mocking_address","ref":"refactor_mocking_address","sha":"1b4ca0968b1c71df0eb698f299da913e7047427c","user":{"login":"dedis","id":3638331,"avatar_url":"https://avatars.githubusercontent.com/u/3638331?v=3","gravatar_id":"","url":"https://api.github.com/users/dedis","html_url":"https://github.com/dedis","followers_url":"https://api.github.com/users/dedis/followers","following_url":"https://api.github.com/users/dedis/following{/other_user}","gists_url":"https://api.github.com/users/dedis/gists{/gist_id}","starred_url":"https://api.github.com/users/dedis/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/dedis/subscriptions","organizations_url":"https://api.github.com/users/dedis/orgs","repos_url":"https://api.github.com/users/dedis/repos","events_url":"https://api.github.com/users/dedis/events{/privacy}","received_events_url":"https://api.github.com/users/dedis/received_events","type":"Organization","site_admin":false},"repo":{"id":41791684,"name":"cothority","full_name":"dedis/cothority","owner":{"login":"dedis","id":3638331,"avatar_url":"https://avatars.githubusercontent.com/u/3638331?v=3","gravatar_id":"","url":"https://api.github.com/users/dedis","html_url":"https://github.com/dedis","followers_url":"https://api.github.com/users/dedis/followers","following_url":"https://api.github.com/users/dedis/following{/other_user}","gists_url":"https://api.github.com/users/dedis/gists{/gist_id}","starred_url":"https://api.github.com/users/dedis/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/dedis/subscriptions","organizations_url":"https://api.github.com/users/dedis/orgs","repos_url":"https://api.github.com/users/dedis/repos","events_url":"https://api.github.com/users/dedis/events{/privacy}","received_events_url":"https://api.github.com/users/dedis/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/dedis/cothority","description":"Scalable collective authority prototype","fork":false,"url":"https://api.github.com/repos/dedis/cothority","forks_url":"https://api.github.com/repos/dedis/cothority/forks","keys_url":"https://api.github.com/repos/dedis/cothority/keys{/key_id}","collaborators_url":"https://api.github.com/repos/dedis/cothority/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/dedis/cothority/teams","hooks_url":"https://api.github.com/repos/dedis/cothority/hooks","issue_events_url":"https://api.github.com/repos/dedis/cothority/issues/events{/number}","events_url":"https://api.github.com/repos/dedis/cothority/events","assignees_url":"https://api.github.com/repos/dedis/cothority/assignees{/user}","branches_url":"https://api.github.com/repos/dedis/cothority/branches{/branch}","tags_url":"https://api.github.com/repos/dedis/cothority/tags","blobs_url":"https://api.github.com/repos/dedis/cothority/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/dedis/cothority/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/dedis/cothority/git/refs{/sha}","trees_url":"https://api.github.com/repos/dedis/cothority/git/trees{/sha}","statuses_url":"https://api.github.com/repos/dedis/cothority/statuses/{sha}","languages_url":"https://api.github.com/repos/dedis/cothority/languages","stargazers_url":"https://api.github.com/repos/dedis/cothority/stargazers","contributors_url":"https://api.github.com/repos/dedis/cothority/contributors","subscribers_url":"https://api.github.com/repos/dedis/cothority/subscribers","subscription_url":"https://api.github.com/repos/dedis/cothority/subscription","commits_url":"https://api.github.com/repos/dedis/cothority/commits{/sha}","git_commits_url":"https://api.github.com/repos/dedis/cothority/git/commits{/sha}","comments_url":"https://api.github.com/repos/dedis/cothority/comments{/number}","issue_comment_url":"https://api.github.com/repos/dedis/cothority/issues/comments{/number}","contents_url":"https://api.github.com/repos/dedis/cothority/contents/{+path}","compare_url":"https://api.github.com/repos/dedis/cothority/compare/{base}...{head}","merges_url":"https://api.github.com/repos/dedis/cothority/merges","archive_url":"https://api.github.com/repos/dedis/cothority/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/dedis/cothority/downloads","issues_url":"https://api.github.com/repos/dedis/cothority/issues{/number}","pulls_url":"https://api.github.com/repos/dedis/cothority/pulls{/number}","milestones_url":"https://api.github.com/repos/dedis/cothority/milestones{/number}","notifications_url":"https://api.github.com/repos/dedis/cothority/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/dedis/cothority/labels{/name}","releases_url":"https://api.github.com/repos/dedis/cothority/releases{/id}","deployments_url":"https://api.github.com/repos/dedis/cothority/deployments","created_at":"2015-09-02T09:13:57Z","updated_at":"2016-08-29T00:58:40Z","pushed_at":"2016-09-05T09:07:20Z","git_url":"git://github.com/dedis/cothority.git","ssh_url":"git@github.com:dedis/cothority.git","clone_url":"https://github.com/dedis/cothority.git","svn_url":"https://github.com/dedis/cothority","homepage":"","size":59959,"stargazers_count":113,"watchers_count":113,"language":"Go","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":11,"mirror_url":null,"open_issues_count":95,"forks":11,"open_issues":95,"watchers":113,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/dedis/cothority/pulls/568"},"html":{"href":"https://github.com/dedis/cothority/pull/568"},"issue":{"href":"https://api.github.com/repos/dedis/cothority/issues/568"},"comments":{"href":"https://api.github.com/repos/dedis/cothority/issues/568/comments"},"review_comments":{"href":"https://api.github.com/repos/dedis/cothority/pulls/568/comments"},"review_comment":{"href":"https://api.github.com/repos/dedis/cothority/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/dedis/cothority/pulls/568/commits"},"statuses":{"href":"https://api.github.com/repos/dedis/cothority/statuses/86357eeaf02445c8532833b973faeb506905a233"}}}}
{"actor":{"display_login":"ineiti"}}