Reformats code to match code guidelines

This commit is contained in:
Sergi Delgado Segura
2019-11-07 15:23:43 +00:00
parent b16775a4aa
commit 20f296c9d4
42 changed files with 770 additions and 587 deletions

View File

@@ -13,8 +13,8 @@ from test.simulator.zmq_publisher import ZMQPublisher
from pisa.conf import FEED_PROTOCOL, FEED_ADDR, FEED_PORT
app = Flask(__name__)
HOST = 'localhost'
PORT = '18443'
HOST = "localhost"
PORT = "18443"
blockchain = []
blocks = {}
@@ -24,20 +24,20 @@ mempool = []
mine_new_block = Event()
TIME_BETWEEN_BLOCKS = 5
GENESIS_PARENT = '0000000000000000000000000000000000000000000000000000000000000000'
GENESIS_PARENT = "0000000000000000000000000000000000000000000000000000000000000000"
prev_block_hash = GENESIS_PARENT
@app.route('/generate', methods=['POST'])
@app.route("/generate", methods=["POST"])
def generate():
global mine_new_block
mine_new_block.set()
return Response(status=200, mimetype='application/json')
return Response(status=200, mimetype="application/json")
@app.route('/fork', methods=['POST'])
@app.route("/fork", methods=["POST"])
def create_fork():
"""
create_fork processes chain fork requests. It will create a fork with the following parameters:
@@ -67,10 +67,10 @@ def create_fork():
# block heights and blockchain length is currently incorrect. It does the trick to test forks, but should
# be fixed for better testing.
return Response(json.dumps(response), status=200, mimetype='application/json')
return Response(json.dumps(response), status=200, mimetype="application/json")
@app.route('/', methods=['POST'])
@app.route("/", methods=["POST"])
def process_request():
"""
process_requests simulates the bitcoin-rpc server run by bitcoind. The available commands are limited to the ones
@@ -108,7 +108,7 @@ def process_request():
global mempool
request_data = request.get_json()
method = request_data.get('method')
method = request_data.get("method")
response = {"id": 0, "result": 0, "error": None}
no_param_err = {"code": RPC_MISC_ERROR, "message": "JSON value is not a {} as expected"}
@@ -142,8 +142,10 @@ def process_request():
response["result"] = {"txid": txid}
else:
response["error"] = {"code": RPC_VERIFY_ALREADY_IN_CHAIN,
"message": "Transaction already in block chain"}
response["error"] = {
"code": RPC_VERIFY_ALREADY_IN_CHAIN,
"message": "Transaction already in block chain",
}
else:
response["error"] = {"code": RPC_DESERIALIZATION_ERROR, "message": "TX decode failed"}
@@ -158,16 +160,18 @@ def process_request():
if isinstance(txid, str):
if txid in mined_transactions:
block = blocks.get(mined_transactions[txid]["block"])
rawtx = mined_transactions[txid].get('tx')
response["result"] = {"hex": rawtx, "confirmations": len(blockchain) - block.get('height')}
rawtx = mined_transactions[txid].get("tx")
response["result"] = {"hex": rawtx, "confirmations": len(blockchain) - block.get("height")}
elif txid in mempool:
response["result"] = {"confirmations": 0}
else:
response["error"] = {'code': RPC_INVALID_ADDRESS_OR_KEY,
'message': 'No such mempool or blockchain transaction. Use gettransaction for '
'wallet transactions.'}
response["error"] = {
"code": RPC_INVALID_ADDRESS_OR_KEY,
"message": "No such mempool or blockchain transaction. Use gettransaction for "
"wallet transactions.",
}
else:
response["error"] = no_param_err
response["error"]["message"] = response["error"]["message"].format("string")
@@ -219,7 +223,7 @@ def process_request():
else:
return abort(404, "Method not found")
return Response(json.dumps(response), status=200, mimetype='application/json')
return Response(json.dumps(response), status=200, mimetype="application/json")
def get_param(request_data):
@@ -240,8 +244,9 @@ def load_data():
def simulate_mining(mode, time_between_blocks):
global mempool, mined_transactions, blocks, blockchain, mine_new_block, prev_block_hash
mining_simulator = ZMQPublisher(topic=b'hashblock', feed_protocol=FEED_PROTOCOL, feed_addr=FEED_ADDR,
feed_port=FEED_PORT)
mining_simulator = ZMQPublisher(
topic=b"hashblock", feed_protocol=FEED_PROTOCOL, feed_addr=FEED_ADDR, feed_port=FEED_PORT
)
# Set the mining event to initialize the blockchain with a block
mine_new_block.set()
@@ -266,8 +271,12 @@ def simulate_mining(mode, time_between_blocks):
mined_transactions[txid] = {"tx": tx, "block": block_hash}
# FIXME: chain_work is being defined as a incremental counter for now. Multiple chains should be possible.
blocks[block_hash] = {"tx": list(txs_to_mine.keys()), "height": len(blockchain), "previousblockhash": prev_block_hash,
"chainwork": '{:x}'.format(len(blockchain))}
blocks[block_hash] = {
"tx": list(txs_to_mine.keys()),
"height": len(blockchain),
"previousblockhash": prev_block_hash,
"chainwork": "{:x}".format(len(blockchain)),
}
mining_simulator.publish_data(binascii.unhexlify(block_hash))
blockchain.append(block_hash)
@@ -276,22 +285,22 @@ def simulate_mining(mode, time_between_blocks):
print("New block mined: {}".format(block_hash))
print("\tTransactions: {}".format(list(txs_to_mine.keys())))
if mode == 'time':
if mode == "time":
time.sleep(time_between_blocks)
else:
mine_new_block.clear()
def run_simulator(mode='time', time_between_blocks=TIME_BETWEEN_BLOCKS):
if mode not in ["time", 'event']:
def run_simulator(mode="time", time_between_blocks=TIME_BETWEEN_BLOCKS):
if mode not in ["time", "event"]:
raise ValueError("Node must be time or event")
mining_thread = Thread(target=simulate_mining, args=[mode, time_between_blocks])
mining_thread.start()
# Setting Flask log to ERROR only so it does not mess with out logging. Also disabling flask initial messages
logging.getLogger('werkzeug').setLevel(logging.ERROR)
os.environ['WERKZEUG_RUN_MAIN'] = 'true'
logging.getLogger("werkzeug").setLevel(logging.ERROR)
os.environ["WERKZEUG_RUN_MAIN"] = "true"
app.run(host=HOST, port=PORT)

