Skip to content
This repository has been archived by the owner on Jul 12, 2021. It is now read-only.

Commit Version, Subversion, ProtoVersion, RelayFee RPC #139

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
52 changes: 52 additions & 0 deletions src/bitcoinrpc.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import ast
import hashlib
from json import dumps, loads
import random
import sys
import time
import threading
import urllib
from utils import logger
from processor import Processor


class BitcoinRPC(Processor):

def __init__(self, config, shared):
Processor.__init__(self)
self.shared = shared
self.config = config
self.bitcoind_url = 'http://%s:%s@%s:%s/' % (
config.get('bitcoind', 'bitcoind_user'),
config.get('bitcoind', 'bitcoind_password'),
config.get('bitcoind', 'bitcoind_host'),
config.get('bitcoind', 'bitcoind_port'))

def wait_on_bitcoind(self):
self.shared.pause()
time.sleep(10)
if self.shared.stopped():
# this will end the thread
raise BaseException()

def call(self, method, params=[]):
postdata = dumps({"method": method, 'params': params, 'id': 'jsonrpc'})
while True:
try:
connection = urllib.urlopen(self.bitcoind_url, postdata)
respdata = connection.read()
connection.close()
except:
print_log("cannot reach bitcoind...")
self.wait_on_bitcoind()
else:
r = loads(respdata)
if r['error'] is not None:
if r['error'].get('code') == -28:
print_log("bitcoind still warming up...")
self.wait_on_bitcoind()
continue
raise BaseException(r['error'])
break
return r.get('result')

52 changes: 22 additions & 30 deletions src/blockchain_processor.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import urllib

import deserialize
from bitcoinrpc import BitcoinRPC
from processor import Processor, print_log
from utils import *
from storage import Storage
Expand Down Expand Up @@ -49,19 +50,17 @@ def __init__(self, config, shared):
self.mempool_lock = threading.Lock()

self.address_queue = Queue()

self.bitcoind_url = 'http://%s:%s@%s:%s/' % (
config.get('bitcoind', 'bitcoind_user'),
config.get('bitcoind', 'bitcoind_password'),
config.get('bitcoind', 'bitcoind_host'),
config.get('bitcoind', 'bitcoind_port'))
try:
self.test_reorgs = config.getboolean('leveldb', 'test_reorgs') # simulate random blockchain reorgs
except:
self.test_reorgs = False
self.storage = Storage(config, shared, self.test_reorgs)

self.bitcoind_url = 'http://%s:%s@%s:%s/' % (
config.get('bitcoind', 'bitcoind_user'),
config.get('bitcoind', 'bitcoind_password'),
config.get('bitcoind', 'bitcoind_host'),
config.get('bitcoind', 'bitcoind_port'))

self.bitcoind = BitcoinRPC(config, shared)
self.sent_height = 0
self.sent_header = None

Expand All @@ -78,7 +77,7 @@ def __init__(self, config, shared):


def do_catch_up(self):
self.header = self.block2header(self.bitcoind('getblock', [self.storage.last_hash]))
self.header = self.block2header(self.bitcoind.call('getblock', [self.storage.last_hash]))
self.header['utxo_root'] = self.storage.get_root_hash().encode('hex')
self.catch_up(sync=False)
if not self.shared.stopped():
Expand Down Expand Up @@ -122,13 +121,6 @@ def print_time(self, num_tx):
msg += " (eta %s, %d blocks)" % (rt, remaining_blocks)
print_log(msg)

def wait_on_bitcoind(self):
self.shared.pause()
time.sleep(10)
if self.shared.stopped():
# this will end the thread
raise BaseException()

def bitcoind(self, method, params=[]):
postdata = dumps({"method": method, 'params': params, 'id': 'jsonrpc'})
while True:
Expand Down Expand Up @@ -163,8 +155,8 @@ def block2header(self, b):
}

def get_header(self, height):
block_hash = self.bitcoind('getblockhash', [height])
b = self.bitcoind('getblock', [block_hash])
block_hash = self.bitcoind.call('getblockhash', [height])
b = self.bitcoind.call('getblock', [block_hash])
return self.block2header(b)

def init_headers(self, db_height):
Expand Down Expand Up @@ -265,7 +257,7 @@ def get_chunk(self, i):

def get_mempool_transaction(self, txid):
try:
raw_tx = self.bitcoind('getrawtransaction', [txid, 0])
raw_tx = self.bitcoind.call('getrawtransaction', [txid, 0])
except:
return None

