Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Helloobelisk #4

Open
wants to merge 39 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
850f559
fix the daemon
Apr 14, 2014
d3b26c7
Merge remote-tracking branch 'upstream/master'
May 8, 2014
e69ada6
reoranize to run with libs
May 8, 2014
1679d9a
make works with lib
May 8, 2014
0aa0b33
ignore ctags
May 8, 2014
1fc632e
fix documentation
May 8, 2014
6c51501
reorganize code
May 8, 2014
4c5af97
dont hide the exception
May 8, 2014
ffadf46
return the main ioloop running
May 8, 2014
3800aa2
decode b58 needs a second params set None for bypass checking
May 8, 2014
2872281
try to fetch address
May 8, 2014
a21df86
try rest
May 8, 2014
7a0d99e
update gw
May 8, 2014
4e879cf
this run
May 9, 2014
001f04f
reorganize code
May 14, 2014
6e2b038
Merge remote-tracking branch 'upstream/master' into helloobelisk
May 15, 2014
82760be
reorganize libs
May 15, 2014
501de36
adding height
May 15, 2014
ccd0d02
reformat the response base object
May 15, 2014
e5e9f73
more info on height
May 15, 2014
4cba15f
rest_handler
May 15, 2014
5f5d633
show address
May 15, 2014
d8a6431
remove logging
May 15, 2014
a1df3f3
better height
May 15, 2014
8d6ba3f
transaction deseralize
May 15, 2014
1745af3
fix typo
May 15, 2014
8c9186c
better dict
May 15, 2014
c29c47f
block header by hash
May 15, 2014
35401dc
try to get block transaction hashesh works
May 15, 2014
d37083b
show correct previus_block_hash
May 16, 2014
695df65
fetching the block
May 16, 2014
9589984
rest handler miss one command
May 16, 2014
ae5baa1
more info on transaction
May 16, 2014
7f5c46b
fix Install conflict
May 19, 2014
94096b5
api rest
May 19, 2014
7d734b1
show net
May 19, 2014
cec3d0b
test
May 19, 2014
3f41c41
change documentation
May 20, 2014
6e8a16f
remove unused line
May 20, 2014
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
*.pyc
*.o
*.so
config.json
tags
.*.sw*
13 changes: 9 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,11 @@ The darkwallet gateway is a daemon providing the following services to wallets:
Generally the gateway tries to provide all services a wallet may need acting as a proxy to mask the user address so as to not compromise it in many services.


Install:
-------------

see INSTALL file

Running:
-----------

Expand All @@ -27,25 +32,25 @@ Client cheatlist:

Fetching a block header
```
$ curl http://localhost:8888/block/000000000000000145f738890dc703e7637b677f15e9a49ea2eeca6e6e3c5f51
$ curl http://localhost:8888/rest/v1/block/000000000000000145f738890dc703e7637b677f15e9a49ea2eeca6e6e3c5f51
{"nonce": 2595258480, "timestamp": 1391031759, "version": 2, "prev_hash": "00000000000000012af08fe29312627aa6f74aa7f617925da4f4f3a572a95da0", "merkle": "088d6b08fbca5c9fb5c1970a7af5a17847d67635b80ca6f12bd982218e2a83ac", "bits": 419558700}
```

Fetching block transactions
```
$ curl http://localhost:8888/block/000000000000000145f738890dc703e7637b677f15e9a49ea2eeca6e6e3c5f51/transactions
$ curl http://localhost:8888/rest/v1/block/000000000000000145f738890dc703e7637b677f15e9a49ea2eeca6e6e3c5f51/transactions
{"transactions": ["0118256f73a29a2d6c06ea21fc48166ebf5acbcfaf57da3e173be7018e245338", "4424d7f653e29d731f95091d478816743c320fd7fa6a94f9bf8d4b2d7baf0975", ....
```

Fetching transaction
```
$ curl http://localhost:8888/tx/5a002b39d70d0c3197afa1d2ae874083631f5a43cd4fe2b2cc35347d863f00f7
$ curl http://localhost:8888/rest/v1/tx/5a002b39d70d0c3197afa1d2ae874083631f5a43cd4fe2b2cc35347d863f00f7
{"inputs": [{"previous_output": ["da03f16974423bf6425be37e7a6297587a35f117ce3b657e781eeff0098faed5", 0], "sequence": 4294967295, ....
```

address history

