miner.py 3.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  1. #!/usr/bin/env python3
  2. import argparse
  3. from urllib.parse import urlparse
  4. import flask
  5. import json
  6. app = flask.Flask(__name__)
  7. from src.crypto import Signing
  8. from src.protocol import Protocol
  9. from src.block import GENESIS_BLOCK
  10. from src.chainbuilder import ChainBuilder
  11. from src.mining import Miner
  12. from src.transaction import TransactionInput
  13. def parse_addr_port(val):
  14. url = urlparse("//" + val)
  15. assert url.scheme == ''
  16. assert url.path == ''
  17. assert url.params == ''
  18. assert url.query == ''
  19. assert url.fragment == ''
  20. assert url.port is not None
  21. assert url.hostname is not None
  22. return (url.hostname, url.port)
  23. def rpc_server(port, chainbuilder):
  24. @app.route("/network-info", methods=['GET'])
  25. def get_network_info():
  26. return json.dumps([list(peer.peer_addr)[:2] for peer in chainbuilder.protocol.peers if peer.is_connected])
  27. @app.route("/transactions", methods=['POST'])
  28. def get_transactions_for_key():
  29. key = Signing(flask.request.data)
  30. transactions = set()
  31. outputs = set()
  32. for b in chainbuilder.primary_block_chain.blocks:
  33. for t in b.transactions:
  34. for i, target in enumerate(t.targets):
  35. if target.recipient_pk == key:
  36. transactions.add(t)
  37. outputs.add(TransactionInput(t.get_hash(), i))
  38. for b in chainbuilder.primary_block_chain.blocks:
  39. for t in b.transactions:
  40. for inp in t.inputs:
  41. if inp in outputs:
  42. transactions.add(t)
  43. return json.dumps([t.to_json_compatible() for t in transactions])
  44. app.run(port=port)
  45. def main():
  46. parser = argparse.ArgumentParser(description="Blockchain Miner.")
  47. parser.add_argument("--listen-address", default="",
  48. help="The IP address where the P2P server should bind to.")
  49. parser.add_argument("--listen-port", default=0, type=int,
  50. help="The port where the P2P server should listen. Defaults a dynamically assigned port.")
  51. parser.add_argument("--mining-pubkey", type=argparse.FileType('rb'),
  52. help="The public key where mining rewards should be sent to. No mining is performed if this is left unspecified.")
  53. parser.add_argument("--bootstrap-peer", action='append', type=parse_addr_port, default=[],
  54. help="Addresses of other P2P peers in the network.")
  55. parser.add_argument("--rpc-port", type=int, default=40203,
  56. help="The port number where the wallet can find an RPC server.")
  57. args = parser.parse_args()
  58. proto = Protocol(args.bootstrap_peer, GENESIS_BLOCK, args.listen_port, args.listen_address)
  59. if args.mining_pubkey is not None:
  60. pubkey = Signing(args.mining_pubkey.read())
  61. args.mining_pubkey.close()
  62. miner = Miner(proto, pubkey)
  63. miner.start_mining()
  64. chainbuilder = miner.chainbuilder
  65. else:
  66. chainbuilder = ChainBuilder(proto)
  67. rpc_server(args.rpc_port, chainbuilder)
  68. if __name__ == '__main__':
  69. main()