View File

@@ -9,12 +9,12 @@ from test.simulator.bitcoind_sim import run_simulator
from pisa.utils.auth_proxy import AuthServiceProxy, JSONRPCException
from pisa.conf import BTC_RPC_USER, BTC_RPC_PASSWD, BTC_RPC_HOST, BTC_RPC_PORT
MIXED_VALUES = values = [-1, 500, '', '111', [], 1.1, None, '', "a" * 31, "b" * 33, get_random_value_hex(32)]
MIXED_VALUES = values = [-1, 500, "", "111", [], 1.1, None, "", "a" * 31, "b" * 33, get_random_value_hex(32)]
bitcoin_cli = AuthServiceProxy("http://%s:%s@%s:%d" % (BTC_RPC_USER, BTC_RPC_PASSWD, BTC_RPC_HOST, BTC_RPC_PORT))
@pytest.fixture(scope='module')
@pytest.fixture(scope="module")
def run_bitcoind():
bitcoind_thread = Thread(target=run_simulator, kwargs={"mode": "event"})
bitcoind_thread.daemon = True
@@ -31,19 +31,20 @@ def genesis_block_hash(run_bitcoind):
def check_hash_format(txid):
# TODO: #12-check-txid-regexp
return isinstance(txid, str) and re.search(r'^[0-9A-Fa-f]{64}$', txid) is not None
return isinstance(txid, str) and re.search(r"^[0-9A-Fa-f]{64}$", txid) is not None
def test_help(run_bitcoind):
# Help should always return 0
assert(bitcoin_cli.help() == 0)
assert bitcoin_cli.help() == 0
# FIXME: Better assert for the exceptions would be nice (check the returned errno is the expected one)
def test_getblockhash(genesis_block_hash):
# First block
assert(check_hash_format(genesis_block_hash))
assert check_hash_format(genesis_block_hash)
# Check that the values are within range and of the proper format (all should fail)
for v in MIXED_VALUES:
@@ -57,9 +58,9 @@ def test_getblockhash(genesis_block_hash):
def test_get_block(genesis_block_hash):
# getblock should return a list of transactions and the height
block = bitcoin_cli.getblock(genesis_block_hash)
assert(isinstance(block.get('tx'), list))
assert(len(block.get('tx')) != 0)
assert(isinstance(block.get('height'), int))
assert isinstance(block.get("tx"), list)
assert len(block.get("tx")) != 0
assert isinstance(block.get("height"), int)
# It should fail for wrong data formats and random ids
for v in MIXED_VALUES:
@@ -73,21 +74,21 @@ def test_get_block(genesis_block_hash):
def test_decoderawtransaction(genesis_block_hash):
# decoderawtransaction should only return if the given transaction matches a txid format
block = bitcoin_cli.getblock(genesis_block_hash)
coinbase_txid = block.get('tx')[0]
coinbase_txid = block.get("tx")[0]
coinbase_tx = bitcoin_cli.getrawtransaction(coinbase_txid).get("hex")
tx = bitcoin_cli.decoderawtransaction(coinbase_tx)
assert(isinstance(tx, dict))
assert(isinstance(tx.get('txid'), str))
assert(check_hash_format(tx.get('txid')))
assert isinstance(tx, dict)
assert isinstance(tx.get("txid"), str)
assert check_hash_format(tx.get("txid"))
# Therefore should also work for a random transaction hex in our simulation
random_tx = TX.create_dummy_transaction()
tx = bitcoin_cli.decoderawtransaction(random_tx)
assert(isinstance(tx, dict))
assert(isinstance(tx.get('txid'), str))
assert(check_hash_format(tx.get('txid')))
assert isinstance(tx, dict)
assert isinstance(tx.get("txid"), str)
assert check_hash_format(tx.get("txid"))
# But it should fail for not proper formatted one
for v in MIXED_VALUES:
@@ -124,8 +125,8 @@ def test_getrawtransaction(genesis_block_hash):
genesis_tx = bitcoin_cli.getblock(genesis_block_hash).get("tx")[0]
tx = bitcoin_cli.getrawtransaction(genesis_tx)
assert(isinstance(tx, dict))
assert(isinstance(tx.get('confirmations'), int))
assert isinstance(tx, dict)
assert isinstance(tx.get("confirmations"), int)
for v in MIXED_VALUES:
try:
@@ -138,9 +139,5 @@ def test_getrawtransaction(genesis_block_hash):
def test_getblockcount():
# getblockcount should always return a positive integer
bc = bitcoin_cli.getblockcount()
assert (isinstance(bc, int))
assert (bc >= 0)
assert isinstance(bc, int)
assert bc >= 0

