Litecoin: Protocol and default settings
0) Adjust BIP16 & BIP30 enforcement values 1) Reduce amount that peers can adjust our time to eliminate an attack vector. Thanks to coblee for this fix. 2) Zeitgeist2 patch - thanks to Lolcust and ArtForz. This fixes an issue where a 51% attack can change difficulty at will. Go back the full period unless it's the first retarget after genesis. 3) Avoid overflow in CalculateNextWorkRequired(). Thanks to pooler for the overflow fix. 4) SegWit ContextualCheckBlockHeader adjustment and extra coverage 5) Reject peer proto version below 70002. Thanks to wtogami for this patch. 6) Adjust default settings for Litecoin
This commit is contained in:
parent
837ee5b597
commit
b41ecc6feb
@ -44,11 +44,11 @@
|
||||
|
||||
# Use as many addnode= settings as you like to connect to specific peers
|
||||
#addnode=69.164.218.197
|
||||
#addnode=10.0.0.2:8333
|
||||
#addnode=10.0.0.2:9333
|
||||
|
||||
# Alternatively use as many connect= settings as you like to connect ONLY to specific peers
|
||||
#connect=69.164.218.197
|
||||
#connect=10.0.0.1:8333
|
||||
#connect=10.0.0.1:9333
|
||||
|
||||
# Listening mode, enabled by default except when 'connect' is being used
|
||||
#listen=1
|
||||
@ -110,7 +110,7 @@
|
||||
#rpcallowip=2001:db8:85a3:0:0:8a2e:370:7334/96
|
||||
|
||||
# Listen for RPC connections on this TCP port:
|
||||
#rpcport=8332
|
||||
#rpcport=9332
|
||||
|
||||
# You can use Bitcoin or bitcoind to send commands to Bitcoin/bitcoind
|
||||
# running on another host using this option:
|
||||
|
||||
@ -3,8 +3,8 @@ rpcuser=someuser
|
||||
rpcpassword=somepassword
|
||||
#datadir=~/.bitcoin
|
||||
host=127.0.0.1
|
||||
port=8332
|
||||
#port=18332
|
||||
port=9332
|
||||
#port=19332
|
||||
|
||||
# bootstrap.dat hashlist settings (linearize-hashes)
|
||||
max_height=313000
|
||||
|
||||
@ -125,7 +125,7 @@ if __name__ == '__main__':
|
||||
if 'host' not in settings:
|
||||
settings['host'] = '127.0.0.1'
|
||||
if 'port' not in settings:
|
||||
settings['port'] = 8332
|
||||
settings['port'] = 9332
|
||||
if 'min_height' not in settings:
|
||||
settings['min_height'] = 0
|
||||
if 'max_height' not in settings:
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
### QoS (Quality of service) ###
|
||||
### Qos ###
|
||||
|
||||
This is a Linux bash script that will set up tc to limit the outgoing bandwidth for connections to the Bitcoin network. It limits outbound TCP traffic with a source or destination port of 8333, but not if the destination IP is within a LAN.
|
||||
This is a Linux bash script that will set up tc to limit the outgoing bandwidth for connections to the Litecoin network. It limits outbound TCP traffic with a source or destination port of 9333, but not if the destination IP is within a LAN (defined as 192.168.x.x).
|
||||
|
||||
This means one can have an always-on bitcoind instance running, and another local bitcoind/bitcoin-qt instance which connects to this node and receives blocks from it.
|
||||
This means one can have an always-on litecoind instance running, and another local litecoind/litecoin-qt instance which connects to this node and receives blocks from it.
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
# Copyright (c) 2017 The Bitcoin Core developers
|
||||
# Copyright (c) 2013 The Bitcoin Core developers
|
||||
# Distributed under the MIT software license, see the accompanying
|
||||
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
@ -6,12 +6,10 @@
|
||||
IF="eth0"
|
||||
#limit of the network interface in question
|
||||
LINKCEIL="1gbit"
|
||||
#limit outbound Bitcoin protocol traffic to this rate
|
||||
#limit outbound Litecoin protocol traffic to this rate
|
||||
LIMIT="160kbit"
|
||||
#defines the IPv4 address space for which you wish to disable rate limiting
|
||||
LOCALNET_V4="192.168.0.0/16"
|
||||
#defines the IPv6 address space for which you wish to disable rate limiting
|
||||
LOCALNET_V6="fe80::/10"
|
||||
#defines the address space for which you wish to disable rate limiting
|
||||
LOCALNET="192.168.0.0/16"
|
||||
|
||||
#delete existing rules
|
||||
tc qdisc del dev ${IF} root
|
||||
@ -30,12 +28,6 @@ tc class add dev ${IF} parent 1:1 classid 1:11 htb rate ${LIMIT} ceil ${LIMIT} p
|
||||
tc filter add dev ${IF} parent 1: protocol ip prio 1 handle 1 fw classid 1:10
|
||||
tc filter add dev ${IF} parent 1: protocol ip prio 2 handle 2 fw classid 1:11
|
||||
|
||||
if [ ! -z "${LOCALNET_V6}" ] ; then
|
||||
# v6 cannot have the same priority value as v4
|
||||
tc filter add dev ${IF} parent 1: protocol ipv6 prio 3 handle 1 fw classid 1:10
|
||||
tc filter add dev ${IF} parent 1: protocol ipv6 prio 4 handle 2 fw classid 1:11
|
||||
fi
|
||||
|
||||
#delete any existing rules
|
||||
#disable for now
|
||||
#ret=0
|
||||
@ -44,16 +36,10 @@ fi
|
||||
# ret=$?
|
||||
#done
|
||||
|
||||
#limit outgoing traffic to and from port 8333. but not when dealing with a host on the local network
|
||||
# (defined by $LOCALNET_V4 and $LOCALNET_V6)
|
||||
# --set-mark marks packages matching these criteria with the number "2" (v4)
|
||||
# --set-mark marks packages matching these criteria with the number "4" (v6)
|
||||
# these packets are filtered by the tc filter with "handle 2"
|
||||
#limit outgoing traffic to and from port 9333. but not when dealing with a host on the local network
|
||||
# (defined by $LOCALNET)
|
||||
# --set-mark marks packages matching these criteria with the number "2"
|
||||
# these packages are filtered by the tc filter with "handle 2"
|
||||
# this filter sends the packages into the 1:11 class, and this class is limited to ${LIMIT}
|
||||
iptables -t mangle -A OUTPUT -p tcp -m tcp --dport 8333 ! -d ${LOCALNET_V4} -j MARK --set-mark 0x2
|
||||
iptables -t mangle -A OUTPUT -p tcp -m tcp --sport 8333 ! -d ${LOCALNET_V4} -j MARK --set-mark 0x2
|
||||
|
||||
if [ ! -z "${LOCALNET_V6}" ] ; then
|
||||
ip6tables -t mangle -A OUTPUT -p tcp -m tcp --dport 8333 ! -d ${LOCALNET_V6} -j MARK --set-mark 0x4
|
||||
ip6tables -t mangle -A OUTPUT -p tcp -m tcp --sport 8333 ! -d ${LOCALNET_V6} -j MARK --set-mark 0x4
|
||||
fi
|
||||
iptables -t mangle -A OUTPUT -p tcp -m tcp --dport 9333 ! -d ${LOCALNET} -j MARK --set-mark 0x2
|
||||
iptables -t mangle -A OUTPUT -p tcp -m tcp --sport 9333 ! -d ${LOCALNET} -j MARK --set-mark 0x2
|
||||
|
||||
@ -332,10 +332,10 @@ if [ `%{_sbindir}/sestatus |grep -c "disabled"` -eq 0 ]; then
|
||||
for selinuxvariant in %{selinux_variants}; do
|
||||
%{_sbindir}/semodule -s ${selinuxvariant} -i %{_datadir}/selinux/${selinuxvariant}/bitcoin.pp &> /dev/null || :
|
||||
done
|
||||
%{_sbindir}/semanage port -a -t bitcoin_port_t -p tcp 8332
|
||||
%{_sbindir}/semanage port -a -t bitcoin_port_t -p tcp 8333
|
||||
%{_sbindir}/semanage port -a -t bitcoin_port_t -p tcp 18332
|
||||
%{_sbindir}/semanage port -a -t bitcoin_port_t -p tcp 18333
|
||||
%{_sbindir}/semanage port -a -t bitcoin_port_t -p tcp 9332
|
||||
%{_sbindir}/semanage port -a -t bitcoin_port_t -p tcp 9333
|
||||
%{_sbindir}/semanage port -a -t bitcoin_port_t -p tcp 19332
|
||||
%{_sbindir}/semanage port -a -t bitcoin_port_t -p tcp 19333
|
||||
%{_sbindir}/fixfiles -R bitcoin-server restore &> /dev/null || :
|
||||
%{_sbindir}/restorecon -R %{_localstatedir}/lib/bitcoin || :
|
||||
fi
|
||||
@ -351,10 +351,10 @@ fi
|
||||
# SELinux
|
||||
if [ $1 -eq 0 ]; then
|
||||
if [ `%{_sbindir}/sestatus |grep -c "disabled"` -eq 0 ]; then
|
||||
%{_sbindir}/semanage port -d -p tcp 8332
|
||||
%{_sbindir}/semanage port -d -p tcp 8333
|
||||
%{_sbindir}/semanage port -d -p tcp 18332
|
||||
%{_sbindir}/semanage port -d -p tcp 18333
|
||||
%{_sbindir}/semanage port -d -p tcp 9332
|
||||
%{_sbindir}/semanage port -d -p tcp 9333
|
||||
%{_sbindir}/semanage port -d -p tcp 19332
|
||||
%{_sbindir}/semanage port -d -p tcp 19333
|
||||
for selinuxvariant in %{selinux_variants}; do
|
||||
%{_sbindir}/semodule -s ${selinuxvariant} -r bitcoin &> /dev/null || :
|
||||
done
|
||||
|
||||
@ -127,10 +127,10 @@ def main():
|
||||
g.write(' * IPv4 as well as onion addresses are wrapped inside a IPv6 address accordingly.\n')
|
||||
g.write(' */\n')
|
||||
with open(os.path.join(indir,'nodes_main.txt'),'r') as f:
|
||||
process_nodes(g, f, 'pnSeed6_main', 8333)
|
||||
process_nodes(g, f, 'pnSeed6_main', 9333)
|
||||
g.write('\n')
|
||||
with open(os.path.join(indir,'nodes_test.txt'),'r') as f:
|
||||
process_nodes(g, f, 'pnSeed6_test', 18333)
|
||||
process_nodes(g, f, 'pnSeed6_test', 19333)
|
||||
g.write('#endif // BITCOIN_CHAINPARAMSSEEDS_H\n')
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
||||
270
contrib/spendfrom/spendfrom.py
Executable file
270
contrib/spendfrom/spendfrom.py
Executable file
@ -0,0 +1,270 @@
|
||||
#!/usr/bin/env python
|
||||
# Copyright (c) 2013 The Bitcoin Core developers
|
||||
# Distributed under the MIT software license, see the accompanying
|
||||
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
#
|
||||
# Use the raw transactions API to spend bitcoins received on particular addresses,
|
||||
# and send any change back to that same address.
|
||||
#
|
||||
# Example usage:
|
||||
# spendfrom.py # Lists available funds
|
||||
# spendfrom.py --from=ADDRESS --to=ADDRESS --amount=11.00
|
||||
#
|
||||
# Assumes it will talk to a bitcoind or Bitcoin-Qt running
|
||||
# on localhost.
|
||||
#
|
||||
# Depends on jsonrpc
|
||||
#
|
||||
|
||||
from decimal import *
|
||||
import getpass
|
||||
import math
|
||||
import os
|
||||
import os.path
|
||||
import platform
|
||||
import sys
|
||||
import time
|
||||
from jsonrpc import ServiceProxy, json
|
||||
|
||||
BASE_FEE=Decimal("0.001")
|
||||
|
||||
def check_json_precision():
|
||||
"""Make sure json library being used does not lose precision converting BTC values"""
|
||||
n = Decimal("20000000.00000003")
|
||||
satoshis = int(json.loads(json.dumps(float(n)))*1.0e8)
|
||||
if satoshis != 2000000000000003:
|
||||
raise RuntimeError("JSON encode/decode loses precision")
|
||||
|
||||
def determine_db_dir():
|
||||
"""Return the default location of the bitcoin data directory"""
|
||||
if platform.system() == "Darwin":
|
||||
return os.path.expanduser("~/Library/Application Support/Bitcoin/")
|
||||
elif platform.system() == "Windows":
|
||||
return os.path.join(os.environ['APPDATA'], "Bitcoin")
|
||||
return os.path.expanduser("~/.bitcoin")
|
||||
|
||||
def read_bitcoin_config(dbdir):
|
||||
"""Read the bitcoin.conf file from dbdir, returns dictionary of settings"""
|
||||
from ConfigParser import SafeConfigParser
|
||||
|
||||
class FakeSecHead(object):
|
||||
def __init__(self, fp):
|
||||
self.fp = fp
|
||||
self.sechead = '[all]\n'
|
||||
def readline(self):
|
||||
if self.sechead:
|
||||
try: return self.sechead
|
||||
finally: self.sechead = None
|
||||
else:
|
||||
s = self.fp.readline()
|
||||
if s.find('#') != -1:
|
||||
s = s[0:s.find('#')].strip() +"\n"
|
||||
return s
|
||||
|
||||
config_parser = SafeConfigParser()
|
||||
config_parser.readfp(FakeSecHead(open(os.path.join(dbdir, "bitcoin.conf"))))
|
||||
return dict(config_parser.items("all"))
|
||||
|
||||
def connect_JSON(config):
|
||||
"""Connect to a bitcoin JSON-RPC server"""
|
||||
testnet = config.get('testnet', '0')
|
||||
testnet = (int(testnet) > 0) # 0/1 in config file, convert to True/False
|
||||
if not 'rpcport' in config:
|
||||
config['rpcport'] = 19332 if testnet else 9332
|
||||
connect = "http://%s:%s@127.0.0.1:%s"%(config['rpcuser'], config['rpcpassword'], config['rpcport'])
|
||||
try:
|
||||
result = ServiceProxy(connect)
|
||||
# ServiceProxy is lazy-connect, so send an RPC command mostly to catch connection errors,
|
||||
# but also make sure the bitcoind we're talking to is/isn't testnet:
|
||||
if result.getmininginfo()['testnet'] != testnet:
|
||||
sys.stderr.write("RPC server at "+connect+" testnet setting mismatch\n")
|
||||
sys.exit(1)
|
||||
return result
|
||||
except:
|
||||
sys.stderr.write("Error connecting to RPC server at "+connect+"\n")
|
||||
sys.exit(1)
|
||||
|
||||
def unlock_wallet(bitcoind):
|
||||
info = bitcoind.getinfo()
|
||||
if 'unlocked_until' not in info:
|
||||
return True # wallet is not encrypted
|
||||
t = int(info['unlocked_until'])
|
||||
if t <= time.time():
|
||||
try:
|
||||
passphrase = getpass.getpass("Wallet is locked; enter passphrase: ")
|
||||
bitcoind.walletpassphrase(passphrase, 5)
|
||||
except:
|
||||
sys.stderr.write("Wrong passphrase\n")
|
||||
|
||||
info = bitcoind.getinfo()
|
||||
return int(info['unlocked_until']) > time.time()
|
||||
|
||||
def list_available(bitcoind):
|
||||
address_summary = dict()
|
||||
|
||||
address_to_account = dict()
|
||||
for info in bitcoind.listreceivedbyaddress(0):
|
||||
address_to_account[info["address"]] = info["account"]
|
||||
|
||||
unspent = bitcoind.listunspent(0)
|
||||
for output in unspent:
|
||||
# listunspent doesn't give addresses, so:
|
||||
rawtx = bitcoind.getrawtransaction(output['txid'], 1)
|
||||
vout = rawtx["vout"][output['vout']]
|
||||
pk = vout["scriptPubKey"]
|
||||
|
||||
# This code only deals with ordinary pay-to-bitcoin-address
|
||||
# or pay-to-script-hash outputs right now; anything exotic is ignored.
|
||||
if pk["type"] != "pubkeyhash" and pk["type"] != "scripthash":
|
||||
continue
|
||||
|
||||
address = pk["addresses"][0]
|
||||
if address in address_summary:
|
||||
address_summary[address]["total"] += vout["value"]
|
||||
address_summary[address]["outputs"].append(output)
|
||||
else:
|
||||
address_summary[address] = {
|
||||
"total" : vout["value"],
|
||||
"outputs" : [output],
|
||||
"account" : address_to_account.get(address, "")
|
||||
}
|
||||
|
||||
return address_summary
|
||||
|
||||
def select_coins(needed, inputs):
|
||||
# Feel free to improve this, this is good enough for my simple needs:
|
||||
outputs = []
|
||||
have = Decimal("0.0")
|
||||
n = 0
|
||||
while have < needed and n < len(inputs):
|
||||
outputs.append({ "txid":inputs[n]["txid"], "vout":inputs[n]["vout"]})
|
||||
have += inputs[n]["amount"]
|
||||
n += 1
|
||||
return (outputs, have-needed)
|
||||
|
||||
def create_tx(bitcoind, fromaddresses, toaddress, amount, fee):
|
||||
all_coins = list_available(bitcoind)
|
||||
|
||||
total_available = Decimal("0.0")
|
||||
needed = amount+fee
|
||||
potential_inputs = []
|
||||
for addr in fromaddresses:
|
||||
if addr not in all_coins:
|
||||
continue
|
||||
potential_inputs.extend(all_coins[addr]["outputs"])
|
||||
total_available += all_coins[addr]["total"]
|
||||
|
||||
if total_available < needed:
|
||||
sys.stderr.write("Error, only %f BTC available, need %f\n"%(total_available, needed));
|
||||
sys.exit(1)
|
||||
|
||||
#
|
||||
# Note:
|
||||
# Python's json/jsonrpc modules have inconsistent support for Decimal numbers.
|
||||
# Instead of wrestling with getting json.dumps() (used by jsonrpc) to encode
|
||||
# Decimals, I'm casting amounts to float before sending them to bitcoind.
|
||||
#
|
||||
outputs = { toaddress : float(amount) }
|
||||
(inputs, change_amount) = select_coins(needed, potential_inputs)
|
||||
if change_amount > BASE_FEE: # don't bother with zero or tiny change
|
||||
change_address = fromaddresses[-1]
|
||||
if change_address in outputs:
|
||||
outputs[change_address] += float(change_amount)
|
||||
else:
|
||||
outputs[change_address] = float(change_amount)
|
||||
|
||||
rawtx = bitcoind.createrawtransaction(inputs, outputs)
|
||||
signed_rawtx = bitcoind.signrawtransaction(rawtx)
|
||||
if not signed_rawtx["complete"]:
|
||||
sys.stderr.write("signrawtransaction failed\n")
|
||||
sys.exit(1)
|
||||
txdata = signed_rawtx["hex"]
|
||||
|
||||
return txdata
|
||||
|
||||
def compute_amount_in(bitcoind, txinfo):
|
||||
result = Decimal("0.0")
|
||||
for vin in txinfo['vin']:
|
||||
in_info = bitcoind.getrawtransaction(vin['txid'], 1)
|
||||
vout = in_info['vout'][vin['vout']]
|
||||
result = result + vout['value']
|
||||
return result
|
||||
|
||||
def compute_amount_out(txinfo):
|
||||
result = Decimal("0.0")
|
||||
for vout in txinfo['vout']:
|
||||
result = result + vout['value']
|
||||
return result
|
||||
|
||||
def sanity_test_fee(bitcoind, txdata_hex, max_fee):
|
||||
class FeeError(RuntimeError):
|
||||
pass
|
||||
try:
|
||||
txinfo = bitcoind.decoderawtransaction(txdata_hex)
|
||||
total_in = compute_amount_in(bitcoind, txinfo)
|
||||
total_out = compute_amount_out(txinfo)
|
||||
if total_in-total_out > max_fee:
|
||||
raise FeeError("Rejecting transaction, unreasonable fee of "+str(total_in-total_out))
|
||||
|
||||
tx_size = len(txdata_hex)/2
|
||||
kb = tx_size/1000 # integer division rounds down
|
||||
if kb > 1 and fee < BASE_FEE:
|
||||
raise FeeError("Rejecting no-fee transaction, larger than 1000 bytes")
|
||||
if total_in < 0.01 and fee < BASE_FEE:
|
||||
raise FeeError("Rejecting no-fee, tiny-amount transaction")
|
||||
# Exercise for the reader: compute transaction priority, and
|
||||
# warn if this is a very-low-priority transaction
|
||||
|
||||
except FeeError as err:
|
||||
sys.stderr.write((str(err)+"\n"))
|
||||
sys.exit(1)
|
||||
|
||||
def main():
|
||||
import optparse
|
||||
|
||||
parser = optparse.OptionParser(usage="%prog [options]")
|
||||
parser.add_option("--from", dest="fromaddresses", default=None,
|
||||
help="addresses to get bitcoins from")
|
||||
parser.add_option("--to", dest="to", default=None,
|
||||
help="address to get send bitcoins to")
|
||||
parser.add_option("--amount", dest="amount", default=None,
|
||||
help="amount to send")
|
||||
parser.add_option("--fee", dest="fee", default="0.0",
|
||||
help="fee to include")
|
||||
parser.add_option("--datadir", dest="datadir", default=determine_db_dir(),
|
||||
help="location of bitcoin.conf file with RPC username/password (default: %default)")
|
||||
parser.add_option("--testnet", dest="testnet", default=False, action="store_true",
|
||||
help="Use the test network")
|
||||
parser.add_option("--dry_run", dest="dry_run", default=False, action="store_true",
|
||||
help="Don't broadcast the transaction, just create and print the transaction data")
|
||||
|
||||
(options, args) = parser.parse_args()
|
||||
|
||||
check_json_precision()
|
||||
config = read_bitcoin_config(options.datadir)
|
||||
if options.testnet: config['testnet'] = True
|
||||
bitcoind = connect_JSON(config)
|
||||
|
||||
if options.amount is None:
|
||||
address_summary = list_available(bitcoind)
|
||||
for address,info in address_summary.iteritems():
|
||||
n_transactions = len(info['outputs'])
|
||||
if n_transactions > 1:
|
||||
print("%s %.8f %s (%d transactions)"%(address, info['total'], info['account'], n_transactions))
|
||||
else:
|
||||
print("%s %.8f %s"%(address, info['total'], info['account']))
|
||||
else:
|
||||
fee = Decimal(options.fee)
|
||||
amount = Decimal(options.amount)
|
||||
while unlock_wallet(bitcoind) == False:
|
||||
pass # Keep asking for passphrase until they get it right
|
||||
txdata = create_tx(bitcoind, options.fromaddresses.split(","), options.to, amount, fee)
|
||||
sanity_test_fee(bitcoind, txdata, amount*Decimal("0.01"))
|
||||
if options.dry_run:
|
||||
print(txdata)
|
||||
else:
|
||||
txid = bitcoind.sendrawtransaction(txdata)
|
||||
print(txid)
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
@ -57,7 +57,7 @@ https://github.com/bitcoin/bips/blob/master/bip-0064.mediawiki
|
||||
|
||||
Example:
|
||||
```
|
||||
$ curl localhost:18332/rest/getutxos/checkmempool/b2cdfd7b89def827ff8af7cd9bff7627ff72e5e8b0f71210f92ea7a4000c5d75-0.json 2>/dev/null | json_pp
|
||||
$ curl localhost:19332/rest/getutxos/checkmempool/b2cdfd7b89def827ff8af7cd9bff7627ff72e5e8b0f71210f92ea7a4000c5d75-0.json 2>/dev/null | json_pp
|
||||
{
|
||||
"chainHeight" : 325347,
|
||||
"chaintipHash" : "00000000fb01a7f3745a717f8caebee056c484e6e0bfe4a9591c235bb70506fb",
|
||||
@ -99,4 +99,4 @@ Only supports JSON as output format.
|
||||
|
||||
Risks
|
||||
-------------
|
||||
Running a web browser on the same node with a REST enabled bitcoind can be a risk. Accessing prepared XSS websites could read out tx/block data of your node by placing links like `<script src="http://127.0.0.1:8332/rest/tx/1234567890.json">` which might break the nodes privacy.
|
||||
Running a web browser on the same node with a REST enabled bitcoind can be a risk. Accessing prepared XSS websites could read out tx/block data of your node by placing links like `<script src="http://127.0.0.1:9332/rest/tx/1234567890.json">` which might break the nodes privacy.
|
||||
|
||||
@ -195,7 +195,7 @@ Threads
|
||||
|
||||
- ThreadMapPort : Universal plug-and-play startup/shutdown
|
||||
|
||||
- ThreadSocketHandler : Sends/Receives data from peers on port 8333.
|
||||
- ThreadSocketHandler : Sends/Receives data from peers on port 9333.
|
||||
|
||||
- ThreadOpenAddedConnections : Opens network connections to added nodes.
|
||||
|
||||
@ -207,7 +207,7 @@ Threads
|
||||
|
||||
- ThreadFlushWalletDB : Close the wallet.dat file if it hasn't been used in 500ms.
|
||||
|
||||
- ThreadRPCServer : Remote procedure call handler, listens on port 8332 for connections and services them.
|
||||
- ThreadRPCServer : Remote procedure call handler, listens on port 9332 for connections and services them.
|
||||
|
||||
- BitcoinMiner : Generates bitcoins (if wallet is enabled).
|
||||
|
||||
|
||||
@ -42,11 +42,11 @@ reachable from the Tor network. Add these lines to your /etc/tor/torrc (or equiv
|
||||
config file):
|
||||
|
||||
HiddenServiceDir /var/lib/tor/bitcoin-service/
|
||||
HiddenServicePort 8333 127.0.0.1:8333
|
||||
HiddenServicePort 18333 127.0.0.1:18333
|
||||
HiddenServicePort 9333 127.0.0.1:9333
|
||||
HiddenServicePort 19333 127.0.0.1:19333
|
||||
|
||||
The directory can be different of course, but (both) port numbers should be equal to
|
||||
your bitcoind's P2P listen port (8333 by default).
|
||||
your bitcoind's P2P listen port (9333 by default).
|
||||
|
||||
-externalip=X You can tell bitcoin about its publicly reachable address using
|
||||
this option, and this can be a .onion address. Given the above
|
||||
@ -81,7 +81,7 @@ as well, use `discover` instead:
|
||||
|
||||
./bitcoind ... -discover
|
||||
|
||||
and open port 8333 on your firewall (or use -upnp).
|
||||
and open port 9333 on your firewall (or use -upnp).
|
||||
|
||||
If you only want to use Tor to reach onion addresses, but not use it as a proxy
|
||||
for normal IPv4/IPv6 communication, use:
|
||||
|
||||
@ -23,7 +23,7 @@ static const CAmount CENT = 1000000;
|
||||
* critical; in unusual circumstances like a(nother) overflow bug that allowed
|
||||
* for the creation of coins out of thin air modification could lead to a fork.
|
||||
* */
|
||||
static const CAmount MAX_MONEY = 21000000 * COIN;
|
||||
static const CAmount MAX_MONEY = 84000000 * COIN;
|
||||
inline bool MoneyRange(const CAmount& nValue) { return (nValue >= 0 && nValue <= MAX_MONEY); }
|
||||
|
||||
#endif // BITCOIN_AMOUNT_H
|
||||
|
||||
@ -27,7 +27,7 @@ static const unsigned int MAX_P2SH_SIGOPS = 15;
|
||||
/** The maximum number of sigops we're willing to relay/mine in a single tx */
|
||||
static const unsigned int MAX_STANDARD_TX_SIGOPS_COST = MAX_BLOCK_SIGOPS_COST/5;
|
||||
/** Default for -maxmempool, maximum megabytes of mempool memory usage */
|
||||
static const unsigned int DEFAULT_MAX_MEMPOOL_SIZE = 300;
|
||||
static const unsigned int DEFAULT_MAX_MEMPOOL_SIZE = 5;
|
||||
/** Default for -incrementalrelayfee, which sets the minimum feerate increase for mempool limiting or BIP 125 replacement **/
|
||||
static const unsigned int DEFAULT_INCREMENTAL_RELAY_FEE = 1000;
|
||||
/** Default for -bytespersigop */
|
||||
|
||||
25
src/pow.cpp
25
src/pow.cpp
@ -9,6 +9,7 @@
|
||||
#include "chain.h"
|
||||
#include "primitives/block.h"
|
||||
#include "uint256.h"
|
||||
#include "util.h"
|
||||
|
||||
unsigned int GetNextWorkRequired(const CBlockIndex* pindexLast, const CBlockHeader *pblock, const Consensus::Params& params)
|
||||
{
|
||||
@ -38,9 +39,17 @@ unsigned int GetNextWorkRequired(const CBlockIndex* pindexLast, const CBlockHead
|
||||
}
|
||||
|
||||
// Go back by what we want to be 14 days worth of blocks
|
||||
int nHeightFirst = pindexLast->nHeight - (params.DifficultyAdjustmentInterval()-1);
|
||||
assert(nHeightFirst >= 0);
|
||||
const CBlockIndex* pindexFirst = pindexLast->GetAncestor(nHeightFirst);
|
||||
// Litecoin: This fixes an issue where a 51% attack can change difficulty at will.
|
||||
// Go back the full period unless it's the first retarget after genesis. Code courtesy of Art Forz
|
||||
int blockstogoback = params.DifficultyAdjustmentInterval()-1;
|
||||
if ((pindexLast->nHeight+1) != params.DifficultyAdjustmentInterval())
|
||||
blockstogoback = params.DifficultyAdjustmentInterval();
|
||||
|
||||
// Go back by what we want to be 14 days worth of blocks
|
||||
const CBlockIndex* pindexFirst = pindexLast;
|
||||
for (int i = 0; pindexFirst && i < blockstogoback; i++)
|
||||
pindexFirst = pindexFirst->pprev;
|
||||
|
||||
assert(pindexFirst);
|
||||
|
||||
return CalculateNextWorkRequired(pindexLast, pindexFirst->GetBlockTime(), params);
|
||||
@ -59,12 +68,20 @@ unsigned int CalculateNextWorkRequired(const CBlockIndex* pindexLast, int64_t nF
|
||||
nActualTimespan = params.nPowTargetTimespan*4;
|
||||
|
||||
// Retarget
|
||||
const arith_uint256 bnPowLimit = UintToArith256(params.powLimit);
|
||||
arith_uint256 bnNew;
|
||||
arith_uint256 bnOld;
|
||||
bnNew.SetCompact(pindexLast->nBits);
|
||||
bnOld = bnNew;
|
||||
// Litecoin: intermediate uint256 can overflow by 1 bit
|
||||
bool fShift = bnNew.bits() > 235;
|
||||
if (fShift)
|
||||
bnNew >>= 1;
|
||||
bnNew *= nActualTimespan;
|
||||
bnNew /= params.nPowTargetTimespan;
|
||||
if (fShift)
|
||||
bnNew <<= 1;
|
||||
|
||||
const arith_uint256 bnPowLimit = UintToArith256(params.powLimit);
|
||||
if (bnNew > bnPowLimit)
|
||||
bnNew = bnPowLimit;
|
||||
|
||||
|
||||
@ -22,7 +22,7 @@
|
||||
|
||||
static const uint64_t GB_BYTES = 1000000000LL;
|
||||
/* Minimum free space (in GB) needed for data directory */
|
||||
static const uint64_t BLOCK_CHAIN_SIZE = 150;
|
||||
static const uint64_t BLOCK_CHAIN_SIZE = 8;
|
||||
/* Minimum free space (in GB) needed for data directory when pruned; Does not include prune target */
|
||||
static const uint64_t CHAIN_STATE_SIZE = 3;
|
||||
/* Total required space (in GB) depending on user choice (prune, not prune) */
|
||||
|
||||
@ -205,8 +205,8 @@ UniValue addnode(const JSONRPCRequest& request)
|
||||
"1. \"node\" (string, required) The node (see getpeerinfo for nodes)\n"
|
||||
"2. \"command\" (string, required) 'add' to add a node to the list, 'remove' to remove a node from the list, 'onetry' to try a connection to the node once\n"
|
||||
"\nExamples:\n"
|
||||
+ HelpExampleCli("addnode", "\"192.168.0.6:8333\" \"onetry\"")
|
||||
+ HelpExampleRpc("addnode", "\"192.168.0.6:8333\", \"onetry\"")
|
||||
+ HelpExampleCli("addnode", "\"192.168.0.6:9333\" \"onetry\"")
|
||||
+ HelpExampleRpc("addnode", "\"192.168.0.6:9333\", \"onetry\"")
|
||||
);
|
||||
|
||||
if(!g_connman)
|
||||
@ -294,7 +294,7 @@ UniValue getaddednodeinfo(const JSONRPCRequest& request)
|
||||
" \"connected\" : true|false, (boolean) If connected\n"
|
||||
" \"addresses\" : [ (list of objects) Only when connected = true\n"
|
||||
" {\n"
|
||||
" \"address\" : \"192.168.0.201:8333\", (string) The bitcoin server IP and port we're connected to\n"
|
||||
" \"address\" : \"192.168.0.201:9333\", (string) The litecoin server IP and port we're connected to\n"
|
||||
" \"connected\" : \"outbound\" (string) connection, inbound or outbound\n"
|
||||
" }\n"
|
||||
" ]\n"
|
||||
|
||||
@ -520,7 +520,7 @@ std::string HelpExampleCli(const std::string& methodname, const std::string& arg
|
||||
std::string HelpExampleRpc(const std::string& methodname, const std::string& args)
|
||||
{
|
||||
return "> curl --user myusername --data-binary '{\"jsonrpc\": \"1.0\", \"id\":\"curltest\", "
|
||||
"\"method\": \"" + methodname + "\", \"params\": [" + args + "] }' -H 'content-type: text/plain;' http://127.0.0.1:8332/\n";
|
||||
"\"method\": \"" + methodname + "\", \"params\": [" + args + "] }' -H 'content-type: text/plain;' http://127.0.0.1:9332/\n";
|
||||
}
|
||||
|
||||
void RPCSetTimerInterfaceIfUnset(RPCTimerInterface *iface)
|
||||
|
||||
@ -20,7 +20,7 @@
|
||||
#define NUM_MULTIPLES_1BTC 10000
|
||||
|
||||
// amounts 50 .. 21000000
|
||||
#define NUM_MULTIPLES_50BTC 420000
|
||||
#define NUM_MULTIPLES_50BTC 1680000
|
||||
|
||||
BOOST_FIXTURE_TEST_SUITE(compress_tests, BasicTestingSetup)
|
||||
|
||||
@ -44,7 +44,7 @@ BOOST_AUTO_TEST_CASE(compress_amounts)
|
||||
BOOST_CHECK(TestPair( CENT, 0x7));
|
||||
BOOST_CHECK(TestPair( COIN, 0x9));
|
||||
BOOST_CHECK(TestPair( 50*COIN, 0x32));
|
||||
BOOST_CHECK(TestPair(21000000*COIN, 0x1406f40));
|
||||
BOOST_CHECK(TestPair(84000000*COIN, 0x501BD00));
|
||||
|
||||
for (uint64_t i = 1; i <= NUM_MULTIPLES_UNIT; i++)
|
||||
BOOST_CHECK(TestEncode(i));
|
||||
|
||||
@ -381,7 +381,7 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity)
|
||||
}
|
||||
BOOST_CHECK(pblocktemplate = AssemblerForTest(chainparams).CreateNewBlock(scriptPubKey));
|
||||
// Extend to a 210000-long block chain.
|
||||
while (chainActive.Tip()->nHeight < 210000) {
|
||||
while (chainActive.Tip()->nHeight < 840000) {
|
||||
CBlockIndex* prev = chainActive.Tip();
|
||||
CBlockIndex* next = new CBlockIndex();
|
||||
next->phashBlock = new uint256(InsecureRand256());
|
||||
|
||||
@ -10,7 +10,7 @@
|
||||
#include <stdint.h>
|
||||
#include <vector>
|
||||
|
||||
static const int64_t DEFAULT_MAX_TIME_ADJUSTMENT = 70 * 60;
|
||||
static const int64_t DEFAULT_MAX_TIME_ADJUSTMENT = 35 * 60;
|
||||
|
||||
class CNetAddr;
|
||||
|
||||
|
||||
@ -1604,8 +1604,8 @@ static ThresholdConditionCache warningcache[VERSIONBITS_NUM_BITS];
|
||||
static unsigned int GetBlockScriptFlags(const CBlockIndex* pindex, const Consensus::Params& consensusparams) {
|
||||
AssertLockHeld(cs_main);
|
||||
|
||||
// BIP16 didn't become active until Apr 1 2012
|
||||
int64_t nBIP16SwitchTime = 1333238400;
|
||||
// BIP16 didn't become active until Oct 1 2012
|
||||
int64_t nBIP16SwitchTime = 1349049600;
|
||||
bool fStrictPayToScriptHash = (pindex->GetBlockTime() >= nBIP16SwitchTime);
|
||||
|
||||
unsigned int flags = fStrictPayToScriptHash ? SCRIPT_VERIFY_P2SH : SCRIPT_VERIFY_NONE;
|
||||
@ -1714,9 +1714,10 @@ static bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockInd
|
||||
// Now that the whole chain is irreversibly beyond that time it is applied to all blocks except the
|
||||
// two in the chain that violate it. This prevents exploiting the issue against nodes during their
|
||||
// initial block download.
|
||||
bool fEnforceBIP30 = (!pindex->phashBlock) || // Enforce on CreateNewBlock invocations which don't have a hash.
|
||||
!((pindex->nHeight==91842 && pindex->GetBlockHash() == uint256S("0x00000000000a4d0a398161ffc163c503763b1f4360639393e0e4c8e300e0caec")) ||
|
||||
(pindex->nHeight==91880 && pindex->GetBlockHash() == uint256S("0x00000000000743f190a18c5577a3c2d2a1f610ae9601ac046a38084ccb7cd721")));
|
||||
bool fEnforceBIP30 = true;
|
||||
//(!pindex->phashBlock) || // Enforce on CreateNewBlock invocations which don't have a hash.
|
||||
// !((pindex->nHeight==91842 && pindex->GetBlockHash() == uint256S("0x00000000000a4d0a398161ffc163c503763b1f4360639393e0e4c8e300e0caec")) ||
|
||||
// (pindex->nHeight==91880 && pindex->GetBlockHash() == uint256S("0x00000000000743f190a18c5577a3c2d2a1f610ae9601ac046a38084ccb7cd721")));
|
||||
|
||||
// Once BIP34 activated it was not possible to create new duplicate coinbases and thus other than starting
|
||||
// with the 2 existing duplicate coinbase pairs, not possible to create overwriting txs. But by the
|
||||
@ -2973,6 +2974,10 @@ static bool ContextualCheckBlockHeader(const CBlockHeader& block, CValidationSta
|
||||
return state.Invalid(false, REJECT_OBSOLETE, strprintf("bad-version(0x%08x)", block.nVersion),
|
||||
strprintf("rejected nVersion=0x%08x block", block.nVersion));
|
||||
|
||||
if (block.nVersion < VERSIONBITS_TOP_BITS && IsWitnessEnabled(pindexPrev, consensusParams))
|
||||
return state.Invalid(false, REJECT_OBSOLETE, strprintf("bad-version(0x%08x)", block.nVersion),
|
||||
strprintf("rejected nVersion=0x%08x block", block.nVersion));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@ -204,7 +204,7 @@ extern uint64_t nPruneTarget;
|
||||
/** Block files containing a block-height within MIN_BLOCKS_TO_KEEP of chainActive.Tip() will not be pruned. */
|
||||
static const unsigned int MIN_BLOCKS_TO_KEEP = 288;
|
||||
|
||||
static const signed int DEFAULT_CHECKBLOCKS = 6;
|
||||
static const signed int DEFAULT_CHECKBLOCKS = 6 * 4;
|
||||
static const unsigned int DEFAULT_CHECKLEVEL = 3;
|
||||
|
||||
// Require that user allocate at least 550MB for block & undo files (blk???.dat and rev???.dat)
|
||||
|
||||
@ -15,7 +15,7 @@ static const int PROTOCOL_VERSION = 70015;
|
||||
static const int INIT_PROTO_VERSION = 209;
|
||||
|
||||
//! In this version, 'getheaders' was introduced.
|
||||
static const int GETHEADERS_VERSION = 31800;
|
||||
static const int GETHEADERS_VERSION = 70002;
|
||||
|
||||
//! disconnect from peers older than this proto version
|
||||
static const int MIN_PEER_PROTO_VERSION = GETHEADERS_VERSION;
|
||||
|
||||
@ -22,6 +22,7 @@ from io import BytesIO
|
||||
import time
|
||||
|
||||
NULLDUMMY_ERROR = "64: non-mandatory-script-verify-flag (Dummy CHECKMULTISIG argument must be zero)"
|
||||
VB_TOP_BITS = 0x20000000
|
||||
|
||||
def trueDummy(tx):
|
||||
scriptSig = CScript(tx.vin[0].scriptSig)
|
||||
@ -93,7 +94,7 @@ class NULLDUMMYTest(BitcoinTestFramework):
|
||||
self.log.info("Test 6: NULLDUMMY compliant base/witness transactions should be accepted to mempool and in block after activation [432]")
|
||||
for i in test6txs:
|
||||
self.nodes[0].sendrawtransaction(bytes_to_hex_str(i.serialize_with_witness()), True)
|
||||
self.block_submit(self.nodes[0], test6txs, True, True)
|
||||
self.block_submit(self.nodes[0], test6txs, True, True, VB_TOP_BITS)
|
||||
|
||||
|
||||
def create_transaction(self, node, txid, to_address, amount):
|
||||
@ -107,9 +108,9 @@ class NULLDUMMYTest(BitcoinTestFramework):
|
||||
return tx
|
||||
|
||||
|
||||
def block_submit(self, node, txs, witness = False, accept = False):
|
||||
def block_submit(self, node, txs, witness = False, accept = False, version=4):
|
||||
block = create_block(self.tip, create_coinbase(self.lastblockheight + 1), self.lastblocktime + 1)
|
||||
block.nVersion = 4
|
||||
block.nVersion = version
|
||||
for tx in txs:
|
||||
tx.rehash()
|
||||
block.vtx.append(tx)
|
||||
|
||||
@ -122,7 +122,7 @@ class SegWitTest(BitcoinTestFramework):
|
||||
|
||||
''' Helpers '''
|
||||
# Build a block on top of node0's tip.
|
||||
def build_next_block(self, nVersion=4):
|
||||
def build_next_block(self, nVersion=VB_TOP_BITS):
|
||||
tip = self.nodes[0].getbestblockhash()
|
||||
height = self.nodes[0].getblockcount() + 1
|
||||
block_time = self.nodes[0].getblockheader(tip)["mediantime"] + 1
|
||||
@ -956,12 +956,11 @@ class SegWitTest(BitcoinTestFramework):
|
||||
assert(self.test_node.last_message["getdata"].inv[0].type == blocktype)
|
||||
self.test_node.test_witness_block(block1, True)
|
||||
|
||||
block2 = self.build_next_block(nVersion=4)
|
||||
block2.solve()
|
||||
# Litecoin: Blocks with nVersion < VB_TOP_BITS are rejected
|
||||
|
||||
self.test_node.announce_block_and_wait_for_getdata(block2, use_header=True)
|
||||
assert(self.test_node.last_message["getdata"].inv[0].type == blocktype)
|
||||
self.test_node.test_witness_block(block2, True)
|
||||
# self.test_node.announce_block_and_wait_for_getdata(block2, use_header=True)
|
||||
# assert(self.test_node.last_message["getdata"].inv[0].type == blocktype)
|
||||
# self.test_node.test_witness_block(block2, True)
|
||||
|
||||
block3 = self.build_next_block(nVersion=(VB_TOP_BITS | (1<<15)))
|
||||
block3.solve()
|
||||
@ -1014,7 +1013,8 @@ class SegWitTest(BitcoinTestFramework):
|
||||
assert_equal(rpc_details["weight"], weight)
|
||||
|
||||
# Upgraded node should not ask for blocks from unupgraded
|
||||
block4 = self.build_next_block(nVersion=4)
|
||||
# Litecoin: Blocks with nVersion < VB_TOP_BITS are rejected
|
||||
block4 = self.build_next_block(nVersion=(VB_TOP_BITS | (1<<15)))
|
||||
block4.solve()
|
||||
self.old_node.getdataset = set()
|
||||
|
||||
@ -1865,6 +1865,12 @@ class SegWitTest(BitcoinTestFramework):
|
||||
|
||||
self.utxo.pop(0)
|
||||
|
||||
def test_reject_blocks(self):
|
||||
print ("\tTesting rejection of block.nVersion < BIP9_TOP_BITS blocks")
|
||||
block = self.build_next_block(nVersion=4)
|
||||
block.solve()
|
||||
resp = self.nodes[0].submitblock(bytes_to_hex_str(block.serialize(True)))
|
||||
assert_equal(resp, 'bad-version(0x00000004)')
|
||||
|
||||
def run_test(self):
|
||||
# Setup the p2p connections and start up the network thread.
|
||||
@ -1924,6 +1930,7 @@ class SegWitTest(BitcoinTestFramework):
|
||||
sync_blocks(self.nodes)
|
||||
|
||||
# Test P2SH witness handling again
|
||||
self.test_reject_blocks()
|
||||
self.test_p2sh_witness(segwit_activated=True)
|
||||
self.test_witness_commitments()
|
||||
self.test_block_malleability()
|
||||
|
||||
@ -120,24 +120,24 @@ class ProxyTest(BitcoinTestFramework):
|
||||
|
||||
if test_onion:
|
||||
# Test: outgoing onion connection through node
|
||||
node.addnode("bitcoinostk4e4re.onion:8333", "onetry")
|
||||
node.addnode("bitcoinostk4e4re.onion:9333", "onetry")
|
||||
cmd = proxies[2].queue.get()
|
||||
assert(isinstance(cmd, Socks5Command))
|
||||
assert_equal(cmd.atyp, AddressType.DOMAINNAME)
|
||||
assert_equal(cmd.addr, b"bitcoinostk4e4re.onion")
|
||||
assert_equal(cmd.port, 8333)
|
||||
assert_equal(cmd.port, 9333)
|
||||
if not auth:
|
||||
assert_equal(cmd.username, None)
|
||||
assert_equal(cmd.password, None)
|
||||
rv.append(cmd)
|
||||
|
||||
# Test: outgoing DNS name connection through node
|
||||
node.addnode("node.noumenon:8333", "onetry")
|
||||
node.addnode("node.noumenon:9333", "onetry")
|
||||
cmd = proxies[3].queue.get()
|
||||
assert(isinstance(cmd, Socks5Command))
|
||||
assert_equal(cmd.atyp, AddressType.DOMAINNAME)
|
||||
assert_equal(cmd.addr, b"node.noumenon")
|
||||
assert_equal(cmd.port, 8333)
|
||||
assert_equal(cmd.port, 9333)
|
||||
if not auth:
|
||||
assert_equal(cmd.username, None)
|
||||
assert_equal(cmd.password, None)
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user