Skip to content

Commit

Permalink
Merge pull request #2156 from CounterpartyXCP/develop
Browse files Browse the repository at this point in the history
v10.3.2
  • Loading branch information
ouziel-slama authored Aug 11, 2024
2 parents 4434a4d + 0459b99 commit 929d8aa
Show file tree
Hide file tree
Showing 24 changed files with 325 additions and 274 deletions.
15 changes: 6 additions & 9 deletions apiary.apib
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
[//]: # (Generated by genapidoc.py on 2024-07-26 10:25:25.518502. Do not edit manually.)
[//]: # (Generated by genapidoc.py on 2024-08-09 11:28:50.521779. Do not edit manually.)
FORMAT: 1A
HOST: https://api.counterparty.io:4000

Expand Down Expand Up @@ -1539,7 +1539,7 @@ Returns server information and the list of documented routes in JSON format.
"result": {
"server_ready": true,
"network": "mainnet",
"version": "10.3.1",
"version": "10.3.2",
"backend_height": 850214,
"counterparty_height": 850214,
"documentation": "https://counterpartycore.docs.apiary.io/",
Expand Down Expand Up @@ -3919,12 +3919,14 @@ Returns the transactions of a list of addresses
}
```

### Get Events By Addresses [GET /v2/addresses/events{?addresses}{&cursor}{&limit}{&offset}{&verbose}{&show_unconfirmed}]
### Get Events By Addresses [GET /v2/addresses/events{?addresses}{&event_name}{&cursor}{&limit}{&offset}{&verbose}{&show_unconfirmed}]

Returns the events of a list of addresses

+ Parameters
+ addresses: `1EC2K34dNc41pk63rc7bMQjbndqfoqQg4V,bc1q5mqesdy0gaj0suzxg4jx7ycmpw66kygdyn80mg` (str, required) - Comma separated list of addresses to return
+ event_name (str, optional) - Comma separated list of events to return
+ Default: `None`
+ cursor: `17629293` (int, optional) - The last event index to return
+ Default: `None`
+ limit: `5` (int, optional) - The maximum number of events to return
Expand Down Expand Up @@ -3968,7 +3970,6 @@ Returns the events of a list of addresses
},
"tx_hash": "2a64bb1c62e142e9b8aeca52e6ea4acac75af9b9eabd39de50b25c3c2260a181",
"block_index": 852611,
"confirmed": true,
"block_time": 1721218343
},
{
Expand All @@ -3994,7 +3995,6 @@ Returns the events of a list of addresses
},
"tx_hash": "2a64bb1c62e142e9b8aeca52e6ea4acac75af9b9eabd39de50b25c3c2260a181",
"block_index": 852611,
"confirmed": true,
"block_time": 1721218343
},
{
Expand Down Expand Up @@ -4024,7 +4024,6 @@ Returns the events of a list of addresses
},
"tx_hash": "6a7d9c1ec3ad23bede42cd7a7e591cf3dc32363c48b626c15770dc735c5bd4a4",
"block_index": 852611,
"confirmed": true,
"block_time": 1721218343
},
{
Expand All @@ -4050,7 +4049,6 @@ Returns the events of a list of addresses
},
"tx_hash": "6a7d9c1ec3ad23bede42cd7a7e591cf3dc32363c48b626c15770dc735c5bd4a4",
"block_index": 852611,
"confirmed": true,
"block_time": 1721218343
},
{
Expand All @@ -4076,12 +4074,11 @@ Returns the events of a list of addresses
},
"tx_hash": null,
"block_index": 852611,
"confirmed": true,
"block_time": 1721218343
}
],
"next_cursor": 17618356,
"result_count": 1682
"result_count": 1692
}
```

Expand Down
2 changes: 0 additions & 2 deletions counterparty-core/counterpartycore/lib/api/api_v1.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@
import re
import threading
import time
import traceback

import counterpartycore.lib.sentry as sentry # noqa: F401
import flask
Expand Down Expand Up @@ -580,7 +579,6 @@ def create_method(**kwargs):
# TypeError happens when unexpected keyword arguments are passed in
error_msg = f"Error composing {tx} transaction via API: {str(error)}"
logging.warning(error_msg)
logging.warning(traceback.format_exc())
raise JSONRPCDispatchException( # noqa: B904
code=JSON_RPC_ERROR_API_COMPOSE, message=error_msg
)
Expand Down
22 changes: 12 additions & 10 deletions counterparty-core/counterpartycore/lib/api/api_watcher.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
from counterpartycore.lib import blocks, config, database, exceptions, ledger
from counterpartycore.lib.api import util
from counterpartycore.lib.util import format_duration
from sentry_sdk import capture_exception
from yoyo import get_backend, read_migrations
from yoyo.exceptions import LockTimeout

Expand Down Expand Up @@ -778,8 +777,7 @@ def synchronize_mempool(api_db, ledger_db):
execute_event(api_db, event)
update_assets_info(api_db, event)
else:
logger.warning(f"Skipping duplicate event: {event}")
capture_exception(e)
# Skipping duplicate event
MEMPOOL_SKIP_EVENT_HASHES.append(event["tx_hash"])
except Exception as e:
logger.error(f"API Watcher - Error executing mempool event: {e}")
Expand Down Expand Up @@ -811,10 +809,14 @@ def __init__(self):
self.api_db.execute("PRAGMA foreign_keys=OFF")
# Create XCP and BTC assets if they don't exist
cursor = self.api_db.cursor()
cursor.execute("""SELECT * FROM assets WHERE asset_name = ?""", ("BTC",))
cursor.execute("""SELECT * FROM assets_info WHERE asset = ?""", ("XCP",))
if not list(cursor):
cursor.execute("""INSERT INTO assets VALUES (?,?,?,?)""", ("0", "BTC", None, None))
cursor.execute("""INSERT INTO assets VALUES (?,?,?,?)""", ("1", "XCP", None, None))
cursor.execute(
"""INSERT OR REPLACE INTO assets VALUES (?,?,?,?)""", ("0", "BTC", None, None)
)
cursor.execute(
"""INSERT OR REPLACE INTO assets VALUES (?,?,?,?)""", ("1", "XCP", None, None)
)
insert_asset_info_sql = """
INSERT INTO assets_info (
asset, divisible, locked, supply, description,
Expand All @@ -829,11 +831,11 @@ def __init__(self):
{
"asset": "XCP",
"divisible": True,
"locked": False,
"supply": 0,
"locked": True,
"supply": ledger.xcp_supply(self.ledger_db),
"description": "The Counterparty protocol native currency",
"first_issuance_block_index": 0,
"last_issuance_block_index": 0,
"first_issuance_block_index": 278319,
"last_issuance_block_index": 283810,
},
)

Expand Down
2 changes: 2 additions & 0 deletions counterparty-core/counterpartycore/lib/api/queries.py
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,8 @@ def select_rows(
"balances",
"address_events",
"asset_holders",
"xcp_holders",
"messages",
]

if where_clause:
Expand Down
2 changes: 2 additions & 0 deletions counterparty-core/counterpartycore/lib/api/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -285,6 +285,8 @@ def to_json(obj, indent=None):

def divide(value1, value2):
decimal.getcontext().prec = 8
if value2 == 0:
return D(0)
return D(value1) / D(value2)


Expand Down
2 changes: 2 additions & 0 deletions counterparty-core/counterpartycore/lib/blocks.py
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,7 @@ def parse_tx(db, tx):
def replay_transactions_events(db, transactions):
cursor = db.cursor()
for tx in transactions:
util.CURRENT_TX_HASH = tx["tx_hash"]
transaction_bindings = {
"tx_index": tx["tx_index"],
"tx_hash": tx["tx_hash"],
Expand Down Expand Up @@ -263,6 +264,7 @@ def replay_transactions_events(db, transactions):
"NEW_TRANSACTION_OUTPUT",
transaction_outputs_bindings,
)
util.CURRENT_TX_HASH = None


def parse_block(
Expand Down
8 changes: 4 additions & 4 deletions counterparty-core/counterpartycore/lib/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@


# Semantic Version
__version__ = "10.3.1" # for hatch
__version__ = "10.3.2" # for hatch
VERSION_STRING = __version__
version = VERSION_STRING.split("-")[0].split(".")
VERSION_MAJOR = int(version[0])
Expand Down Expand Up @@ -59,11 +59,11 @@
DEFAULT_RPC_PORT_TESTNET = 14100
DEFAULT_RPC_PORT = 4100

DEFAULT_BACKEND_PORT_REGTEST = 28332
DEFAULT_BACKEND_PORT_REGTEST = 18443
DEFAULT_BACKEND_PORT_TESTNET = 18332
DEFAULT_BACKEND_PORT = 8332

DEFAULT_INDEXD_PORT_REGTEST = 28432
DEFAULT_INDEXD_PORT_REGTEST = 18543
DEFAULT_INDEXD_PORT_TESTNET = 18432
DEFAULT_INDEXD_PORT = 8432

Expand Down Expand Up @@ -114,7 +114,7 @@
BURN_START_MAINNET = 278310
BURN_END_MAINNET = 283810

BLOCK_FIRST_REGTEST = 0
BLOCK_FIRST_REGTEST = 1
BLOCK_FIRST_REGTEST_HASH = "0f9188f13cb7b2c71f2a335e3a4fc328bf5beb436012afca590b1a11466e2206"
BURN_START_REGTEST = 101
BURN_END_REGTEST = 150000000
Expand Down
2 changes: 1 addition & 1 deletion counterparty-core/counterpartycore/lib/follow.py
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,7 @@ async def handle(self):
# sequence topic
await self.receive_multipart(self.zmq_sub_socket_sequence, "sequence")
# check rawblock topic
check_block_delay = 0.5 if config.TESTNET else 10
check_block_delay = 10 if config.NETWORK_NAME == "mainnet" else 0.5
if time.time() - self.last_block_check_time > check_block_delay:
await self.receive_multipart(self.zmq_sub_socket_rawblock, "rawblock")
self.last_block_check_time = time.time()
Expand Down
51 changes: 45 additions & 6 deletions counterparty-core/counterpartycore/lib/log.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
import zmq
from dateutil.tz import tzlocal
from halo import Halo
from json_log_formatter import VerboseJSONFormatter
from json_log_formatter import JSONFormatter
from termcolor import colored, cprint

from counterpartycore.lib import config, util
Expand Down Expand Up @@ -62,6 +62,8 @@ class CustomFormatter(logging.Formatter):

def format(self, record):
attrs = ["bold"] if hasattr(record, "bold") else []

time_format = colored("%(asctime)s", attrs=attrs)
level_name_format = colored("%(levelname)8s", self.COLORS.get(record.levelno), attrs=attrs)

if (
Expand All @@ -70,11 +72,15 @@ def format(self, record):
and "/counterpartycore/lib/messages/" in record.pathname
):
if util.PARSING_MEMPOOL:
log_format = f"%(asctime)s - [{level_name_format}] - Mempool - %(message)s"
log_message = "Mempool - %(message)s"
else:
log_format = f"%(asctime)s - [{level_name_format}] - Block {util.CURRENT_BLOCK_INDEX} - %(message)s"
log_message = f"Block {util.CURRENT_BLOCK_INDEX} - %(message)s"
else:
log_format = f"%(asctime)s - [{level_name_format}] - %(message)s"
log_message = "%(message)s"
if hasattr(record, "bold"):
log_message = colored(log_message, attrs=attrs)

log_format = f"{time_format} - [{level_name_format}] - {log_message}"

formatter = logging.Formatter(log_format)
if isinstance(record.args, dict):
Expand All @@ -83,6 +89,39 @@ def format(self, record):
return formatter.format(record)


class CustomisedJSONFormatter(JSONFormatter):
def json_record(self, message: str, extra: dict, record: logging.LogRecord) -> dict:
extra["filename"] = record.filename
extra["funcName"] = record.funcName
extra["levelname"] = record.levelname
extra["lineno"] = record.lineno
extra["module"] = record.module
extra["name"] = record.name
extra["pathname"] = record.pathname
extra["process"] = record.process
extra["processName"] = record.processName
if hasattr(record, "stack_info"):
extra["stack_info"] = record.stack_info
else:
extra["stack_info"] = None
extra["thread"] = record.thread
extra["threadName"] = record.threadName

if (
record.levelno != logging.EVENT
and util.CURRENT_BLOCK_INDEX is not None
and "/counterpartycore/lib/messages/" in record.pathname
):
if util.PARSING_MEMPOOL:
extra["block_index"] = "Mempool"
else:
extra["block_index"] = util.CURRENT_BLOCK_INDEX
else:
extra["block_index"] = None

return super(CustomisedJSONFormatter, self).json_record(message, extra, record)


def set_up(verbose=0, quiet=True, log_file=None, json_logs=False):
logging.Logger.trace = trace
logging.Logger.event = event
Expand Down Expand Up @@ -114,14 +153,14 @@ def set_up(verbose=0, quiet=True, log_file=None, json_logs=False):
max_log_size = 20 * 1024 * 1024 # 20 MB
fileh = RotatingFileHandler(log_file, maxBytes=max_log_size, backupCount=5)
fileh.setLevel(logging.TRACE)
fileh.setFormatter(VerboseJSONFormatter())
fileh.setFormatter(CustomisedJSONFormatter())
logger.addHandler(fileh)

if config.LOG_IN_CONSOLE:
console = logging.StreamHandler()
console.setLevel(log_level)
if json_logs:
console.setFormatter(VerboseJSONFormatter())
console.setFormatter(CustomisedJSONFormatter())
else:
console.setFormatter(CustomFormatter())
logger.addHandler(console)
Expand Down
15 changes: 11 additions & 4 deletions counterparty-core/counterpartycore/lib/messages/order.py
Original file line number Diff line number Diff line change
Expand Up @@ -967,9 +967,7 @@ def match(db, tx, block_index=None):
return


def expire(db, block_index):
cursor = db.cursor()

def expire_orders(db, block_index):
# Expire orders and give refunds for the quantity give_remaining (if non-zero; if not BTC).
orders = ledger.get_orders_to_expire(db, block_index)
# Edge case: filled orders, and therefore not expired in the previous block,
Expand All @@ -979,6 +977,8 @@ def expire(db, block_index):
for order in orders:
cancel_order(db, order, "expired", block_index, 0) # tx_index=0 for block action


def expire_order_matches(db, block_index):
# Expire order_matches for BTC with no BTC.
order_matches = ledger.get_order_matches_to_expire(db, block_index)
for order_match in order_matches:
Expand Down Expand Up @@ -1015,4 +1015,11 @@ def expire(db, block_index):
match(db, ledger.get_order(db, order_hash=order_match["tx0_hash"])[0], block_index)
match(db, ledger.get_order(db, order_hash=order_match["tx1_hash"])[0], block_index)

cursor.close()

def expire(db, block_index):
# if util.enabled("expire_order_matches_then_orders"):
# expire_order_matches(db, block_index)
# expire_orders(db, block_index)
# else:
expire_orders(db, block_index)
expire_order_matches(db, block_index)
23 changes: 16 additions & 7 deletions counterparty-core/counterpartycore/lib/telemetry/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import time
from uuid import uuid4

import appdirs
from counterpartycore.lib import config

start_time = time.time()
Expand Down Expand Up @@ -49,22 +50,30 @@ def __read_config_with_default(key, default):
return getattr(config, key, default)


NODE_UUID_FILENAME = ".counterparty-node-uuid"
NODE_UUID_FILEPATH = os.path.join(os.path.expanduser("~"), NODE_UUID_FILENAME)


class ID:
def __init__(self):
# if file exists, read id from file
# else create new id and write to file
id = None

if os.path.exists(NODE_UUID_FILEPATH):
with open(NODE_UUID_FILEPATH) as f:
state_dir = appdirs.user_state_dir(
appauthor=config.XCP_NAME, appname=config.APP_NAME, roaming=True
)
if not os.path.isdir(state_dir):
os.makedirs(state_dir, mode=0o755)
node_uid_filepath = os.path.join(state_dir, ".counterparty-node-uuid")

# Migrate old file
node_uid_old_filepath = os.path.join(os.path.expanduser("~"), ".counterparty-node-uuid")
if os.path.exists(node_uid_old_filepath):
os.rename(node_uid_old_filepath, node_uid_filepath)

if os.path.exists(node_uid_filepath):
with open(node_uid_filepath) as f:
id = f.read()
else:
id = str(uuid4())
with open(NODE_UUID_FILEPATH, "w") as f:
with open(node_uid_filepath, "w") as f:
f.write(id)

self.id = id
Loading

0 comments on commit 929d8aa

Please sign in to comment.