View File

@@ -137,14 +137,16 @@ class TX:
tx.prev_out_index = [prev_out_index]
tx.nLockTime = 0
tx.scriptSig = [
'47304402204e45e16932b8af514961a1d3a1a25fdf3f4f7732e9d624c6c61548ab5fb8cd410220181522ec8eca07de4860'
'a4acdd12909d831cc56cbbac4622082221a8768d1d0901']
"47304402204e45e16932b8af514961a1d3a1a25fdf3f4f7732e9d624c6c61548ab5fb8cd410220181522ec8eca07de4860"
"a4acdd12909d831cc56cbbac4622082221a8768d1d0901"
]
tx.scriptSig_len = [77]
tx.nSequence = [4294967295]
tx.value = [5000000000]
tx.scriptPubKey = [
'4104ae1a62fe09c5f51b13905f07f06b99a2f7159b2225f374cd378d71302fa28414e7aab37397f554a7df5f142c21c'
'1b7303b8a0626f1baded5c72a704f7e6cd84cac']
"4104ae1a62fe09c5f51b13905f07f06b99a2f7159b2225f374cd378d71302fa28414e7aab37397f554a7df5f142c21c"
"1b7303b8a0626f1baded5c72a704f7e6cd84cac"
]
tx.scriptPubKey_len = [67]
return tx.serialize()

View File

@@ -17,7 +17,7 @@ def change_endianness(x):
y = unhexlify(x)
z = y[::-1]
return hexlify(z).decode('utf-8')
return hexlify(z).decode("utf-8")
def parse_varint(tx):
@@ -30,10 +30,10 @@ def parse_varint(tx):
# First of all, the offset of the hex transaction if moved to the proper position (i.e where the varint should be
# located) and the length and format of the data to be analyzed is checked.
data = tx.hex[tx.offset:]
assert (len(data) > 0)
data = tx.hex[tx.offset :]
assert len(data) > 0
size = int(data[:2], 16)
assert (size <= 255)
assert size <= 255
# Then, the integer is encoded as a varint using the proper prefix, if needed.
if size <= 252: # No prefix
@@ -49,7 +49,7 @@ def parse_varint(tx):
# Finally, the storage length is used to extract the proper number of bytes from the transaction hex and the
# transaction offset is updated.
varint = data[:storage_length * 2]
varint = data[: storage_length * 2]
tx.offset += storage_length * 2
return varint
@@ -65,7 +65,7 @@ def parse_element(tx, size):
:rtype: hex str
"""
element = tx.hex[tx.offset:tx.offset + size * 2]
element = tx.hex[tx.offset : tx.offset + size * 2]
tx.offset += size * 2
return element
@@ -97,7 +97,7 @@ def encode_varint(value):
prefix = 255 # 0xFF
else:
raise Exception("Wrong input data size")
varint = format(prefix, 'x') + change_endianness(int2bytes(value, size))
varint = format(prefix, "x") + change_endianness(int2bytes(value, size))
return varint
@@ -112,12 +112,13 @@ def int2bytes(a, b):
:rtype: hex str
"""
m = pow(2, 8*b) - 1
m = pow(2, 8 * b) - 1
if a > m:
raise Exception(str(a) + " is too big to be represented with " + str(b) + " bytes. Maximum value is "
+ str(m) + ".")
raise Exception(
str(a) + " is too big to be represented with " + str(b) + " bytes. Maximum value is " + str(m) + "."
)
return ('%0' + str(2 * b) + 'x') % a
return ("%0" + str(2 * b) + "x") % a
def sha256d(hex_data):
@@ -125,4 +126,3 @@ def sha256d(hex_data):
double_sha256 = sha256(sha256(data).digest()).hexdigest()
return change_endianness(double_sha256)