Skip to content
This repository has been archived by the owner on Nov 28, 2022. It is now read-only.

Increased block size up to 4M; txes are allowed to occupy only a subs… #149

Merged
merged 14 commits into from
Sep 2, 2021
Merged
Show file tree
Hide file tree
Changes from 10 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
1 change: 1 addition & 0 deletions configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -251,6 +251,7 @@ case $host in
use_pkgconfig=no

TARGET_OS=windows
AC_CHECK_LIB([bcrypt], [main],, AC_MSG_ERROR(lib missing))
AC_CHECK_LIB([mingwthrd], [main],, AC_MSG_ERROR(lib missing))
AC_CHECK_LIB([kernel32], [main],, AC_MSG_ERROR(lib missing))
AC_CHECK_LIB([user32], [main],, AC_MSG_ERROR(lib missing))
Expand Down
2 changes: 2 additions & 0 deletions qa/pull-tester/rpc-tests.sh
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,8 @@ testScripts=(
'cbh_rpcheck.py'
'tlsprotocols.py'
'getblockmerkleroots.py'
'sc_block_partitions.py'
'sc_cert_bwt_amount_rounding.py'
);
testScriptsExt=(
'getblocktemplate_longpoll.py'
Expand Down
2 changes: 1 addition & 1 deletion qa/rpc-tests/sc_big_block.py
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ def advance_sidechains_epoch(num_of_scs):
certMcTest = CertTestUtils(self.options.tmpdir, self.options.srcdir, CERT_PROVING_SYSTEM)
cswMcTest = CSWTestUtils(self.options.tmpdir, self.options.srcdir, CSW_PROVING_SYSTEM)

certVk = certMcTest.generate_params('scs', CERT_NUM_CONSTRAINTS, SEGMENT_SIZE)
certVk = certMcTest.generate_params('scs', 'cert', CERT_NUM_CONSTRAINTS, SEGMENT_SIZE)
cswVk = cswMcTest.generate_params('scs', CSW_NUM_CONSTRAINTS, SEGMENT_SIZE)

constant = generate_random_field_element_hex()
Expand Down
253 changes: 253 additions & 0 deletions qa/rpc-tests/sc_block_partitions.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,253 @@
#!/usr/bin/env python2
# Copyright (c) 2014 The Bitcoin Core developers
# Copyright (c) 2018 The Zencash developers
# Distributed under the MIT software license, see the accompanying
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
from test_framework.test_framework import BitcoinTestFramework
from test_framework.authproxy import JSONRPCException
from test_framework.test_framework import MINIMAL_SC_HEIGHT
from test_framework.util import assert_true, assert_equal, initialize_chain_clean, \
start_nodes, stop_nodes, wait_bitcoinds, sync_blocks, sync_mempools, connect_nodes_bi, mark_logs, \
dump_sc_info, dump_sc_info_record, get_epoch_data, get_spendable, swap_bytes, advance_epoch
from test_framework.mc_test.mc_test import *
ptagl marked this conversation as resolved.
Show resolved Hide resolved
import os
import pprint
from decimal import Decimal
import json
import time

NUMB_OF_NODES = 2
DEBUG_MODE = 1
EPOCH_LENGTH = 40
FT_SC_FEE = Decimal('0')
MBTR_SC_FEE = Decimal('0')
CERT_FEE = Decimal("0.01")

BIT_VECTOR_BUF = "021f8b08000000000002ff017f0080ff44c7e21ba1c7c0a29de006cb8074e2ba39f15abfef2525a4cbb3f235734410bda21cdab6624de769ceec818ac6c2d3a01e382e357dce1f6e9a0ff281f0fedae0efe274351db37599af457984dcf8e3ae4479e0561341adfff4746fbe274d90f6f76b8a2552a6ebb98aee918c7ceac058f4c1ae0131249546ef5e22f4187a07da02ca5b7f000000"
BIT_VECTOR_FE = "8a7d5229f440d4700d8b0343de4e14400d1cb87428abf83bd67153bf58871721"

TEST_BLOCK_TX_PARTITION_MAX_SIZE = 6000
TEST_BLOCK_MAX_SIZE = 3*TEST_BLOCK_TX_PARTITION_MAX_SIZE
TEST_BLOCK_PRIORITY_SIZE = 0

class sc_block_partitions(BitcoinTestFramework):
alert_filename = None

def setup_chain(self, split=False):
print("Initializing test directory " + self.options.tmpdir)
initialize_chain_clean(self.options.tmpdir, NUMB_OF_NODES)
self.alert_filename = os.path.join(self.options.tmpdir, "alert.txt")
with open(self.alert_filename, 'w'):
pass # Just open then close to create zero-length file

def setup_network(self, split=False):

self.nodes = start_nodes(NUMB_OF_NODES, self.options.tmpdir,
extra_args=[['-logtimemicros=1', '-debug=py', '-debug=sc', '-debug=mempool', '-debug=cert', '-debug=bench',
'-blockmaxsize=%d'%TEST_BLOCK_MAX_SIZE,
'-blocktxpartitionmaxsize=%d'%TEST_BLOCK_TX_PARTITION_MAX_SIZE,
'-blockprioritysize=%d'%TEST_BLOCK_PRIORITY_SIZE,
'-scproofqueuesize=0']] * NUMB_OF_NODES)

connect_nodes_bi(self.nodes, 0, 1)
self.is_network_split = split
self.sync_all()

def run_test(self):
'''
Setup a node with a custom size for block size and tx partition size.
Create a SC, advance epoch and create a bunch of certificates with progressive quality and high fee.
Create also a number of txes with lower fee than certs and whose total size exceeds the tx partition size.
- Check that the block is filled by high-fee certs and only the reminder of free space is taken up by txes
- Check that only reserved block partition is occupied despite a greater block size
'''


def create_sc(cmdInput, node):
try:
res = node.create_sidechain(cmdInput)
tx = res['txid']
scid = res['scid']
except JSONRPCException, e:
errorString = e.error['message']
mark_logs(errorString,self.nodes,DEBUG_MODE)
assert_true(False);
ptagl marked this conversation as resolved.
Show resolved Hide resolved

return tx, scid

# network topology: (0)--(1)

print "Miners have max block size = {}, max tx partition size = {}".format(TEST_BLOCK_MAX_SIZE, TEST_BLOCK_TX_PARTITION_MAX_SIZE)

mark_logs("Node 1 generates {} block".format(100), self.nodes, DEBUG_MODE)
self.nodes[1].generate(100)
self.sync_all()

mark_logs("Node 0 generates {} block".format(MINIMAL_SC_HEIGHT-100), self.nodes, DEBUG_MODE)
self.nodes[0].generate(MINIMAL_SC_HEIGHT-100)
self.sync_all()

#generate Vks and constant
certMcTest = CertTestUtils(self.options.tmpdir, self.options.srcdir)

certVk = certMcTest.generate_params('scs')

constant = generate_random_field_element_hex()

amount = 1.0

#-------------------------------------------------------
cmdInput = {
'withdrawalEpochLength': EPOCH_LENGTH, 'amount': amount, 'fee': 0.0001,
'constant':constant , 'wCertVk': certVk, 'toaddress':"cdcd",
}

tx, scid = create_sc(cmdInput, self.nodes[0]);
ptagl marked this conversation as resolved.
Show resolved Hide resolved
mark_logs("Created SC with scid={} via tx={}".format(scid, tx), self.nodes,DEBUG_MODE)
self.sync_all()

# advance epoch
self.nodes[0].generate(EPOCH_LENGTH)
self.sync_all()
epoch_number, epoch_cum_tree_hash = get_epoch_data(scid, self.nodes[0], EPOCH_LENGTH)

mark_logs("Creating certs...", self.nodes, DEBUG_MODE)
proofs = []
q = 10
tot_num_cert = 0
tot_cert_sz = 0
scid_swapped = str(swap_bytes(scid))

while True:
t0 = time.time()
proof = certMcTest.create_test_proof(
"scs", scid_swapped, epoch_number, (q+tot_num_cert), MBTR_SC_FEE, FT_SC_FEE,
epoch_cum_tree_hash, constant, [], [], [])
assert_true(proof != None)
t1 = time.time()
print "...proof generated: {} secs".format(t1-t0)
proofs.append(proof)

try:
cert = self.nodes[0].send_certificate(scid, epoch_number, (q+tot_num_cert),
epoch_cum_tree_hash, proof, [], FT_SC_FEE, MBTR_SC_FEE, CERT_FEE, [], [])
except JSONRPCException, e:
errorString = e.error['message']
print "Send certificate failed with reason {}".format(errorString)
assert(False)
self.sync_all()
tot_num_cert += 1

#mark_logs("cert={}".format(cert), self.nodes, DEBUG_MODE)
hexCert = self.nodes[0].getrawtransaction(cert)
tot_cert_sz += len(hexCert)//2
#print "sz=", len(hexCert)//2
if tot_cert_sz > TEST_BLOCK_MAX_SIZE:
break

print "tot cert = {}, tot sz = {} ".format(tot_num_cert, tot_cert_sz)

mark_logs("Creating txes...", self.nodes, DEBUG_MODE)
tot_num_tx = 0
tot_tx_sz = 0
taddr_node0 = self.nodes[0].getnewaddress()
ptagl marked this conversation as resolved.
Show resolved Hide resolved
taddr_node1 = self.nodes[1].getnewaddress()

# fee lower than the one used for certs
fee = Decimal("0.000025")
am = 0.1
sc_ft = [ {"address":"abc", "amount":am, "scid":scid} ]


# there are 100 coinbase utxo now matured
listunspent = self.nodes[1].listunspent()

while True:
utxo = listunspent[tot_num_tx]
change = utxo['amount'] - Decimal(am) - Decimal(fee)
raw_inputs = [ {'txid' : utxo['txid'], 'vout' : utxo['vout']}]
raw_outs = { taddr_node1: change }
try:
raw_tx = self.nodes[1].createrawtransaction(raw_inputs, raw_outs, [], [], sc_ft)
signed_tx = self.nodes[1].signrawtransaction(raw_tx)
tx = self.nodes[1].sendrawtransaction(signed_tx['hex'])
except JSONRPCException, e:
errorString = e.error['message']
print "Send raw tx failed with reason {}".format(errorString)
assert(False)

tot_num_tx += 1
hexTx = self.nodes[1].getrawtransaction(tx)
tot_tx_sz += len(hexTx)//2
if tot_tx_sz > 2*TEST_BLOCK_TX_PARTITION_MAX_SIZE:
self.sync_all()
break

print "tot tx = {}, tot sz = {} ".format(tot_num_tx, tot_tx_sz)

mark_logs("Generating 1 block and checking blocks partitions...".format(2), self.nodes, DEBUG_MODE)
ptagl marked this conversation as resolved.
Show resolved Hide resolved
self.nodes[0].generate(1)
self.sync_all()
ret = self.nodes[0].getmininginfo()

print "block num of cert = ", ret['currentblockcert']
print "block size = ", ret['currentblocksize']
print "block num of tx = ", ret['currentblocktx']
print "tx partition used = ", ret['currenttxpartitionused']

# all certs but one are included in the block
assert_equal(ret['currentblockcert'], tot_num_cert - 1)
# block space used for certs and txes is lower than max block size
assert_true(ret['currentblocksize'] < TEST_BLOCK_MAX_SIZE)
# block space used for txes is lower than tx partition
assert_true(ret['currenttxpartitionused'] < TEST_BLOCK_TX_PARTITION_MAX_SIZE)

mark_logs("Generating 1 block and checking blocks partitions...".format(2), self.nodes, DEBUG_MODE)
ptagl marked this conversation as resolved.
Show resolved Hide resolved
self.nodes[0].generate(1)
self.sync_all()
ret = self.nodes[0].getmininginfo()

print "block num of cert = ", ret['currentblockcert']
print "block size = ", ret['currentblocksize']
print "block num of tx = ", ret['currentblocktx']
print "tx partition used = ", ret['currenttxpartitionused']

# last cert has been included in the block
assert_equal(ret['currentblockcert'], 1)
# block space used for certs and txes is lower than max block size
assert_true(ret['currentblocksize'] < TEST_BLOCK_MAX_SIZE)
# block space used for txes is lower than tx partition
assert_true(ret['currentblocktx'] > 0)
assert_true(ret['currenttxpartitionused'] < TEST_BLOCK_TX_PARTITION_MAX_SIZE)

mark_logs("Generating 1 block and checking blocks partitions...".format(2), self.nodes, DEBUG_MODE)
ptagl marked this conversation as resolved.
Show resolved Hide resolved
self.nodes[0].generate(1)
self.sync_all()
ret = self.nodes[0].getmininginfo()

print "block num of cert = ", ret['currentblockcert']
print "block size = ", ret['currentblocksize']
print "block num of tx = ", ret['currentblocktx']
print "tx partition used = ", ret['currenttxpartitionused']

# no more certs
assert_equal(ret['currentblockcert'], 0)
# block space used for nd txes is lower than max block size
assert_true(ret['currentblocksize'] < TEST_BLOCK_MAX_SIZE)
# block space used for txes is lower than tx partition
assert_true(ret['currentblocktx'] > 0)
assert_true(ret['currenttxpartitionused'] < TEST_BLOCK_TX_PARTITION_MAX_SIZE)

self.nodes[0].generate(1)
self.sync_all()
ret = self.nodes[0].getmininginfo()

# no more certs nor txes, it took 3 blocks as expected to mine all of them
assert_equal(len(self.nodes[0].getrawmempool()), 0)
assert_equal(ret['currentblockcert'], 0)
assert_equal(ret['currentblocktx'], 0)


if __name__ == '__main__':
sc_block_partitions().main()

Loading