Browse Source

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
0.15
Adrian Gallagher 8 years ago
parent
commit
b41ecc6feb
No known key found for this signature in database
GPG Key ID: FE3348877809386C
  1. 6
      contrib/debian/examples/bitcoin.conf
  2. 4
      contrib/linearize/example-linearize.cfg
  3. 2
      contrib/linearize/linearize-hashes.py
  4. 6
      contrib/qos/README.md
  5. 34
      contrib/qos/tc.sh
  6. 16
      contrib/rpm/bitcoin.spec
  7. 4
      contrib/seeds/generate-seeds.py
  8. 270
      contrib/spendfrom/spendfrom.py
  9. 4
      doc/REST-interface.md
  10. 4
      doc/developer-notes.md
  11. 8
      doc/tor.md
  12. 2
      src/amount.h
  13. 2
      src/policy/policy.h
  14. 25
      src/pow.cpp
  15. 2
      src/qt/intro.cpp
  16. 6
      src/rpc/net.cpp
  17. 2
      src/rpc/server.cpp
  18. 4
      src/test/compress_tests.cpp
  19. 2
      src/test/miner_tests.cpp
  20. 2
      src/timedata.h
  21. 15
      src/validation.cpp
  22. 2
      src/validation.h
  23. 2
      src/version.h
  24. 7
      test/functional/nulldummy.py
  25. 21
      test/functional/p2p-segwit.py
  26. 8
      test/functional/proxy_test.py

6
contrib/debian/examples/bitcoin.conf vendored

@ -44,11 +44,11 @@ @@ -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 @@ @@ -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:

4
contrib/linearize/example-linearize.cfg

@ -3,8 +3,8 @@ rpcuser=someuser @@ -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

2
contrib/linearize/linearize-hashes.py

@ -125,7 +125,7 @@ if __name__ == '__main__': @@ -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:

6
contrib/qos/README.md

@ -1,5 +1,5 @@ @@ -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.

34
contrib/qos/tc.sh

@ -1,4 +1,4 @@ @@ -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 @@ @@ -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 @@ -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 @@ -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

16
contrib/rpm/bitcoin.spec

@ -332,10 +332,10 @@ if [ `%{_sbindir}/sestatus |grep -c "disabled"` -eq 0 ]; then @@ -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 @@ -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

4
contrib/seeds/generate-seeds.py

@ -127,10 +127,10 @@ def main(): @@ -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

@ -0,0 +1,270 @@ @@ -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()

4
doc/REST-interface.md

@ -57,7 +57,7 @@ https://github.com/bitcoin/bips/blob/master/bip-0064.mediawiki @@ -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. @@ -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.

4
doc/developer-notes.md

@ -195,7 +195,7 @@ Threads @@ -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 @@ -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).

8
doc/tor.md

@ -42,11 +42,11 @@ reachable from the Tor network. Add these lines to your /etc/tor/torrc (or equiv @@ -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: @@ -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:

2
src/amount.h

@ -23,7 +23,7 @@ static const CAmount CENT = 1000000; @@ -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

2
src/policy/policy.h

@ -27,7 +27,7 @@ static const unsigned int MAX_P2SH_SIGOPS = 15; @@ -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

@ -9,6 +9,7 @@ @@ -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 @@ -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 @@ -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;

2
src/qt/intro.cpp

@ -22,7 +22,7 @@ @@ -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) */

6
src/rpc/net.cpp

@ -205,8 +205,8 @@ UniValue addnode(const JSONRPCRequest& request) @@ -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) @@ -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"

2
src/rpc/server.cpp

@ -520,7 +520,7 @@ std::string HelpExampleCli(const std::string& methodname, const std::string& arg @@ -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)

4
src/test/compress_tests.cpp

@ -20,7 +20,7 @@ @@ -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) @@ -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));

2
src/test/miner_tests.cpp

@ -381,7 +381,7 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity) @@ -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());

2
src/timedata.h

@ -10,7 +10,7 @@ @@ -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;

15
src/validation.cpp

@ -1604,8 +1604,8 @@ static ThresholdConditionCache warningcache[VERSIONBITS_NUM_BITS]; @@ -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 @@ -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 @@ -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;
}

2
src/validation.h

@ -204,7 +204,7 @@ extern uint64_t nPruneTarget; @@ -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)

2
src/version.h

@ -15,7 +15,7 @@ static const int PROTOCOL_VERSION = 70015; @@ -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;

7
test/functional/nulldummy.py

@ -22,6 +22,7 @@ from io import BytesIO @@ -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): @@ -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): @@ -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)

21
test/functional/p2p-segwit.py

@ -122,7 +122,7 @@ class SegWitTest(BitcoinTestFramework): @@ -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): @@ -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): @@ -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): @@ -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): @@ -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()

8
test/functional/proxy_test.py

@ -120,24 +120,24 @@ class ProxyTest(BitcoinTestFramework): @@ -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…
Cancel
Save