```
$ curl http://localhost:8888/address/1dice3jkpTvevsohA4Np1yP4uKzG1SRLv
$ curl http://localhost:8888/rest/v1/address/1dice3jkpTvevsohA4Np1yP4uKzG1SRLv
{ "history" : [{"spend_hash": "cdf6ea4f4590fbc847855cf68af181f1398b8997081cf0cfbd14e0f2cf2808ea", "output_height": 228180, "spend_index": 0, "value": 1000000, ....
```
2 changes: 1 addition & 1 deletion client/test.html
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
write_to_screen("CONNECTED");
test(client);
};
var client = new GatewayClient("ws://obelisk.unsystem.net:8888/", handle_connect);
var client = new GatewayClient("ws://localhost:8888/", handle_connect);

client.on_error = function(evt) {
write_to_screen('<span style="color: red;">ERROR:</span> ' + evt.data);
Expand Down
4 changes: 2 additions & 2 deletions daemon/base58.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ def b58encode(v):

return (__b58chars[0]*nPad) + result

def b58decode(v, length):
def b58decode(v, length=None):
""" decode v into a string of len bytes."""
long_value = 0L
for (i, c) in enumerate(v[::-1]):
Expand All @@ -47,4 +47,4 @@ def b58decode(v, length):
if length is not None and len(result) != length:
return None

return result
return result
120 changes: 21 additions & 99 deletions daemon/gateway.py
Original file line number Diff line number Diff line change
@@ -1,15 +1,11 @@
#!/usr/bin/env python

import logging
import tornado.options
import tornado.web
import tornado.websocket
import os.path
import obelisk
import json
import threading
import code
from collections import defaultdict

import config

Expand All @@ -27,6 +23,7 @@

import rest_handlers
import obelisk_handler
import querysocket_handler
import jsonchan
import broadcast
import ticker
Expand All @@ -43,110 +40,32 @@ def __init__(self, service):
settings = dict(debug=True)
settings.update(options.as_dict())
client = obelisk.ObeliskOfLightClient(service)
self.client = client
self.obelisk_handler = obelisk_handler.ObeliskHandler(client)
self.brc_handler = broadcast.BroadcastHandler()
self.p2p = CryptoTransportLayer(config.get('p2p-port', 8889), config.get('external-ip', '127.0.0.1'))
self.p2p.join_network(config.get('seeds', []))
self.json_chan_handler = jsonchan.JsonChanHandler(self.p2p)
self.ticker_handler = ticker.TickerHandler()

#websocket uri space
handlers = [
# /block/<block hash>
(r"/block/([^/]*)(?:/)?", rest_handlers.BlockHeaderHandler),

# /block/<block hash>/transactions
(r"/block/([^/]*)/transactions(?:/)?",
rest_handlers.BlockTransactionsHandler),

# /tx/
(r"/tx(?:/)?", rest_handlers.TransactionPoolHandler),

# /tx/<txid>
(r"/tx/([^/]*)(?:/)?", rest_handlers.TransactionHandler),

# /address/<address>
(r"/address/([^/]*)(?:/)?", rest_handlers.AddressHistoryHandler),

# /height
(r"/height(?:/)?", rest_handlers.HeightHandler),
## WebSocket Handler
(r"/", querysocket_handler.QuerySocketHandler)
]

# /
(r"/", QuerySocketHandler)
# helloobelisk uri space
uri_space= r"/rest/v1/"
other_handlers = [
(uri_space + r'net(?:/)?', rest_handlers.NetHandler),
(uri_space + r'height(?:/)?', rest_handlers.HeightHandler),
(uri_space + r'address/([^/]*)(?:/)?', rest_handlers.AddressHistoryHandler),
(uri_space + r'tx/([^/]*)(?:/)?', rest_handlers.TransactionHandler),
(uri_space + r'block/([^/]*)(?:/)?', rest_handlers.BlockHeaderHandler),
(uri_space + r"block/([^/]*)/transactions(?:/)?", rest_handlers.BlockTransactionsHandler),
]
all_handlers = other_handlers + handlers
tornado.web.Application.__init__(self, all_handlers, **settings)

tornado.web.Application.__init__(self, handlers, **settings)

class QuerySocketHandler(tornado.websocket.WebSocketHandler):

# Set of WebsocketHandler
listeners = set()
# Protects listeners
listen_lock = threading.Lock()

def initialize(self):
self._obelisk_handler = self.application.obelisk_handler
self._brc_handler = self.application.brc_handler
self._json_chan_handler = self.application.json_chan_handler
self._ticker_handler = self.application.ticker_handler
self._subscriptions = defaultdict(dict)
self._connected = False

def open(self):
logging.info("OPEN")
with QuerySocketHandler.listen_lock:
self.listeners.add(self)
self._connected = True

def on_close(self):
logging.info("CLOSE")
disconnect_msg = {'command': 'disconnect_client', 'id': 0, 'params': []}
self._connected = False
self._obelisk_handler.handle_request(self, disconnect_msg)
self._json_chan_handler.handle_request(self, disconnect_msg)
with QuerySocketHandler.listen_lock:
self.listeners.remove(self)

def _check_request(self, request):
return request.has_key("command") and request.has_key("id") and \
request.has_key("params") and type(request["params"]) == list

def on_message(self, message):
try:
request = json.loads(message)
except:
logging.error("Error decoding message: %s", message, exc_info=True)

# Check request is correctly formed.
if not self._check_request(request):
logging.error("Malformed request: %s", request, exc_info=True)
return
# Try different handlers until one accepts request and
# processes it.
if self._json_chan_handler.handle_request(self, request):
return
if self._obelisk_handler.handle_request(self, request):
return
if self._brc_handler.handle_request(self, request):
return
if self._ticker_handler.handle_request(self, request):
return
logging.warning("Unhandled command. Dropping request: %s",
request, exc_info=True)

def _send_response(self, response):
try:
self.write_message(json.dumps(response))
except tornado.websocket.WebSocketClosedError:
self._connected = False
logging.warning("Dropping response to closed socket: %s",
response, exc_info=True)

def queue_response(self, response):
try:
# calling write_message or the socket is not thread safe
ioloop.add_callback(self._send_response, response)
except:
logging.error("Error adding callback", exc_info=True)

class DebugConsole(threading.Thread):

Expand All @@ -170,5 +89,8 @@ def main(service):

if __name__ == "__main__":
service = config.get("obelisk-url", "tcp://127.0.0.1:9091")
main(service)
try:
main(service)
except KeyboardInterrupt:
reactor.stop()

3 changes: 2 additions & 1 deletion daemon/obelisk_handler.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
from twisted.internet import reactor

import base58
import logging
import obelisk

Expand Down Expand Up @@ -131,7 +132,7 @@ def call_method(self, method, params):

def translate_arguments(self, params):
if len(params) != 1 and len(params) != 2:
raise ValueError("Invalid parameter list length")
raise ValueError("Invalid parameter list length %s" % len(params))
address = params[0]
if len(params) == 2:
from_height = params[1]
Expand Down
81 changes: 81 additions & 0 deletions daemon/querysocket_handler.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
import tornado
import logging
import threading
from collections import defaultdict
import json


class QuerySocketHandler(tornado.websocket.WebSocketHandler):

# Set of WebsocketHandler
listeners = set()
# Protects listeners
listen_lock = threading.Lock()

def initialize(self):
self._obelisk_handler = self.application.obelisk_handler
self._brc_handler = self.application.brc_handler
self._json_chan_handler = self.application.json_chan_handler
self._ticker_handler = self.application.ticker_handler
self._subscriptions = defaultdict(dict)
self._connected = False

def open(self):
logging.info("OPEN")
with QuerySocketHandler.listen_lock:
self.listeners.add(self)
self._connected = True

def on_close(self):
logging.info("CLOSE")
disconnect_msg = {'command': 'disconnect_client', 'id': 0, 'params': []}
self._connected = False
self._obelisk_handler.handle_request(self, disconnect_msg)
self._json_chan_handler.handle_request(self, disconnect_msg)
with QuerySocketHandler.listen_lock:
self.listeners.remove(self)

def _check_request(self, request):
return request.has_key("command") and request.has_key("id") and \
request.has_key("params") and type(request["params"]) == list

def on_message(self, message):
try:
request = json.loads(message)
except:
logging.error("Error decoding message: %s", message, exc_info=True)
return

# Check request is correctly formed.
if not self._check_request(request):
logging.error("Malformed request: %s", request, exc_info=True)
return
# Try different handlers until one accepts request and
# processes it.
if self._json_chan_handler.handle_request(self, request):
return
if self._obelisk_handler.handle_request(self, request):
return
if self._brc_handler.handle_request(self, request):
return
if self._ticker_handler.handle_request(self, request):
return
logging.warning("Unhandled command. Dropping request: %s",
request, exc_info=True)

def _send_response(self, response):
try:
self.write_message(json.dumps(response))
except tornado.websocket.WebSocketClosedError:
self._connected = False
logging.warning("Dropping response to closed socket: %s",
response, exc_info=True)

def queue_response(self, response):
ioloop = tornado.ioloop.IOLoop.current()
try:
# calling write_message or the socket is not thread safe
ioloop.add_callback(self._send_response, response)
except:
logging.error("Error adding callback", exc_info=True)

Loading