-
Notifications
You must be signed in to change notification settings - Fork 69
/
otsd
executable file
·177 lines (148 loc) · 7.03 KB
/
otsd
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
#!/usr/bin/env python3
# Copyright (C) 2016-2018 The OpenTimestamps developers
#
# This file is part of the OpenTimestamps Server.
#
# It is subject to the license terms in the LICENSE file found in the top-level
# directory of this distribution.
#
# No part of the OpenTimestamps Server, including this file, may be copied,
# modified, propagated, or distributed except according to the terms contained
# in the LICENSE file.
import argparse
import logging
import logging.handlers
import os
import queue
import sys
import threading
import time
import bitcoin
import bitcoin.core
from bitcoin.wallet import CBitcoinAddress
import otsserver.calendar
import otsserver.rpc
import otsserver.stamper
parser = argparse.ArgumentParser(description="OpenTimestamps Server")
parser.add_argument("-q", "--quiet", action="count", default=0,
help="Be more quiet.")
parser.add_argument("-v", "--verbose", action="count", default=0,
help="Be more verbose. Both -v and -q may be used multiple times.")
parser.add_argument("-c", "--calendar", type=str,
dest='calendar_path',
default='~/.otsd/calendar',
help="Location of the calendar (default: '%(default)s')")
parser.add_argument("--debug-file", type=str,
dest='debug_file',
default='~/.otsd/debug.log',
help="Location of the debug log")
parser.add_argument("--debug-file-max-size", type=int,
dest='debug_file_max_size',
default=10000000,
help="Max size of the debug log (default: %(default)d bytes) ")
parser.add_argument("--debug-file-backup-count", type=int,
dest='debug_file_backup_count',
default=10,
help="Number of debug log file backups (default: %(default)d bytes) ")
parser.add_argument("--debug-file-gmtime", action="store_true",
dest='debug_file_gmtime',
help="Use GMT/UTC time instead of local time in debug log file")
parser.add_argument("--rpc-port", type=int,
default=14788,
help="RPC port (default: %(default)d)")
parser.add_argument("--rpc-address", type=str,
default='localhost',
help="RPC address (default: %(default)s)")
parser.add_argument("--lightning-invoice-file", type=str,
help="file containing a lightning invoice without amount for donations")
parser.add_argument("--explorer-url", type=str,
default='https://mempool.space',
help="block explorer URL to use in the status page")
parser.add_argument("--max-pending", type=int,
default=100000,
help="Maximum number of pending commitments to timestamp at a time (default: %(default)s)")
parser.add_argument("--btc-min-relay-feerate", metavar='FEERATE', type=float,
default=1,
help="Minimum relay feerate (default: %(default).1f sat/vB)")
parser.add_argument("--btc-conf-target", metavar='N', type=int,
default=1008,
help="Confirmation target for the first timestamp transaction (will be RBF-replaced if not mined)"
" (default: %(default)d)")
parser.add_argument("--btc-min-confirmations", metavar='N', type=int,
default=6,
help="Confirmations required before we save a Bitcoin timestamp permanently, must be greater than 1"
" (default: %(default)d)")
parser.add_argument("--btc-min-tx-interval", metavar='SECONDS', type=int,
default=60*60*6,
help="Minimum interval between timestamp transactions (default: %(default)d seconds)")
parser.add_argument("--btc-max-fee", metavar='FEE', type=float,
default=0.001,
help="Maximum transaction fee (default: %(default).3f BTC)")
parser.add_argument("--btc-full-rbf", action='store_true',
default=False,
help="Do full-RBF replacements")
btc_net_group = parser.add_mutually_exclusive_group()
btc_net_group.add_argument('--btc-testnet', dest='btc_net', action='store_const',
const='testnet', default='mainnet',
help='Use Bitcoin testnet rather than mainnet')
btc_net_group.add_argument('--btc-regtest', dest='btc_net', action='store_const',
const='regtest',
help='Use Bitcoin regtest rather than mainnet')
args = parser.parse_args()
args.parser = parser
directory = os.path.expanduser("~/.otsd")
if not os.path.exists(directory):
os.makedirs(directory)
debugfile = os.path.expanduser(args.debug_file)
handler = logging.handlers.RotatingFileHandler(filename=debugfile, maxBytes=args.debug_file_max_size, backupCount=args.debug_file_backup_count)
fmt = logging.Formatter("%(asctime)-15s %(message)s")
handler.setFormatter(fmt)
logger = logging.getLogger('')
logger.addHandler(handler)
ch = logging.StreamHandler(sys.stdout)
logger.addHandler(ch)
if args.debug_file_gmtime:
logging.Formatter.converter = time.gmtime
args.verbosity = args.verbose - args.quiet
if args.verbosity == 0:
logging.root.setLevel(logging.INFO)
elif args.verbosity > 0:
logging.root.setLevel(logging.DEBUG)
elif args.verbosity == -1:
logging.root.setLevel(logging.WARNING)
elif args.verbosity < -1:
logging.root.setLevel(logging.ERROR)
if args.btc_net == 'testnet':
bitcoin.SelectParams('testnet')
elif args.btc_net == 'regtest':
bitcoin.SelectParams('regtest')
if not (1 <= args.btc_conf_target <= 1008):
args.parser.error("--btc-conf-target must be in range 1 <= N <= 1008")
exit_event = threading.Event()
calendar_path = os.path.expanduser(args.calendar_path)
with open(calendar_path + '/donation_addr', "r") as fd:
donation_address = fd.read().rstrip()
donation_address = CBitcoinAddress(donation_address)
calendar = otsserver.calendar.Calendar(calendar_path)
aggregator = otsserver.calendar.Aggregator(calendar, exit_event)
stamper = otsserver.stamper.Stamper(calendar, exit_event,
args.btc_conf_target,
args.btc_min_relay_feerate,
args.btc_min_confirmations,
args.btc_min_tx_interval,
args.btc_max_fee * bitcoin.core.COIN,
args.btc_full_rbf,
args.max_pending)
calendar.stamper = stamper
server = otsserver.rpc.StampServer((args.rpc_address, args.rpc_port),
aggregator,
calendar,
args.lightning_invoice_file,
donation_address,
args.explorer_url)
try:
server.serve_forever()
except KeyboardInterrupt:
exit_event.set()
sys.exit(0)
# vim:syntax=python filetype=python