Expand Down Expand Up @@ -337,8 +329,8 @@ def get_merkle(self, tx_hash, height, cache_only):
if cache_only:
return -1

block_hash = self.bitcoind('getblockhash', [height])
b = self.bitcoind('getblock', [block_hash])
block_hash = self.bitcoind.call('getblockhash', [height])
b = self.bitcoind.call('getblock', [block_hash])
tx_list = b.get('tx')
tx_pos = tx_list.index(tx_hash)

Expand Down Expand Up @@ -555,7 +547,7 @@ def process(self, request, cache_only=False):

elif method == 'blockchain.transaction.broadcast':
try:
txo = self.bitcoind('sendrawtransaction', params)
txo = self.bitcoind.call('sendrawtransaction', params)
print_log("sent tx:", txo)
result = txo
except BaseException, e:
Expand All @@ -581,11 +573,11 @@ def process(self, request, cache_only=False):

elif method == 'blockchain.transaction.get':
tx_hash = params[0]
result = self.bitcoind('getrawtransaction', [tx_hash, 0])
result = self.bitcoind.call('getrawtransaction', [tx_hash, 0])

elif method == 'blockchain.estimatefee':
num = int(params[0])
result = self.bitcoind('estimatefee', [num])
result = self.bitcoind.call('estimatefee', [num])

else:
raise BaseException("unknown method:%s" % method)
Expand All @@ -597,7 +589,7 @@ def process(self, request, cache_only=False):


def getfullblock(self, block_hash):
block = self.bitcoind('getblock', [block_hash])
block = self.bitcoind.call('getblock', [block_hash])

rawtxreq = []
i = 0
Expand Down Expand Up @@ -643,9 +635,9 @@ def catch_up(self, sync=True):

while not self.shared.stopped():
# are we done yet?
info = self.bitcoind('getinfo')
info = self.bitcoind.call('getinfo')
self.bitcoind_height = info.get('blocks')
bitcoind_block_hash = self.bitcoind('getblockhash', [self.bitcoind_height])
bitcoind_block_hash = self.bitcoind.call('getblockhash', [self.bitcoind_height])
if self.storage.last_hash == bitcoind_block_hash:
self.up_to_date = True
break
Expand All @@ -657,7 +649,7 @@ def catch_up(self, sync=True):
# not done..
self.up_to_date = False
try:
next_block_hash = self.bitcoind('getblockhash', [self.storage.height + 1])
next_block_hash = self.bitcoind.call('getblockhash', [self.storage.height + 1])
except BaseException, e:
revert = True

Expand Down Expand Up @@ -694,7 +686,7 @@ def catch_up(self, sync=True):
# print time
self.print_time(n)

self.header = self.block2header(self.bitcoind('getblock', [self.storage.last_hash]))
self.header = self.block2header(self.bitcoind.call('getblock', [self.storage.last_hash]))
self.header['utxo_root'] = self.storage.get_root_hash().encode('hex')

if self.shared.stopped():
Expand All @@ -704,7 +696,7 @@ def catch_up(self, sync=True):

def memorypool_update(self):
t0 = time.time()
mempool_hashes = set(self.bitcoind('getrawmempool'))
mempool_hashes = set(self.bitcoind.call('getrawmempool'))
touched_addresses = set([])

# get new transactions
Expand Down
16 changes: 15 additions & 1 deletion src/server_processor.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
from version import VERSION
from utils import logger
from ircthread import IrcThread

from bitcoinrpc import BitcoinRPC


class ServerProcessor(Processor):
Expand All @@ -19,6 +19,7 @@ def __init__(self, config, shared):
Processor.__init__(self)
self.daemon = True
self.config = config
self.bitcoind = BitcoinRPC(config)
self.shared = shared
self.irc_queue = Queue.Queue()
self.peers = {}
Expand Down Expand Up @@ -61,6 +62,19 @@ def process(self, request):
if method == 'server.banner':
result = self.config.get('server', 'banner').replace('\\n', '\n')

elif method == 'server.core.version':
info = self.bitcoind.call('getnetworkinfo')
info.get('version')
elif method == 'server.core.subversion':
info = self.bitcoind.call('getnetworkinfo')
info.get('subversion')
result = self.config.get('server', 'subversion')
elif method == 'server.core.protocolversion':
info = self.bitcoind.call('getnetworkinfo')
info.get('protocolversion')
elif method == 'server.core.relayfee':
info = self.bitcoind.call('getnetworkinfo')
info.get('relayfee')
elif method == 'server.donation_address':
result = self.config.get('server', 'donation_address')

Expand Down