diff --git a/README.rst b/README.rst index ee48bd8..b8bfc5c 100644 --- a/README.rst +++ b/README.rst @@ -59,13 +59,13 @@ can perform any other actions. :: - GET /api/register// + GET /api/register/ Success Example: :: - GET /api/register/191GVvAaTRxLmz3rW3nU5jAV1rF186VxQc/ + GET /api/register/191GVvAaTRxLmz3rW3nU5jAV1rF186VxQc RESPONSE: Status Code: 200 Text: User registered. @@ -74,12 +74,12 @@ Fail Examples: :: - GET /api/register/notvalidaddress/ + GET /api/register/notvalidaddress RESPONSE: Status Code: 400 Text: Registration Failed: Invalid BTC Address. - GET /api/register/191GVvAaTRxLmz3rW3nU5jAV1rF186VxQc/ + GET /api/register/191GVvAaTRxLmz3rW3nU5jAV1rF186VxQc RESPONSE: Status Code: 409 Text: Registration failed: Address already is registered. @@ -92,13 +92,13 @@ has gone offline, and that we should not issue more challenges. :: - GET /api/ping// + GET /api/ping/ Success Example: :: - GET /api/ping/191GVvAaTRxLmz3rW3nU5jAV1rF186VxQc/ + GET /api/ping/191GVvAaTRxLmz3rW3nU5jAV1rF186VxQc RESPONSE: Status Code: 200 Text: Ping accepted. @@ -107,12 +107,12 @@ Fail Examples: :: - GET /api/ping/notvalidaddress/ + GET /api/ping/notvalidaddress RESPONSE: Status Code: 400 Text: Ping failed: Invalid Bitcoin address. - GET /api/ping/1EawBV7n7f2wDbgxJfNzo1eHyQ9Gj77oJd/ + GET /api/ping/1EawBV7n7f2wDbgxJfNzo1eHyQ9Gj77oJd RESPONSE: Status Code: 404 Text: Ping Failed: Farmer not found. @@ -127,13 +127,13 @@ is 15 minutes. :: - GET /api/online/ + GET /api/online Success Example: :: - GET /api/online/ + GET /api/online RESPONSE: Status Code: 200 Text: @@ -144,6 +144,23 @@ Success Example: 1CgLoZT1ZuSHPBp3H4rLTXJvEUDV3kK7QK | Last Seen: 13 second(s) | Height: 245 1QACy1Tx5JFzGDyPd8J3oU8SrjhkZkru4H | Last Seen: 14 second(s) | Height: 88 +Total Bytes +*********** + +Get the total number of terabytes currently being managed by the node. + +:: + + GET /api/total + +Success Example: + +:: + + GET /api/total + RESPONSE: + Status Code: 200 + Text: 35 TB Advertise Height **************** @@ -152,13 +169,13 @@ Allows the user to let the node know how much space they have generated via the :: - GET /api/height/// + GET /api/height// Success Example: :: - GET /api/height/191GVvAaTRxLmz3rW3nU5jAV1rF186VxQc/50/ + GET /api/height/191GVvAaTRxLmz3rW3nU5jAV1rF186VxQc/50 RESPONSE: Status Code: 200 Text: Height accepted. @@ -167,12 +184,12 @@ Fail Examples: :: - GET /api/height/notvalidaddress/50/ + GET /api/height/notvalidaddress/50 RESPONSE: Status Code: 400 Text: Ping Failed: Invalid Bitcoin address. - GET /api/height/1EawBV7n7f2wDbgxJfNzo1eHyQ9Gj77oJd/50/ + GET /api/height/1EawBV7n7f2wDbgxJfNzo1eHyQ9Gj77oJd/50 RESPONSE: Status Code: 404 Text: Ping Failed: Farmer not found. diff --git a/dataserv/app.py b/dataserv/app.py index 6854214..2a26d9f 100644 --- a/dataserv/app.py +++ b/dataserv/app.py @@ -19,6 +19,18 @@ def secs_to_mins(seconds): else: return "{0} hour(s)".format(int(seconds/3600)) +def online_farmers(): + # maximum number of minutes since the last check in for + # the farmer to be considered an online farmer + online_time = app.config["ONLINE_TIME"] + + # find the time object online_time minutes in the past + current_time = datetime.datetime.utcnow() + time_ago = current_time - datetime.timedelta(minutes=online_time) + + # give us all farmers that have been around for the past online_time + return db.session.query(Farmer).filter(Farmer.last_seen > time_ago).all() + # Routes @app.route('/') @@ -68,21 +80,12 @@ def ping(btc_addr): @app.route('/api/online', methods=["GET"]) def online(): - # maximum number of minutes since the last check in for - # the farmer to be considered an online farmer - online_time = app.config["ONLINE_TIME"] - - # find the time object online_time minutes in the past - current_time = datetime.datetime.utcnow() - time_ago = current_time - datetime.timedelta(minutes=online_time) - - # give us all farmers that have been around for the past online_time - online_farmers = db.session.query(Farmer).filter(Farmer.last_seen > time_ago).all() - # this could be formatted a bit better, but we just want to publicly display # that status of the farmers connected to the node output = "" - for farmer in online_farmers: + current_time = datetime.datetime.utcnow() + + for farmer in online_farmers(): last_seen = secs_to_mins((current_time - farmer.last_seen).seconds) text = "{0} | Last Seen: {1} | Height: {2}
" output += text.format(farmer.btc_addr, last_seen, farmer.height) @@ -90,6 +93,25 @@ def online(): return output +@app.route('/api/total', methods=["GET"]) +def total(): + total_shards = 0 + + # add up number of shards + for farmer in online_farmers(): + total_shards += farmer.height + + # return in TB the number + app.config["BYTE_SIZE"] = 1024*1024*128 + result = total_shards * (app.config["BYTE_SIZE"] / (1024*1024*1024*1024)) # 1 TB + + print(total_shards) + print(app.config["BYTE_SIZE"]) + print(app.config["BYTE_SIZE"] / (1024*1024*1024*1024)) + + return "{0} TB".format(round(result,2)) + + @app.route('/api/height//', methods=["GET"]) def set_height(btc_addr, height): # create Farmer object to represent user diff --git a/tests/test_App.py b/tests/test_App.py index 53044bb..43eea4c 100644 --- a/tests/test_App.py +++ b/tests/test_App.py @@ -126,5 +126,31 @@ def test_farmer_set_height(self): rv = self.app.get('/api/height/{0}/1'.format(addr2)) self.assertEqual(rv.status_code, 400) + def test_farmer_total_bytes(self): + addr1 = '191GVvAaTRxLmz3rW3nU5jAV1rF186VxQc' + addr2 = '18c2qnUAfgF3UnJCjAz2rpWQph5xugEfkr' + addr3 = '1NqtfdHe3X6rqHRQjsGq5CT9LYYjTFJ1qD' + addr4 = '1JnaPB29Un3FBSf3e4Jzabwi1ekeKoh1Gr' + + # register farmers + self.app.get('/api/register/{0}'.format(addr1)) + self.app.get('/api/register/{0}'.format(addr2)) + self.app.get('/api/register/{0}'.format(addr3)) + self.app.get('/api/register/{0}'.format(addr4)) + # set height + self.app.get('/api/height/{0}/{1}'.format(addr1, 0)) + self.app.get('/api/height/{0}/{1}'.format(addr2, 2475)) + self.app.get('/api/height/{0}/{1}'.format(addr3, 2525)) + self.app.get('/api/height/{0}/{1}'.format(addr4, 5000)) + # check online + rv = self.app.get('/api/online') + self.assertTrue(b"Height: 0" in rv.data) + self.assertTrue(b"Height: 2475" in rv.data) + self.assertTrue(b"Height: 2525" in rv.data) + self.assertTrue(b"Height: 5000" in rv.data) + + # check total bytes + rv = self.app.get('/api/total') + self.assertEqual(b"1.22 TB", rv.data) \ No newline at end of file