Claim name returned is strange #172
193 changed files with 15685 additions and 4149 deletions
|
@ -16,6 +16,7 @@ env:
|
|||
- CCACHE_COMPRESS=1
|
||||
- BASE_OUTDIR=$TRAVIS_BUILD_DIR/out
|
||||
- SDK_URL=https://bitcoincore.org/depends-sources/sdks
|
||||
- PYTHON_DEBUG=1
|
||||
cache:
|
||||
apt: true
|
||||
directories:
|
||||
|
|
|
@ -6,6 +6,7 @@ AC_DEFUN([BITCOIN_QT_FAIL],[
|
|||
AC_MSG_WARN([$1; bitcoin-qt frontend will not be built])
|
||||
fi
|
||||
bitcoin_enable_qt=no
|
||||
bitcoin_enable_qt_test=no
|
||||
else
|
||||
AC_MSG_ERROR([$1])
|
||||
fi
|
||||
|
|
|
@ -15,10 +15,6 @@ Files: src/json/*
|
|||
Copyright: 2007-2009, John W. Wilkinson
|
||||
License: Expat
|
||||
|
||||
Files: src/strlcpy.h
|
||||
Copyright: 1998, Todd C. Miller <Todd.Miller@courtesan.com>
|
||||
License: ISC
|
||||
|
||||
Files: debian/*
|
||||
Copyright: 2010-2011, Jonas Smedegaard <dr@jones.dk>
|
||||
2011, Matt Corallo <matt@bluematt.me>
|
||||
|
|
4
depends/.gitignore
vendored
4
depends/.gitignore
vendored
|
@ -3,3 +3,7 @@ work/
|
|||
built/
|
||||
sources/
|
||||
config.site
|
||||
x86_64*
|
||||
i686*
|
||||
mips*
|
||||
arm*
|
||||
|
|
27
depends/config.guess
vendored
27
depends/config.guess
vendored
|
@ -2,7 +2,7 @@
|
|||
# Attempt to guess a canonical system name.
|
||||
# Copyright 1992-2015 Free Software Foundation, Inc.
|
||||
|
||||
timestamp='2015-01-01'
|
||||
timestamp='2015-03-04'
|
||||
|
||||
# This file is free software; you can redistribute it and/or modify it
|
||||
# under the terms of the GNU General Public License as published by
|
||||
|
@ -168,20 +168,27 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
|
|||
# Note: NetBSD doesn't particularly care about the vendor
|
||||
# portion of the name. We always set it to "unknown".
|
||||
sysctl="sysctl -n hw.machine_arch"
|
||||
UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \
|
||||
/usr/sbin/$sysctl 2>/dev/null || echo unknown)`
|
||||
UNAME_MACHINE_ARCH=`(uname -p 2>/dev/null || \
|
||||
/sbin/$sysctl 2>/dev/null || \
|
||||
/usr/sbin/$sysctl 2>/dev/null || \
|
||||
echo unknown)`
|
||||
case "${UNAME_MACHINE_ARCH}" in
|
||||
armeb) machine=armeb-unknown ;;
|
||||
arm*) machine=arm-unknown ;;
|
||||
sh3el) machine=shl-unknown ;;
|
||||
sh3eb) machine=sh-unknown ;;
|
||||
sh5el) machine=sh5le-unknown ;;
|
||||
earmv*)
|
||||
arch=`echo ${UNAME_MACHINE_ARCH} | sed -e 's,^e\(armv[0-9]\).*$,\1,'`
|
||||
endian=`echo ${UNAME_MACHINE_ARCH} | sed -ne 's,^.*\(eb\)$,\1,p'`
|
||||
machine=${arch}${endian}-unknown
|
||||
;;
|
||||
*) machine=${UNAME_MACHINE_ARCH}-unknown ;;
|
||||
esac
|
||||
# The Operating System including object format, if it has switched
|
||||
# to ELF recently, or will in the future.
|
||||
case "${UNAME_MACHINE_ARCH}" in
|
||||
arm*|i386|m68k|ns32k|sh3*|sparc|vax)
|
||||
arm*|earm*|i386|m68k|ns32k|sh3*|sparc|vax)
|
||||
eval $set_cc_for_build
|
||||
if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \
|
||||
| grep -q __ELF__
|
||||
|
@ -197,6 +204,13 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
|
|||
os=netbsd
|
||||
;;
|
||||
esac
|
||||
# Determine ABI tags.
|
||||
case "${UNAME_MACHINE_ARCH}" in
|
||||
earm*)
|
||||
expr='s/^earmv[0-9]/-eabi/;s/eb$//'
|
||||
abi=`echo ${UNAME_MACHINE_ARCH} | sed -e "$expr"`
|
||||
;;
|
||||
esac
|
||||
# The OS release
|
||||
# Debian GNU/NetBSD machines have a different userland, and
|
||||
# thus, need a distinct triplet. However, they do not need
|
||||
|
@ -213,7 +227,7 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
|
|||
# Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM:
|
||||
# contains redundant information, the shorter form:
|
||||
# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used.
|
||||
echo "${machine}-${os}${release}"
|
||||
echo "${machine}-${os}${release}${abi}"
|
||||
exit ;;
|
||||
*:Bitrig:*:*)
|
||||
UNAME_MACHINE_ARCH=`arch | sed 's/Bitrig.//'`
|
||||
|
@ -933,6 +947,9 @@ EOF
|
|||
crisv32:Linux:*:*)
|
||||
echo ${UNAME_MACHINE}-axis-linux-${LIBC}
|
||||
exit ;;
|
||||
e2k:Linux:*:*)
|
||||
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
|
||||
exit ;;
|
||||
frv:Linux:*:*)
|
||||
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
|
||||
exit ;;
|
||||
|
|
13
depends/config.sub
vendored
13
depends/config.sub
vendored
|
@ -2,7 +2,7 @@
|
|||
# Configuration validation subroutine script.
|
||||
# Copyright 1992-2015 Free Software Foundation, Inc.
|
||||
|
||||
timestamp='2015-01-01'
|
||||
timestamp='2015-03-08'
|
||||
|
||||
# This file is free software; you can redistribute it and/or modify it
|
||||
# under the terms of the GNU General Public License as published by
|
||||
|
@ -117,7 +117,7 @@ maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
|
|||
case $maybe_os in
|
||||
nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-newlib* | \
|
||||
linux-musl* | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \
|
||||
knetbsd*-gnu* | netbsd*-gnu* | \
|
||||
knetbsd*-gnu* | netbsd*-gnu* | netbsd*-eabi* | \
|
||||
kopensolaris*-gnu* | \
|
||||
storm-chaos* | os2-emx* | rtmk-nova*)
|
||||
os=-$maybe_os
|
||||
|
@ -259,7 +259,7 @@ case $basic_machine in
|
|||
| bfin \
|
||||
| c4x | c8051 | clipper \
|
||||
| d10v | d30v | dlx | dsp16xx \
|
||||
| epiphany \
|
||||
| e2k | epiphany \
|
||||
| fido | fr30 | frv | ft32 \
|
||||
| h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
|
||||
| hexagon \
|
||||
|
@ -381,7 +381,7 @@ case $basic_machine in
|
|||
| c[123]* | c30-* | [cjt]90-* | c4x-* \
|
||||
| c8051-* | clipper-* | craynv-* | cydra-* \
|
||||
| d10v-* | d30v-* | dlx-* \
|
||||
| elxsi-* \
|
||||
| e2k-* | elxsi-* \
|
||||
| f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \
|
||||
| h8300-* | h8500-* \
|
||||
| hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \
|
||||
|
@ -518,6 +518,9 @@ case $basic_machine in
|
|||
basic_machine=i386-pc
|
||||
os=-aros
|
||||
;;
|
||||
asmjs)
|
||||
basic_machine=asmjs-unknown
|
||||
;;
|
||||
aux)
|
||||
basic_machine=m68k-apple
|
||||
os=-aux
|
||||
|
@ -1373,7 +1376,7 @@ case $os in
|
|||
| -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* \
|
||||
| -sym* | -kopensolaris* | -plan9* \
|
||||
| -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \
|
||||
| -aos* | -aros* \
|
||||
| -aos* | -aros* | -cloudabi* \
|
||||
| -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
|
||||
| -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
|
||||
| -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \
|
||||
|
|
|
@ -5,6 +5,8 @@ The REST API can be enabled with the `-rest` option.
|
|||
|
||||
Supported API
|
||||
-------------
|
||||
|
||||
####Transactions
|
||||
`GET /rest/tx/TX-HASH.{bin|hex|json}`
|
||||
|
||||
Given a transaction hash,
|
||||
|
@ -12,6 +14,7 @@ Returns a transaction, in binary, hex-encoded binary or JSON formats.
|
|||
|
||||
For full TX query capability, one must enable the transaction index via "txindex=1" command line / configuration option.
|
||||
|
||||
####Blocks
|
||||
`GET /rest/block/BLOCK-HASH.{bin|hex|json}`
|
||||
`GET /rest/block/notxdetails/BLOCK-HASH.{bin|hex|json}`
|
||||
|
||||
|
@ -22,6 +25,15 @@ The HTTP request and response are both handled entirely in-memory, thus making m
|
|||
|
||||
With the /notxdetails/ option JSON response will only contain the transaction hash instead of the complete transaction details. The option only affects the JSON response.
|
||||
|
||||
####Blockheaders
|
||||
`GET /rest/headers/<COUNT>/<BLOCK-HASH>.<bin|hex>`
|
||||
|
||||
Given a block hash,
|
||||
Returns <COUNT> amount of blockheaders in upward direction.
|
||||
|
||||
JSON is not supported.
|
||||
|
||||
####Chaininfos
|
||||
`GET /rest/chaininfo.json`
|
||||
|
||||
Returns various state info regarding block chain processing.
|
||||
|
@ -36,4 +48,4 @@ Only supports JSON as output format.
|
|||
|
||||
Risks
|
||||
-------------
|
||||
Running a webbrowser 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:1234/tx/json/1234567890">` which might break the nodes privacy.
|
||||
Running a webbrowser 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.
|
||||
|
|
|
@ -7,9 +7,8 @@ As such, DNS seeds must be run by entities which have some minimum
|
|||
level of trust within the Bitcoin community.
|
||||
|
||||
Other implementations of Bitcoin software may also use the same
|
||||
seeds and may be more exposed. In light of this exposure this
|
||||
document establishes some basic expectations for the expectations
|
||||
for the operation of dnsseeds.
|
||||
seeds and may be more exposed. In light of this exposure, this
|
||||
document establishes some basic expectations for operating dnsseeds.
|
||||
|
||||
0. A DNS seed operating organization or person is expected
|
||||
to follow good host security practices and maintain control of
|
||||
|
|
|
@ -74,11 +74,11 @@ In the VirtualBox GUI click "Create" and choose the following parameters in the
|
|||
- Disk size: at least 40GB; as low as 20GB *may* be possible, but better to err on the safe side
|
||||
- Push the `Create` button
|
||||
|
||||
Get the [Debian 7.7 net installer](http://cdimage.debian.org/debian-cd/7.7.0/amd64/iso-cd/debian-7.7.0-amd64-netinst.iso) (a more recent minor version should also work, see also [Debian Network installation](https://www.debian.org/CD/netinst/)).
|
||||
Get the [Debian 7.8 net installer](http://cdimage.debian.org/debian-cd/7.8.0/amd64/iso-cd/debian-7.8.0-amd64-netinst.iso) (a more recent minor version should also work, see also [Debian Network installation](https://www.debian.org/CD/netinst/)).
|
||||
This DVD image can be validated using a SHA256 hashing tool, for example on
|
||||
Unixy OSes by entering the following in a terminal:
|
||||
|
||||
echo "d440e85b4121f94608748139f25dbce1ad36771348b002fe07d4d44b9d9e623f debian-7.7.0-amd64-netinst.iso" | sha256sum -c
|
||||
echo "e39c36d6adc0fd86c6edb0e03e22919086c883b37ca194d063b8e3e8f6ff6a3a debian-7.8.0-amd64-netinst.iso" | sha256sum -c
|
||||
# (must return OK)
|
||||
|
||||
After creating the VM, we need to configure it.
|
||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -27,7 +27,11 @@ testScripts=(
|
|||
'mempool_coinbase_spends.py'
|
||||
'httpbasics.py'
|
||||
'zapwallettxes.py'
|
||||
'proxy_test.py'
|
||||
'merkle_blocks.py'
|
||||
# 'forknotify.py'
|
||||
'maxblocksinflight.py'
|
||||
'invalidblockrequest.py'
|
||||
);
|
||||
if [ "x${ENABLE_BITCOIND}${ENABLE_UTILS}${ENABLE_WALLET}" = "x111" ]; then
|
||||
for (( i = 0; i < ${#testScripts[@]}; i++ ))
|
||||
|
|
102
qa/rpc-tests/bignum.py
Normal file
102
qa/rpc-tests/bignum.py
Normal file
|
@ -0,0 +1,102 @@
|
|||
#
|
||||
#
|
||||
# bignum.py
|
||||
#
|
||||
# This file is copied from python-bitcoinlib.
|
||||
#
|
||||
# Distributed under the MIT/X11 software license, see the accompanying
|
||||
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
#
|
||||
|
||||
"""Bignum routines"""
|
||||
|
||||
from __future__ import absolute_import, division, print_function, unicode_literals
|
||||
|
||||
import struct
|
||||
|
||||
|
||||
# generic big endian MPI format
|
||||
|
||||
def bn_bytes(v, have_ext=False):
|
||||
ext = 0
|
||||
if have_ext:
|
||||
ext = 1
|
||||
return ((v.bit_length()+7)//8) + ext
|
||||
|
||||
def bn2bin(v):
|
||||
s = bytearray()
|
||||
i = bn_bytes(v)
|
||||
while i > 0:
|
||||
s.append((v >> ((i-1) * 8)) & 0xff)
|
||||
i -= 1
|
||||
return s
|
||||
|
||||
def bin2bn(s):
|
||||
l = 0
|
||||
for ch in s:
|
||||
l = (l << 8) | ch
|
||||
return l
|
||||
|
||||
def bn2mpi(v):
|
||||
have_ext = False
|
||||
if v.bit_length() > 0:
|
||||
have_ext = (v.bit_length() & 0x07) == 0
|
||||
|
||||
neg = False
|
||||
if v < 0:
|
||||
neg = True
|
||||
v = -v
|
||||
|
||||
s = struct.pack(b">I", bn_bytes(v, have_ext))
|
||||
ext = bytearray()
|
||||
if have_ext:
|
||||
ext.append(0)
|
||||
v_bin = bn2bin(v)
|
||||
if neg:
|
||||
if have_ext:
|
||||
ext[0] |= 0x80
|
||||
else:
|
||||
v_bin[0] |= 0x80
|
||||
return s + ext + v_bin
|
||||
|
||||
def mpi2bn(s):
|
||||
if len(s) < 4:
|
||||
return None
|
||||
s_size = bytes(s[:4])
|
||||
v_len = struct.unpack(b">I", s_size)[0]
|
||||
if len(s) != (v_len + 4):
|
||||
return None
|
||||
if v_len == 0:
|
||||
return 0
|
||||
|
||||
v_str = bytearray(s[4:])
|
||||
neg = False
|
||||
i = v_str[0]
|
||||
if i & 0x80:
|
||||
neg = True
|
||||
i &= ~0x80
|
||||
v_str[0] = i
|
||||
|
||||
v = bin2bn(v_str)
|
||||
|
||||
if neg:
|
||||
return -v
|
||||
return v
|
||||
|
||||
# bitcoin-specific little endian format, with implicit size
|
||||
def mpi2vch(s):
|
||||
r = s[4:] # strip size
|
||||
r = r[::-1] # reverse string, converting BE->LE
|
||||
return r
|
||||
|
||||
def bn2vch(v):
|
||||
return bytes(mpi2vch(bn2mpi(v)))
|
||||
|
||||
def vch2mpi(s):
|
||||
r = struct.pack(b">I", len(s)) # size
|
||||
r += s[::-1] # reverse string, converting LE->BE
|
||||
return r
|
||||
|
||||
def vch2bn(s):
|
||||
return mpi2bn(vch2mpi(s))
|
||||
|
183
qa/rpc-tests/bipdersig-p2p.py
Executable file
183
qa/rpc-tests/bipdersig-p2p.py
Executable file
|
@ -0,0 +1,183 @@
|
|||
#!/usr/bin/env python2
|
||||
#
|
||||
# Distributed under the MIT/X11 software license, see the accompanying
|
||||
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
#
|
||||
|
||||
from test_framework import ComparisonTestFramework
|
||||
from util import *
|
||||
from mininode import CTransaction, NetworkThread
|
||||
from blocktools import create_coinbase, create_block
|
||||
from binascii import hexlify, unhexlify
|
||||
import cStringIO
|
||||
from comptool import TestInstance, TestManager
|
||||
from script import CScript
|
||||
import time
|
||||
|
||||
# A canonical signature consists of:
|
||||
# <30> <total len> <02> <len R> <R> <02> <len S> <S> <hashtype>
|
||||
def unDERify(tx):
|
||||
'''
|
||||
Make the signature in vin 0 of a tx non-DER-compliant,
|
||||
by adding padding after the S-value.
|
||||
'''
|
||||
scriptSig = CScript(tx.vin[0].scriptSig)
|
||||
newscript = []
|
||||
for i in scriptSig:
|
||||
if (len(newscript) == 0):
|
||||
newscript.append(i[0:-1] + '\0' + i[-1])
|
||||
else:
|
||||
newscript.append(i)
|
||||
tx.vin[0].scriptSig = CScript(newscript)
|
||||
|
||||
'''
|
||||
This test is meant to exercise BIP66 (DER SIG).
|
||||
Connect to a single node.
|
||||
Mine 2 (version 2) blocks (save the coinbases for later).
|
||||
Generate 98 more version 2 blocks, verify the node accepts.
|
||||
Mine 749 version 3 blocks, verify the node accepts.
|
||||
Check that the new DERSIG rules are not enforced on the 750th version 3 block.
|
||||
Check that the new DERSIG rules are enforced on the 751st version 3 block.
|
||||
Mine 199 new version blocks.
|
||||
Mine 1 old-version block.
|
||||
Mine 1 new version block.
|
||||
Mine 1 old version block, see that the node rejects.
|
||||
'''
|
||||
|
||||
class BIP66Test(ComparisonTestFramework):
|
||||
|
||||
def __init__(self):
|
||||
self.num_nodes = 1
|
||||
|
||||
def setup_network(self):
|
||||
# Must set the blockversion for this test
|
||||
self.nodes = start_nodes(1, self.options.tmpdir,
|
||||
extra_args=[['-debug', '-whitelist=127.0.0.1', '-blockversion=2']],
|
||||
binary=[self.options.testbinary])
|
||||
|
||||
def run_test(self):
|
||||
test = TestManager(self, self.options.tmpdir)
|
||||
test.add_all_connections(self.nodes)
|
||||
NetworkThread().start() # Start up network handling in another thread
|
||||
test.run()
|
||||
|
||||
def create_transaction(self, node, coinbase, to_address, amount):
|
||||
from_txid = node.getblock(coinbase)['tx'][0]
|
||||
inputs = [{ "txid" : from_txid, "vout" : 0}]
|
||||
outputs = { to_address : amount }
|
||||
rawtx = node.createrawtransaction(inputs, outputs)
|
||||
signresult = node.signrawtransaction(rawtx)
|
||||
tx = CTransaction()
|
||||
f = cStringIO.StringIO(unhexlify(signresult['hex']))
|
||||
tx.deserialize(f)
|
||||
return tx
|
||||
|
||||
def get_tests(self):
|
||||
|
||||
self.coinbase_blocks = self.nodes[0].generate(2)
|
||||
self.tip = int ("0x" + self.nodes[0].getbestblockhash() + "L", 0)
|
||||
self.nodeaddress = self.nodes[0].getnewaddress()
|
||||
self.last_block_time = time.time()
|
||||
|
||||
''' 98 more version 2 blocks '''
|
||||
test_blocks = []
|
||||
for i in xrange(98):
|
||||
block = create_block(self.tip, create_coinbase(2), self.last_block_time + 1)
|
||||
block.nVersion = 2
|
||||
block.rehash()
|
||||
block.solve()
|
||||
test_blocks.append([block, True])
|
||||
self.last_block_time += 1
|
||||
self.tip = block.sha256
|
||||
yield TestInstance(test_blocks, sync_every_block=False)
|
||||
|
||||
''' Mine 749 version 3 blocks '''
|
||||
test_blocks = []
|
||||
for i in xrange(749):
|
||||
block = create_block(self.tip, create_coinbase(2), self.last_block_time + 1)
|
||||
block.nVersion = 3
|
||||
block.rehash()
|
||||
block.solve()
|
||||
test_blocks.append([block, True])
|
||||
self.last_block_time += 1
|
||||
self.tip = block.sha256
|
||||
yield TestInstance(test_blocks, sync_every_block=False)
|
||||
|
||||
'''
|
||||
Check that the new DERSIG rules are not enforced in the 750th
|
||||
version 3 block.
|
||||
'''
|
||||
spendtx = self.create_transaction(self.nodes[0],
|
||||
self.coinbase_blocks[0], self.nodeaddress, 1.0)
|
||||
unDERify(spendtx)
|
||||
spendtx.rehash()
|
||||
|
||||
block = create_block(self.tip, create_coinbase(2), self.last_block_time + 1)
|
||||
block.nVersion = 3
|
||||
block.vtx.append(spendtx)
|
||||
block.hashMerkleRoot = block.calc_merkle_root()
|
||||
block.rehash()
|
||||
block.solve()
|
||||
|
||||
self.last_block_time += 1
|
||||
self.tip = block.sha256
|
||||
yield TestInstance([[block, True]])
|
||||
|
||||
'''
|
||||
Check that the new DERSIG rules are enforced in the 751st version 3
|
||||
block.
|
||||
'''
|
||||
spendtx = self.create_transaction(self.nodes[0],
|
||||
self.coinbase_blocks[1], self.nodeaddress, 1.0)
|
||||
unDERify(spendtx)
|
||||
spendtx.rehash()
|
||||
|
||||
block = create_block(self.tip, create_coinbase(1), self.last_block_time + 1)
|
||||
block.nVersion = 3
|
||||
block.vtx.append(spendtx)
|
||||
block.hashMerkleRoot = block.calc_merkle_root()
|
||||
block.rehash()
|
||||
block.solve()
|
||||
self.last_block_time += 1
|
||||
yield TestInstance([[block, False]])
|
||||
|
||||
''' Mine 199 new version blocks on last valid tip '''
|
||||
test_blocks = []
|
||||
for i in xrange(199):
|
||||
block = create_block(self.tip, create_coinbase(1), self.last_block_time + 1)
|
||||
block.nVersion = 3
|
||||
block.rehash()
|
||||
block.solve()
|
||||
test_blocks.append([block, True])
|
||||
self.last_block_time += 1
|
||||
self.tip = block.sha256
|
||||
yield TestInstance(test_blocks, sync_every_block=False)
|
||||
|
||||
''' Mine 1 old version block '''
|
||||
block = create_block(self.tip, create_coinbase(1), self.last_block_time + 1)
|
||||
block.nVersion = 2
|
||||
block.rehash()
|
||||
block.solve()
|
||||
self.last_block_time += 1
|
||||
self.tip = block.sha256
|
||||
yield TestInstance([[block, True]])
|
||||
|
||||
''' Mine 1 new version block '''
|
||||
block = create_block(self.tip, create_coinbase(1), self.last_block_time + 1)
|
||||
block.nVersion = 3
|
||||
block.rehash()
|
||||
block.solve()
|
||||
self.last_block_time += 1
|
||||
self.tip = block.sha256
|
||||
yield TestInstance([[block, True]])
|
||||
|
||||
''' Mine 1 old version block, should be invalid '''
|
||||
block = create_block(self.tip, create_coinbase(1), self.last_block_time + 1)
|
||||
block.nVersion = 2
|
||||
block.rehash()
|
||||
block.solve()
|
||||
self.last_block_time += 1
|
||||
yield TestInstance([[block, False]])
|
||||
|
||||
if __name__ == '__main__':
|
||||
BIP66Test().main()
|
|
@ -29,14 +29,14 @@ class BIP66Test(BitcoinTestFramework):
|
|||
cnt = self.nodes[0].getblockcount()
|
||||
|
||||
# Mine some old-version blocks
|
||||
self.nodes[1].setgenerate(True, 100)
|
||||
self.nodes[1].generate(100)
|
||||
self.sync_all()
|
||||
if (self.nodes[0].getblockcount() != cnt + 100):
|
||||
raise AssertionError("Failed to mine 100 version=2 blocks")
|
||||
|
||||
# Mine 750 new-version blocks
|
||||
for i in xrange(15):
|
||||
self.nodes[2].setgenerate(True, 50)
|
||||
self.nodes[2].generate(50)
|
||||
self.sync_all()
|
||||
if (self.nodes[0].getblockcount() != cnt + 850):
|
||||
raise AssertionError("Failed to mine 750 version=3 blocks")
|
||||
|
@ -44,7 +44,7 @@ class BIP66Test(BitcoinTestFramework):
|
|||
# TODO: check that new DERSIG rules are not enforced
|
||||
|
||||
# Mine 1 new-version block
|
||||
self.nodes[2].setgenerate(True, 1)
|
||||
self.nodes[2].generate(1)
|
||||
self.sync_all()
|
||||
if (self.nodes[0].getblockcount() != cnt + 851):
|
||||
raise AssertionFailure("Failed to mine a version=3 blocks")
|
||||
|
@ -53,26 +53,26 @@ class BIP66Test(BitcoinTestFramework):
|
|||
|
||||
# Mine 198 new-version blocks
|
||||
for i in xrange(2):
|
||||
self.nodes[2].setgenerate(True, 99)
|
||||
self.nodes[2].generate(99)
|
||||
self.sync_all()
|
||||
if (self.nodes[0].getblockcount() != cnt + 1049):
|
||||
raise AssertionError("Failed to mine 198 version=3 blocks")
|
||||
|
||||
# Mine 1 old-version block
|
||||
self.nodes[1].setgenerate(True, 1)
|
||||
self.nodes[1].generate(1)
|
||||
self.sync_all()
|
||||
if (self.nodes[0].getblockcount() != cnt + 1050):
|
||||
raise AssertionError("Failed to mine a version=2 block after 949 version=3 blocks")
|
||||
|
||||
# Mine 1 new-version blocks
|
||||
self.nodes[2].setgenerate(True, 1)
|
||||
self.nodes[2].generate(1)
|
||||
self.sync_all()
|
||||
if (self.nodes[0].getblockcount() != cnt + 1051):
|
||||
raise AssertionError("Failed to mine a version=3 block")
|
||||
|
||||
# Mine 1 old-version blocks
|
||||
try:
|
||||
self.nodes[1].setgenerate(True, 1)
|
||||
self.nodes[1].generate(1)
|
||||
raise AssertionError("Succeeded to mine a version=2 block after 950 version=3 blocks")
|
||||
except JSONRPCException:
|
||||
pass
|
||||
|
@ -81,7 +81,7 @@ class BIP66Test(BitcoinTestFramework):
|
|||
raise AssertionError("Accepted a version=2 block after 950 version=3 blocks")
|
||||
|
||||
# Mine 1 new-version blocks
|
||||
self.nodes[2].setgenerate(True, 1)
|
||||
self.nodes[2].generate(1)
|
||||
self.sync_all()
|
||||
if (self.nodes[0].getblockcount() != cnt + 1052):
|
||||
raise AssertionError("Failed to mine a version=3 block")
|
||||
|
|
127
qa/rpc-tests/blockstore.py
Normal file
127
qa/rpc-tests/blockstore.py
Normal file
|
@ -0,0 +1,127 @@
|
|||
# BlockStore: a helper class that keeps a map of blocks and implements
|
||||
# helper functions for responding to getheaders and getdata,
|
||||
# and for constructing a getheaders message
|
||||
#
|
||||
|
||||
from mininode import *
|
||||
import dbm
|
||||
|
||||
class BlockStore(object):
|
||||
def __init__(self, datadir):
|
||||
self.blockDB = dbm.open(datadir + "/blocks", 'c')
|
||||
self.currentBlock = 0L
|
||||
|
||||
def close(self):
|
||||
self.blockDB.close()
|
||||
|
||||
def get(self, blockhash):
|
||||
serialized_block = None
|
||||
try:
|
||||
serialized_block = self.blockDB[repr(blockhash)]
|
||||
except KeyError:
|
||||
return None
|
||||
f = cStringIO.StringIO(serialized_block)
|
||||
ret = CBlock()
|
||||
ret.deserialize(f)
|
||||
ret.calc_sha256()
|
||||
return ret
|
||||
|
||||
# Note: this pulls full blocks out of the database just to retrieve
|
||||
# the headers -- perhaps we could keep a separate data structure
|
||||
# to avoid this overhead.
|
||||
def headers_for(self, locator, hash_stop, current_tip=None):
|
||||
if current_tip is None:
|
||||
current_tip = self.currentBlock
|
||||
current_block = self.get(current_tip)
|
||||
if current_block is None:
|
||||
return None
|
||||
|
||||
response = msg_headers()
|
||||
headersList = [ CBlockHeader(current_block) ]
|
||||
maxheaders = 2000
|
||||
while (headersList[0].sha256 not in locator.vHave):
|
||||
prevBlockHash = headersList[0].hashPrevBlock
|
||||
prevBlock = self.get(prevBlockHash)
|
||||
if prevBlock is not None:
|
||||
headersList.insert(0, CBlockHeader(prevBlock))
|
||||
else:
|
||||
break
|
||||
headersList = headersList[:maxheaders] # truncate if we have too many
|
||||
hashList = [x.sha256 for x in headersList]
|
||||
index = len(headersList)
|
||||
if (hash_stop in hashList):
|
||||
index = hashList.index(hash_stop)+1
|
||||
response.headers = headersList[:index]
|
||||
return response
|
||||
|
||||
def add_block(self, block):
|
||||
block.calc_sha256()
|
||||
try:
|
||||
self.blockDB[repr(block.sha256)] = bytes(block.serialize())
|
||||
except TypeError as e:
|
||||
print "Unexpected error: ", sys.exc_info()[0], e.args
|
||||
self.currentBlock = block.sha256
|
||||
|
||||
def get_blocks(self, inv):
|
||||
responses = []
|
||||
for i in inv:
|
||||
if (i.type == 2): # MSG_BLOCK
|
||||
block = self.get(i.hash)
|
||||
if block is not None:
|
||||
responses.append(msg_block(block))
|
||||
return responses
|
||||
|
||||
def get_locator(self, current_tip=None):
|
||||
if current_tip is None:
|
||||
current_tip = self.currentBlock
|
||||
r = []
|
||||
counter = 0
|
||||
step = 1
|
||||
lastBlock = self.get(current_tip)
|
||||
while lastBlock is not None:
|
||||
r.append(lastBlock.hashPrevBlock)
|
||||
for i in range(step):
|
||||
lastBlock = self.get(lastBlock.hashPrevBlock)
|
||||
if lastBlock is None:
|
||||
break
|
||||
counter += 1
|
||||
if counter > 10:
|
||||
step *= 2
|
||||
locator = CBlockLocator()
|
||||
locator.vHave = r
|
||||
return locator
|
||||
|
||||
class TxStore(object):
|
||||
def __init__(self, datadir):
|
||||
self.txDB = dbm.open(datadir + "/transactions", 'c')
|
||||
|
||||
def close(self):
|
||||
self.txDB.close()
|
||||
|
||||
def get(self, txhash):
|
||||
serialized_tx = None
|
||||
try:
|
||||
serialized_tx = self.txDB[repr(txhash)]
|
||||
except KeyError:
|
||||
return None
|
||||
f = cStringIO.StringIO(serialized_tx)
|
||||
ret = CTransaction()
|
||||
ret.deserialize(f)
|
||||
ret.calc_sha256()
|
||||
return ret
|
||||
|
||||
def add_transaction(self, tx):
|
||||
tx.calc_sha256()
|
||||
try:
|
||||
self.txDB[repr(tx.sha256)] = bytes(tx.serialize())
|
||||
except TypeError as e:
|
||||
print "Unexpected error: ", sys.exc_info()[0], e.args
|
||||
|
||||
def get_transactions(self, inv):
|
||||
responses = []
|
||||
for i in inv:
|
||||
if (i.type == 1): # MSG_TX
|
||||
tx = self.get(i.hash)
|
||||
if tx is not None:
|
||||
responses.append(msg_tx(tx))
|
||||
return responses
|
65
qa/rpc-tests/blocktools.py
Normal file
65
qa/rpc-tests/blocktools.py
Normal file
|
@ -0,0 +1,65 @@
|
|||
# blocktools.py - utilities for manipulating blocks and transactions
|
||||
#
|
||||
# Distributed under the MIT/X11 software license, see the accompanying
|
||||
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
#
|
||||
|
||||
from mininode import *
|
||||
from script import CScript, CScriptOp
|
||||
|
||||
# Create a block (with regtest difficulty)
|
||||
def create_block(hashprev, coinbase, nTime=None):
|
||||
block = CBlock()
|
||||
if nTime is None:
|
||||
import time
|
||||
block.nTime = int(time.time()+600)
|
||||
else:
|
||||
block.nTime = nTime
|
||||
block.hashPrevBlock = hashprev
|
||||
block.nBits = 0x207fffff # Will break after a difficulty adjustment...
|
||||
block.vtx.append(coinbase)
|
||||
block.hashMerkleRoot = block.calc_merkle_root()
|
||||
block.calc_sha256()
|
||||
return block
|
||||
|
||||
def serialize_script_num(value):
|
||||
r = bytearray(0)
|
||||
if value == 0:
|
||||
return r
|
||||
neg = value < 0
|
||||
absvalue = -value if neg else value
|
||||
while (absvalue):
|
||||
r.append(chr(absvalue & 0xff))
|
||||
absvalue >>= 8
|
||||
if r[-1] & 0x80:
|
||||
r.append(0x80 if neg else 0)
|
||||
elif neg:
|
||||
r[-1] |= 0x80
|
||||
return r
|
||||
|
||||
counter=1
|
||||
# Create an anyone-can-spend coinbase transaction, assuming no miner fees
|
||||
def create_coinbase(heightAdjust = 0):
|
||||
global counter
|
||||
coinbase = CTransaction()
|
||||
coinbase.vin.append(CTxIn(COutPoint(0, 0xffffffff),
|
||||
ser_string(serialize_script_num(counter+heightAdjust)), 0xffffffff))
|
||||
counter += 1
|
||||
coinbaseoutput = CTxOut()
|
||||
coinbaseoutput.nValue = 50*100000000
|
||||
halvings = int((counter+heightAdjust)/150) # regtest
|
||||
coinbaseoutput.nValue >>= halvings
|
||||
coinbaseoutput.scriptPubKey = ""
|
||||
coinbase.vout = [ coinbaseoutput ]
|
||||
coinbase.calc_sha256()
|
||||
return coinbase
|
||||
|
||||
# Create a transaction with an anyone-can-spend output, that spends the
|
||||
# nth output of prevtx.
|
||||
def create_transaction(prevtx, n, sig, value):
|
||||
tx = CTransaction()
|
||||
assert(n < len(prevtx.vout))
|
||||
tx.vin.append(CTxIn(COutPoint(prevtx.sha256, n), sig, 0xffffffff))
|
||||
tx.vout.append(CTxOut(value, ""))
|
||||
tx.calc_sha256()
|
||||
return tx
|
330
qa/rpc-tests/comptool.py
Executable file
330
qa/rpc-tests/comptool.py
Executable file
|
@ -0,0 +1,330 @@
|
|||
#!/usr/bin/env python2
|
||||
#
|
||||
# Distributed under the MIT/X11 software license, see the accompanying
|
||||
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
#
|
||||
|
||||
from mininode import *
|
||||
from blockstore import BlockStore, TxStore
|
||||
from util import p2p_port
|
||||
|
||||
'''
|
||||
This is a tool for comparing two or more bitcoinds to each other
|
||||
using a script provided.
|
||||
|
||||
To use, create a class that implements get_tests(), and pass it in
|
||||
as the test generator to TestManager. get_tests() should be a python
|
||||
generator that returns TestInstance objects. See below for definition.
|
||||
'''
|
||||
|
||||
# TestNode behaves as follows:
|
||||
# Configure with a BlockStore and TxStore
|
||||
# on_inv: log the message but don't request
|
||||
# on_headers: log the chain tip
|
||||
# on_pong: update ping response map (for synchronization)
|
||||
# on_getheaders: provide headers via BlockStore
|
||||
# on_getdata: provide blocks via BlockStore
|
||||
|
||||
class TestNode(NodeConnCB):
|
||||
|
||||
def __init__(self, block_store, tx_store):
|
||||
NodeConnCB.__init__(self)
|
||||
self.create_callback_map()
|
||||
self.conn = None
|
||||
self.bestblockhash = None
|
||||
self.block_store = block_store
|
||||
self.block_request_map = {}
|
||||
self.tx_store = tx_store
|
||||
self.tx_request_map = {}
|
||||
|
||||
# When the pingmap is non-empty we're waiting for
|
||||
# a response
|
||||
self.pingMap = {}
|
||||
self.lastInv = []
|
||||
|
||||
def add_connection(self, conn):
|
||||
self.conn = conn
|
||||
|
||||
def on_headers(self, conn, message):
|
||||
if len(message.headers) > 0:
|
||||
best_header = message.headers[-1]
|
||||
best_header.calc_sha256()
|
||||
self.bestblockhash = best_header.sha256
|
||||
|
||||
def on_getheaders(self, conn, message):
|
||||
response = self.block_store.headers_for(message.locator, message.hashstop)
|
||||
if response is not None:
|
||||
conn.send_message(response)
|
||||
|
||||
def on_getdata(self, conn, message):
|
||||
[conn.send_message(r) for r in self.block_store.get_blocks(message.inv)]
|
||||
[conn.send_message(r) for r in self.tx_store.get_transactions(message.inv)]
|
||||
|
||||
for i in message.inv:
|
||||
if i.type == 1:
|
||||
self.tx_request_map[i.hash] = True
|
||||
elif i.type == 2:
|
||||
self.block_request_map[i.hash] = True
|
||||
|
||||
def on_inv(self, conn, message):
|
||||
self.lastInv = [x.hash for x in message.inv]
|
||||
|
||||
def on_pong(self, conn, message):
|
||||
try:
|
||||
del self.pingMap[message.nonce]
|
||||
except KeyError:
|
||||
raise AssertionError("Got pong for unknown ping [%s]" % repr(message))
|
||||
|
||||
def send_inv(self, obj):
|
||||
mtype = 2 if isinstance(obj, CBlock) else 1
|
||||
self.conn.send_message(msg_inv([CInv(mtype, obj.sha256)]))
|
||||
|
||||
def send_getheaders(self):
|
||||
# We ask for headers from their last tip.
|
||||
m = msg_getheaders()
|
||||
m.locator = self.block_store.get_locator(self.bestblockhash)
|
||||
self.conn.send_message(m)
|
||||
|
||||
# This assumes BIP31
|
||||
def send_ping(self, nonce):
|
||||
self.pingMap[nonce] = True
|
||||
self.conn.send_message(msg_ping(nonce))
|
||||
|
||||
def received_ping_response(self, nonce):
|
||||
return nonce not in self.pingMap
|
||||
|
||||
def send_mempool(self):
|
||||
self.lastInv = []
|
||||
self.conn.send_message(msg_mempool())
|
||||
|
||||
# TestInstance:
|
||||
#
|
||||
# Instances of these are generated by the test generator, and fed into the
|
||||
# comptool.
|
||||
#
|
||||
# "blocks_and_transactions" should be an array of [obj, True/False/None]:
|
||||
# - obj is either a CBlock or a CTransaction, and
|
||||
# - the second value indicates whether the object should be accepted
|
||||
# into the blockchain or mempool (for tests where we expect a certain
|
||||
# answer), or "None" if we don't expect a certain answer and are just
|
||||
# comparing the behavior of the nodes being tested.
|
||||
# sync_every_block: if True, then each block will be inv'ed, synced, and
|
||||
# nodes will be tested based on the outcome for the block. If False,
|
||||
# then inv's accumulate until all blocks are processed (or max inv size
|
||||
# is reached) and then sent out in one inv message. Then the final block
|
||||
# will be synced across all connections, and the outcome of the final
|
||||
# block will be tested.
|
||||
# sync_every_tx: analagous to behavior for sync_every_block, except if outcome
|
||||
# on the final tx is None, then contents of entire mempool are compared
|
||||
# across all connections. (If outcome of final tx is specified as true
|
||||
# or false, then only the last tx is tested against outcome.)
|
||||
|
||||
class TestInstance(object):
|
||||
def __init__(self, objects=[], sync_every_block=True, sync_every_tx=False):
|
||||
self.blocks_and_transactions = objects
|
||||
self.sync_every_block = sync_every_block
|
||||
self.sync_every_tx = sync_every_tx
|
||||
|
||||
class TestManager(object):
|
||||
|
||||
def __init__(self, testgen, datadir):
|
||||
self.test_generator = testgen
|
||||
self.connections = []
|
||||
self.block_store = BlockStore(datadir)
|
||||
self.tx_store = TxStore(datadir)
|
||||
self.ping_counter = 1
|
||||
|
||||
def add_all_connections(self, nodes):
|
||||
for i in range(len(nodes)):
|
||||
# Create a p2p connection to each node
|
||||
self.connections.append(NodeConn('127.0.0.1', p2p_port(i),
|
||||
nodes[i], TestNode(self.block_store, self.tx_store)))
|
||||
# Make sure the TestNode (callback class) has a reference to its
|
||||
# associated NodeConn
|
||||
self.connections[-1].cb.add_connection(self.connections[-1])
|
||||
|
||||
def wait_for_verack(self):
|
||||
sleep_time = 0.05
|
||||
max_tries = 10 / sleep_time # Wait at most 10 seconds
|
||||
while max_tries > 0:
|
||||
done = True
|
||||
for c in self.connections:
|
||||
if c.cb.verack_received is False:
|
||||
done = False
|
||||
break
|
||||
if done:
|
||||
break
|
||||
time.sleep(sleep_time)
|
||||
|
||||
def wait_for_pings(self, counter):
|
||||
received_pongs = False
|
||||
while received_pongs is not True:
|
||||
time.sleep(0.05)
|
||||
received_pongs = True
|
||||
for c in self.connections:
|
||||
if c.cb.received_ping_response(counter) is not True:
|
||||
received_pongs = False
|
||||
break
|
||||
|
||||
# sync_blocks: Wait for all connections to request the blockhash given
|
||||
# then send get_headers to find out the tip of each node, and synchronize
|
||||
# the response by using a ping (and waiting for pong with same nonce).
|
||||
def sync_blocks(self, blockhash, num_blocks):
|
||||
# Wait for nodes to request block (50ms sleep * 20 tries * num_blocks)
|
||||
max_tries = 20*num_blocks
|
||||
while max_tries > 0:
|
||||
results = [ blockhash in c.cb.block_request_map and
|
||||
c.cb.block_request_map[blockhash] for c in self.connections ]
|
||||
if False not in results:
|
||||
break
|
||||
time.sleep(0.05)
|
||||
max_tries -= 1
|
||||
|
||||
# --> error if not requested
|
||||
if max_tries == 0:
|
||||
# print [ c.cb.block_request_map for c in self.connections ]
|
||||
raise AssertionError("Not all nodes requested block")
|
||||
# --> Answer request (we did this inline!)
|
||||
|
||||
# Send getheaders message
|
||||
[ c.cb.send_getheaders() for c in self.connections ]
|
||||
|
||||
# Send ping and wait for response -- synchronization hack
|
||||
[ c.cb.send_ping(self.ping_counter) for c in self.connections ]
|
||||
self.wait_for_pings(self.ping_counter)
|
||||
self.ping_counter += 1
|
||||
|
||||
# Analogous to sync_block (see above)
|
||||
def sync_transaction(self, txhash, num_events):
|
||||
# Wait for nodes to request transaction (50ms sleep * 20 tries * num_events)
|
||||
max_tries = 20*num_events
|
||||
while max_tries > 0:
|
||||
results = [ txhash in c.cb.tx_request_map and
|
||||
c.cb.tx_request_map[txhash] for c in self.connections ]
|
||||
if False not in results:
|
||||
break
|
||||
time.sleep(0.05)
|
||||
max_tries -= 1
|
||||
|
||||
# --> error if not requested
|
||||
if max_tries == 0:
|
||||
# print [ c.cb.tx_request_map for c in self.connections ]
|
||||
raise AssertionError("Not all nodes requested transaction")
|
||||
# --> Answer request (we did this inline!)
|
||||
|
||||
# Get the mempool
|
||||
[ c.cb.send_mempool() for c in self.connections ]
|
||||
|
||||
# Send ping and wait for response -- synchronization hack
|
||||
[ c.cb.send_ping(self.ping_counter) for c in self.connections ]
|
||||
self.wait_for_pings(self.ping_counter)
|
||||
self.ping_counter += 1
|
||||
|
||||
# Sort inv responses from each node
|
||||
[ c.cb.lastInv.sort() for c in self.connections ]
|
||||
|
||||
# Verify that the tip of each connection all agree with each other, and
|
||||
# with the expected outcome (if given)
|
||||
def check_results(self, blockhash, outcome):
|
||||
for c in self.connections:
|
||||
if outcome is None:
|
||||
if c.cb.bestblockhash != self.connections[0].cb.bestblockhash:
|
||||
return False
|
||||
elif ((c.cb.bestblockhash == blockhash) != outcome):
|
||||
# print c.cb.bestblockhash, blockhash, outcome
|
||||
return False
|
||||
return True
|
||||
|
||||
# Either check that the mempools all agree with each other, or that
|
||||
# txhash's presence in the mempool matches the outcome specified.
|
||||
# This is somewhat of a strange comparison, in that we're either comparing
|
||||
# a particular tx to an outcome, or the entire mempools altogether;
|
||||
# perhaps it would be useful to add the ability to check explicitly that
|
||||
# a particular tx's existence in the mempool is the same across all nodes.
|
||||
def check_mempool(self, txhash, outcome):
|
||||
for c in self.connections:
|
||||
if outcome is None:
|
||||
# Make sure the mempools agree with each other
|
||||
if c.cb.lastInv != self.connections[0].cb.lastInv:
|
||||
# print c.rpc.getrawmempool()
|
||||
return False
|
||||
elif ((txhash in c.cb.lastInv) != outcome):
|
||||
# print c.rpc.getrawmempool(), c.cb.lastInv
|
||||
return False
|
||||
return True
|
||||
|
||||
def run(self):
|
||||
# Wait until verack is received
|
||||
self.wait_for_verack()
|
||||
|
||||
test_number = 1
|
||||
for test_instance in self.test_generator.get_tests():
|
||||
# We use these variables to keep track of the last block
|
||||
# and last transaction in the tests, which are used
|
||||
# if we're not syncing on every block or every tx.
|
||||
[ block, block_outcome ] = [ None, None ]
|
||||
[ tx, tx_outcome ] = [ None, None ]
|
||||
invqueue = []
|
||||
|
||||
for b_or_t, outcome in test_instance.blocks_and_transactions:
|
||||
# Determine if we're dealing with a block or tx
|
||||
if isinstance(b_or_t, CBlock): # Block test runner
|
||||
block = b_or_t
|
||||
block_outcome = outcome
|
||||
# Add to shared block_store, set as current block
|
||||
self.block_store.add_block(block)
|
||||
for c in self.connections:
|
||||
c.cb.block_request_map[block.sha256] = False
|
||||
# Either send inv's to each node and sync, or add
|
||||
# to invqueue for later inv'ing.
|
||||
if (test_instance.sync_every_block):
|
||||
[ c.cb.send_inv(block) for c in self.connections ]
|
||||
self.sync_blocks(block.sha256, 1)
|
||||
if (not self.check_results(block.sha256, outcome)):
|
||||
raise AssertionError("Test failed at test %d" % test_number)
|
||||
else:
|
||||
invqueue.append(CInv(2, block.sha256))
|
||||
else: # Tx test runner
|
||||
assert(isinstance(b_or_t, CTransaction))
|
||||
tx = b_or_t
|
||||
tx_outcome = outcome
|
||||
# Add to shared tx store
|
||||
self.tx_store.add_transaction(tx)
|
||||
for c in self.connections:
|
||||
c.cb.tx_request_map[tx.sha256] = False
|
||||
# Again, either inv to all nodes or save for later
|
||||
if (test_instance.sync_every_tx):
|
||||
[ c.cb.send_inv(tx) for c in self.connections ]
|
||||
self.sync_transaction(tx.sha256, 1)
|
||||
if (not self.check_mempool(tx.sha256, outcome)):
|
||||
raise AssertionError("Test failed at test %d" % test_number)
|
||||
else:
|
||||
invqueue.append(CInv(1, tx.sha256))
|
||||
# Ensure we're not overflowing the inv queue
|
||||
if len(invqueue) == MAX_INV_SZ:
|
||||
[ c.sb.send_message(msg_inv(invqueue)) for c in self.connections ]
|
||||
invqueue = []
|
||||
|
||||
# Do final sync if we weren't syncing on every block or every tx.
|
||||
if (not test_instance.sync_every_block and block is not None):
|
||||
if len(invqueue) > 0:
|
||||
[ c.send_message(msg_inv(invqueue)) for c in self.connections ]
|
||||
invqueue = []
|
||||
self.sync_blocks(block.sha256,
|
||||
len(test_instance.blocks_and_transactions))
|
||||
if (not self.check_results(block.sha256, block_outcome)):
|
||||
raise AssertionError("Block test failed at test %d" % test_number)
|
||||
if (not test_instance.sync_every_tx and tx is not None):
|
||||
if len(invqueue) > 0:
|
||||
[ c.send_message(msg_inv(invqueue)) for c in self.connections ]
|
||||
invqueue = []
|
||||
self.sync_transaction(tx.sha256, len(test_instance.blocks_and_transactions))
|
||||
if (not self.check_mempool(tx.sha256, tx_outcome)):
|
||||
raise AssertionError("Mempool test failed at test %d" % test_number)
|
||||
|
||||
print "Test %d: PASS" % test_number, [ c.rpc.getblockcount() for c in self.connections ]
|
||||
test_number += 1
|
||||
|
||||
self.block_store.close()
|
||||
self.tx_store.close()
|
||||
[ c.disconnect_node() for c in self.connections ]
|
|
@ -84,11 +84,11 @@ WaitPeers "$B1ARGS" 1
|
|||
|
||||
# 2 block, 50 XBT each == 100 XBT
|
||||
# These will be transactions "A" and "B"
|
||||
$CLI $B1ARGS setgenerate true 2
|
||||
$CLI $B1ARGS generate 2
|
||||
|
||||
WaitBlocks
|
||||
# 100 blocks, 0 mature == 0 XBT
|
||||
$CLI $B2ARGS setgenerate true 100
|
||||
$CLI $B2ARGS generate 100
|
||||
WaitBlocks
|
||||
|
||||
CheckBalance "$B1ARGS" 100
|
||||
|
@ -130,7 +130,7 @@ WaitPeers "$B1ARGS" 1
|
|||
|
||||
# Having B2 mine the next block puts the mutated
|
||||
# transaction C in the chain:
|
||||
$CLI $B2ARGS setgenerate true 1
|
||||
$CLI $B2ARGS generate 1
|
||||
WaitBlocks
|
||||
|
||||
# B1 should still be able to spend 100, because D is conflicted
|
||||
|
|
|
@ -34,12 +34,12 @@ class ForkNotifyTest(BitcoinTestFramework):
|
|||
|
||||
def run_test(self):
|
||||
# Mine 51 up-version blocks
|
||||
self.nodes[1].setgenerate(True, 51)
|
||||
self.nodes[1].generate(51)
|
||||
self.sync_all()
|
||||
# -alertnotify should trigger on the 51'st,
|
||||
# but mine and sync another to give
|
||||
# -alertnotify time to write
|
||||
self.nodes[1].setgenerate(True, 1)
|
||||
self.nodes[1].generate(1)
|
||||
self.sync_all()
|
||||
|
||||
with open(self.alert_filename, 'r') as f:
|
||||
|
@ -49,9 +49,9 @@ class ForkNotifyTest(BitcoinTestFramework):
|
|||
raise AssertionError("-alertnotify did not warn of up-version blocks")
|
||||
|
||||
# Mine more up-version blocks, should not get more alerts:
|
||||
self.nodes[1].setgenerate(True, 1)
|
||||
self.nodes[1].generate(1)
|
||||
self.sync_all()
|
||||
self.nodes[1].setgenerate(True, 1)
|
||||
self.nodes[1].generate(1)
|
||||
self.sync_all()
|
||||
|
||||
with open(self.alert_filename, 'r') as f:
|
||||
|
|
|
@ -51,7 +51,7 @@ class GetBlockTemplateLPTest(BitcoinTestFramework):
|
|||
|
||||
def run_test(self):
|
||||
print "Warning: this test will take about 70 seconds in the best case. Be patient."
|
||||
self.nodes[0].setgenerate(True, 10)
|
||||
self.nodes[0].generate(10)
|
||||
templat = self.nodes[0].getblocktemplate()
|
||||
longpollid = templat['longpollid']
|
||||
# longpollid should not change between successive invocations if nothing else happens
|
||||
|
@ -66,7 +66,7 @@ class GetBlockTemplateLPTest(BitcoinTestFramework):
|
|||
assert(thr.is_alive())
|
||||
|
||||
# Test 2: test that longpoll will terminate if another node generates a block
|
||||
self.nodes[1].setgenerate(True, 1) # generate a block on another node
|
||||
self.nodes[1].generate(1) # generate a block on another node
|
||||
# check that thread will exit now that new transaction entered mempool
|
||||
thr.join(5) # wait 5 seconds or until thread exits
|
||||
assert(not thr.is_alive())
|
||||
|
@ -74,7 +74,7 @@ class GetBlockTemplateLPTest(BitcoinTestFramework):
|
|||
# Test 3: test that longpoll will terminate if we generate a block ourselves
|
||||
thr = LongpollThread(self.nodes[0])
|
||||
thr.start()
|
||||
self.nodes[0].setgenerate(True, 1) # generate a block on another node
|
||||
self.nodes[0].generate(1) # generate a block on another node
|
||||
thr.join(5) # wait 5 seconds or until thread exits
|
||||
assert(not thr.is_alive())
|
||||
|
||||
|
|
|
@ -95,7 +95,7 @@ class GetBlockTemplateProposalTest(BitcoinTestFramework):
|
|||
|
||||
def run_test(self):
|
||||
node = self.nodes[0]
|
||||
node.setgenerate(True, 1) # Mine a block to leave initial block download
|
||||
node.generate(1) # Mine a block to leave initial block download
|
||||
tmpl = node.getblocktemplate()
|
||||
if 'coinbasetxn' not in tmpl:
|
||||
rawcoinbase = encodeUNum(tmpl['height'])
|
||||
|
|
|
@ -23,8 +23,8 @@ class GetChainTipsTest (BitcoinTestFramework):
|
|||
|
||||
# Split the network and build two chains of different lengths.
|
||||
self.split_network ()
|
||||
self.nodes[0].setgenerate (True, 10);
|
||||
self.nodes[2].setgenerate (True, 20);
|
||||
self.nodes[0].generate(10);
|
||||
self.nodes[2].generate(20);
|
||||
self.sync_all ()
|
||||
|
||||
tips = self.nodes[1].getchaintips ()
|
||||
|
|
|
@ -28,12 +28,12 @@ class InvalidateTest(BitcoinTestFramework):
|
|||
def run_test(self):
|
||||
print "Make sure we repopulate setBlockIndexCandidates after InvalidateBlock:"
|
||||
print "Mine 4 blocks on Node 0"
|
||||
self.nodes[0].setgenerate(True, 4)
|
||||
self.nodes[0].generate(4)
|
||||
assert(self.nodes[0].getblockcount() == 4)
|
||||
besthash = self.nodes[0].getbestblockhash()
|
||||
|
||||
print "Mine competing 6 blocks on Node 1"
|
||||
self.nodes[1].setgenerate(True, 6)
|
||||
self.nodes[1].generate(6)
|
||||
assert(self.nodes[1].getblockcount() == 6)
|
||||
|
||||
print "Connect nodes to force a reorg"
|
||||
|
@ -61,7 +61,7 @@ class InvalidateTest(BitcoinTestFramework):
|
|||
self.nodes[2].invalidateblock(self.nodes[2].getblockhash(3))
|
||||
assert(self.nodes[2].getblockcount() == 2)
|
||||
print "..and then mine a block"
|
||||
self.nodes[2].setgenerate(True, 1)
|
||||
self.nodes[2].generate(1)
|
||||
print "Verify all nodes are at the right height"
|
||||
time.sleep(5)
|
||||
for i in xrange(3):
|
||||
|
|
115
qa/rpc-tests/invalidblockrequest.py
Executable file
115
qa/rpc-tests/invalidblockrequest.py
Executable file
|
@ -0,0 +1,115 @@
|
|||
#!/usr/bin/env python2
|
||||
#
|
||||
# Distributed under the MIT/X11 software license, see the accompanying
|
||||
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
#
|
||||
|
||||
from test_framework import ComparisonTestFramework
|
||||
from util import *
|
||||
from comptool import TestManager, TestInstance
|
||||
from mininode import *
|
||||
from blocktools import *
|
||||
import logging
|
||||
import copy
|
||||
import time
|
||||
|
||||
|
||||
'''
|
||||
In this test we connect to one node over p2p, and test block requests:
|
||||
1) Valid blocks should be requested and become chain tip.
|
||||
2) Invalid block with duplicated transaction should be re-requested.
|
||||
3) Invalid block with bad coinbase value should be rejected and not
|
||||
re-requested.
|
||||
'''
|
||||
|
||||
# Use the ComparisonTestFramework with 1 node: only use --testbinary.
|
||||
class InvalidBlockRequestTest(ComparisonTestFramework):
|
||||
|
||||
''' Can either run this test as 1 node with expected answers, or two and compare them.
|
||||
Change the "outcome" variable from each TestInstance object to only do the comparison. '''
|
||||
def __init__(self):
|
||||
self.num_nodes = 1
|
||||
|
||||
def run_test(self):
|
||||
test = TestManager(self, self.options.tmpdir)
|
||||
test.add_all_connections(self.nodes)
|
||||
self.tip = None
|
||||
self.block_time = None
|
||||
NetworkThread().start() # Start up network handling in another thread
|
||||
test.run()
|
||||
|
||||
def get_tests(self):
|
||||
if self.tip is None:
|
||||
self.tip = int ("0x" + self.nodes[0].getbestblockhash() + "L", 0)
|
||||
self.block_time = int(time.time())+1
|
||||
|
||||
'''
|
||||
Create a new block with an anyone-can-spend coinbase
|
||||
'''
|
||||
block = create_block(self.tip, create_coinbase(), self.block_time)
|
||||
self.block_time += 1
|
||||
block.solve()
|
||||
# Save the coinbase for later
|
||||
self.block1 = block
|
||||
self.tip = block.sha256
|
||||
yield TestInstance([[block, True]])
|
||||
|
||||
'''
|
||||
Now we need that block to mature so we can spend the coinbase.
|
||||
'''
|
||||
test = TestInstance(sync_every_block=False)
|
||||
for i in xrange(100):
|
||||
block = create_block(self.tip, create_coinbase(), self.block_time)
|
||||
block.solve()
|
||||
self.tip = block.sha256
|
||||
self.block_time += 1
|
||||
test.blocks_and_transactions.append([block, True])
|
||||
yield test
|
||||
|
||||
'''
|
||||
Now we use merkle-root malleability to generate an invalid block with
|
||||
same blockheader.
|
||||
Manufacture a block with 3 transactions (coinbase, spend of prior
|
||||
coinbase, spend of that spend). Duplicate the 3rd transaction to
|
||||
leave merkle root and blockheader unchanged but invalidate the block.
|
||||
'''
|
||||
block2 = create_block(self.tip, create_coinbase(), self.block_time)
|
||||
self.block_time += 1
|
||||
|
||||
# chr(81) is OP_TRUE
|
||||
tx1 = create_transaction(self.block1.vtx[0], 0, chr(81), 50*100000000)
|
||||
tx2 = create_transaction(tx1, 0, chr(81), 50*100000000)
|
||||
|
||||
block2.vtx.extend([tx1, tx2])
|
||||
block2.hashMerkleRoot = block2.calc_merkle_root()
|
||||
block2.rehash()
|
||||
block2.solve()
|
||||
orig_hash = block2.sha256
|
||||
block2_orig = copy.deepcopy(block2)
|
||||
|
||||
# Mutate block 2
|
||||
block2.vtx.append(tx2)
|
||||
assert_equal(block2.hashMerkleRoot, block2.calc_merkle_root())
|
||||
assert_equal(orig_hash, block2.rehash())
|
||||
assert(block2_orig.vtx != block2.vtx)
|
||||
|
||||
self.tip = block2.sha256
|
||||
yield TestInstance([[block2, False], [block2_orig, True]])
|
||||
|
||||
'''
|
||||
Make sure that a totally screwed up block is not valid.
|
||||
'''
|
||||
block3 = create_block(self.tip, create_coinbase(), self.block_time)
|
||||
self.block_time += 1
|
||||
block3.vtx[0].vout[0].nValue = 100*100000000 # Too high!
|
||||
block3.vtx[0].sha256=None
|
||||
block3.vtx[0].calc_sha256()
|
||||
block3.hashMerkleRoot = block3.calc_merkle_root()
|
||||
block3.rehash()
|
||||
block3.solve()
|
||||
|
||||
yield TestInstance([[block3, False]])
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
InvalidBlockRequestTest().main()
|
|
@ -44,7 +44,7 @@ class ListTransactionsTest(BitcoinTestFramework):
|
|||
{"txid":txid},
|
||||
{"category":"receive","account":"","amount":Decimal("0.1"),"confirmations":0})
|
||||
# mine a block, confirmations should change:
|
||||
self.nodes[0].setgenerate(True, 1)
|
||||
self.nodes[0].generate(1)
|
||||
self.sync_all()
|
||||
check_array_result(self.nodes[0].listtransactions(),
|
||||
{"txid":txid},
|
||||
|
|
100
qa/rpc-tests/maxblocksinflight.py
Executable file
100
qa/rpc-tests/maxblocksinflight.py
Executable file
|
@ -0,0 +1,100 @@
|
|||
#!/usr/bin/env python2
|
||||
#
|
||||
# Distributed under the MIT/X11 software license, see the accompanying
|
||||
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
#
|
||||
|
||||
from mininode import *
|
||||
from test_framework import BitcoinTestFramework
|
||||
from util import *
|
||||
import logging
|
||||
|
||||
'''
|
||||
In this test we connect to one node over p2p, send it numerous inv's, and
|
||||
compare the resulting number of getdata requests to a max allowed value. We
|
||||
test for exceeding 128 blocks in flight, which was the limit an 0.9 client will
|
||||
reach. [0.10 clients shouldn't request more than 16 from a single peer.]
|
||||
'''
|
||||
MAX_REQUESTS = 128
|
||||
|
||||
class TestManager(NodeConnCB):
|
||||
# set up NodeConnCB callbacks, overriding base class
|
||||
def on_getdata(self, conn, message):
|
||||
self.log.debug("got getdata %s" % repr(message))
|
||||
# Log the requests
|
||||
for inv in message.inv:
|
||||
if inv.hash not in self.blockReqCounts:
|
||||
self.blockReqCounts[inv.hash] = 0
|
||||
self.blockReqCounts[inv.hash] += 1
|
||||
|
||||
def on_close(self, conn):
|
||||
if not self.disconnectOkay:
|
||||
raise EarlyDisconnectError(0)
|
||||
|
||||
def __init__(self):
|
||||
NodeConnCB.__init__(self)
|
||||
self.log = logging.getLogger("BlockRelayTest")
|
||||
self.create_callback_map()
|
||||
|
||||
def add_new_connection(self, connection):
|
||||
self.connection = connection
|
||||
self.blockReqCounts = {}
|
||||
self.disconnectOkay = False
|
||||
|
||||
def run(self):
|
||||
try:
|
||||
fail = False
|
||||
self.connection.rpc.generate(1) # Leave IBD
|
||||
|
||||
numBlocksToGenerate = [ 8, 16, 128, 1024 ]
|
||||
for count in range(len(numBlocksToGenerate)):
|
||||
current_invs = []
|
||||
for i in range(numBlocksToGenerate[count]):
|
||||
current_invs.append(CInv(2, random.randrange(0, 1<<256)))
|
||||
if len(current_invs) >= 50000:
|
||||
self.connection.send_message(msg_inv(current_invs))
|
||||
current_invs = []
|
||||
if len(current_invs) > 0:
|
||||
self.connection.send_message(msg_inv(current_invs))
|
||||
|
||||
# Wait and see how many blocks were requested
|
||||
time.sleep(2)
|
||||
|
||||
total_requests = 0
|
||||
for key in self.blockReqCounts:
|
||||
total_requests += self.blockReqCounts[key]
|
||||
if self.blockReqCounts[key] > 1:
|
||||
raise AssertionError("Error, test failed: block %064x requested more than once" % key)
|
||||
if total_requests > MAX_REQUESTS:
|
||||
raise AssertionError("Error, too many blocks (%d) requested" % total_requests)
|
||||
print "Round %d: success (total requests: %d)" % (count, total_requests)
|
||||
except AssertionError as e:
|
||||
print "TEST FAILED: ", e.args
|
||||
|
||||
self.disconnectOkay = True
|
||||
self.connection.disconnect_node()
|
||||
|
||||
|
||||
class MaxBlocksInFlightTest(BitcoinTestFramework):
|
||||
def add_options(self, parser):
|
||||
parser.add_option("--testbinary", dest="testbinary",
|
||||
default=os.getenv("BITCOIND", "bitcoind"),
|
||||
help="Binary to test max block requests behavior")
|
||||
|
||||
def setup_chain(self):
|
||||
print "Initializing test directory "+self.options.tmpdir
|
||||
initialize_chain_clean(self.options.tmpdir, 1)
|
||||
|
||||
def setup_network(self):
|
||||
self.nodes = start_nodes(1, self.options.tmpdir,
|
||||
extra_args=[['-debug', '-whitelist=127.0.0.1']],
|
||||
binary=[self.options.testbinary])
|
||||
|
||||
def run_test(self):
|
||||
test = TestManager()
|
||||
test.add_new_connection(NodeConn('127.0.0.1', p2p_port(0), self.nodes[0], test))
|
||||
NetworkThread().start() # Start up network handling in another thread
|
||||
test.run()
|
||||
|
||||
if __name__ == '__main__':
|
||||
MaxBlocksInFlightTest().main()
|
|
@ -41,7 +41,7 @@ class MempoolCoinbaseTest(BitcoinTestFramework):
|
|||
|
||||
# Mine three blocks. After this, nodes[0] blocks
|
||||
# 101, 102, and 103 are spend-able.
|
||||
new_blocks = self.nodes[1].setgenerate(True, 4)
|
||||
new_blocks = self.nodes[1].generate(4)
|
||||
self.sync_all()
|
||||
|
||||
node0_address = self.nodes[0].getnewaddress()
|
||||
|
@ -62,7 +62,7 @@ class MempoolCoinbaseTest(BitcoinTestFramework):
|
|||
# Broadcast and mine spend_102 and 103:
|
||||
spend_102_id = self.nodes[0].sendrawtransaction(spend_102_raw)
|
||||
spend_103_id = self.nodes[0].sendrawtransaction(spend_103_raw)
|
||||
self.nodes[0].setgenerate(True, 1)
|
||||
self.nodes[0].generate(1)
|
||||
|
||||
# Create 102_1 and 103_1:
|
||||
spend_102_1_raw = self.create_tx(spend_102_id, node1_address, 50)
|
||||
|
@ -70,7 +70,7 @@ class MempoolCoinbaseTest(BitcoinTestFramework):
|
|||
|
||||
# Broadcast and mine 103_1:
|
||||
spend_103_1_id = self.nodes[0].sendrawtransaction(spend_103_1_raw)
|
||||
self.nodes[0].setgenerate(True, 1)
|
||||
self.nodes[0].generate(1)
|
||||
|
||||
# ... now put spend_101 and spend_102_1 in memory pools:
|
||||
spend_101_id = self.nodes[0].sendrawtransaction(spend_101_raw)
|
||||
|
|
|
@ -51,12 +51,12 @@ class MempoolCoinbaseTest(BitcoinTestFramework):
|
|||
spends1_id = [ self.nodes[0].sendrawtransaction(tx) for tx in spends1_raw ]
|
||||
|
||||
blocks = []
|
||||
blocks.extend(self.nodes[0].setgenerate(True, 1))
|
||||
blocks.extend(self.nodes[0].generate(1))
|
||||
|
||||
spends2_raw = [ self.create_tx(txid, node0_address, 49.99) for txid in spends1_id ]
|
||||
spends2_id = [ self.nodes[0].sendrawtransaction(tx) for tx in spends2_raw ]
|
||||
|
||||
blocks.extend(self.nodes[0].setgenerate(True, 1))
|
||||
blocks.extend(self.nodes[0].generate(1))
|
||||
|
||||
# mempool should be empty, all txns confirmed
|
||||
assert_equal(set(self.nodes[0].getrawmempool()), set())
|
||||
|
@ -76,7 +76,7 @@ class MempoolCoinbaseTest(BitcoinTestFramework):
|
|||
assert(tx["confirmations"] == 0)
|
||||
|
||||
# Generate another block, they should all get mined
|
||||
self.nodes[0].setgenerate(True, 1)
|
||||
self.nodes[0].generate(1)
|
||||
# mempool should be empty, all txns confirmed
|
||||
assert_equal(set(self.nodes[0].getrawmempool()), set())
|
||||
for txid in spends1_id+spends2_id:
|
||||
|
|
|
@ -58,7 +58,7 @@ class MempoolSpendCoinbaseTest(BitcoinTestFramework):
|
|||
assert_equal(self.nodes[0].getrawmempool(), [ spend_101_id ])
|
||||
|
||||
# mine a block, spend_101 should get confirmed
|
||||
self.nodes[0].setgenerate(True, 1)
|
||||
self.nodes[0].generate(1)
|
||||
assert_equal(set(self.nodes[0].getrawmempool()), set())
|
||||
|
||||
# ... and now height 102 can be spent:
|
||||
|
|
90
qa/rpc-tests/merkle_blocks.py
Executable file
90
qa/rpc-tests/merkle_blocks.py
Executable file
|
@ -0,0 +1,90 @@
|
|||
#!/usr/bin/env python2
|
||||
# Copyright (c) 2014 The Bitcoin Core developers
|
||||
# Distributed under the MIT software license, see the accompanying
|
||||
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#
|
||||
# Test merkleblock fetch/validation
|
||||
#
|
||||
|
||||
from test_framework import BitcoinTestFramework
|
||||
from bitcoinrpc.authproxy import AuthServiceProxy, JSONRPCException
|
||||
from util import *
|
||||
import os
|
||||
import shutil
|
||||
|
||||
class MerkleBlockTest(BitcoinTestFramework):
|
||||
|
||||
def setup_chain(self):
|
||||
print("Initializing test directory "+self.options.tmpdir)
|
||||
initialize_chain_clean(self.options.tmpdir, 4)
|
||||
|
||||
def setup_network(self):
|
||||
self.nodes = []
|
||||
# Nodes 0/1 are "wallet" nodes
|
||||
self.nodes.append(start_node(0, self.options.tmpdir, ["-debug"]))
|
||||
self.nodes.append(start_node(1, self.options.tmpdir, ["-debug"]))
|
||||
# Nodes 2/3 are used for testing
|
||||
self.nodes.append(start_node(2, self.options.tmpdir, ["-debug"]))
|
||||
self.nodes.append(start_node(3, self.options.tmpdir, ["-debug", "-txindex"]))
|
||||
connect_nodes(self.nodes[0], 1)
|
||||
connect_nodes(self.nodes[0], 2)
|
||||
connect_nodes(self.nodes[0], 3)
|
||||
|
||||
self.is_network_split = False
|
||||
self.sync_all()
|
||||
|
||||
def run_test(self):
|
||||
print "Mining blocks..."
|
||||
self.nodes[0].generate(105)
|
||||
self.sync_all()
|
||||
|
||||
chain_height = self.nodes[1].getblockcount()
|
||||
assert_equal(chain_height, 105)
|
||||
assert_equal(self.nodes[1].getbalance(), 0)
|
||||
assert_equal(self.nodes[2].getbalance(), 0)
|
||||
|
||||
node0utxos = self.nodes[0].listunspent(1)
|
||||
tx1 = self.nodes[0].createrawtransaction([node0utxos.pop()], {self.nodes[1].getnewaddress(): 50})
|
||||
txid1 = self.nodes[0].sendrawtransaction(self.nodes[0].signrawtransaction(tx1)["hex"])
|
||||
tx2 = self.nodes[0].createrawtransaction([node0utxos.pop()], {self.nodes[1].getnewaddress(): 50})
|
||||
txid2 = self.nodes[0].sendrawtransaction(self.nodes[0].signrawtransaction(tx2)["hex"])
|
||||
assert_raises(JSONRPCException, self.nodes[0].gettxoutproof, [txid1])
|
||||
|
||||
self.nodes[0].generate(1)
|
||||
blockhash = self.nodes[0].getblockhash(chain_height + 1)
|
||||
self.sync_all()
|
||||
|
||||
txlist = []
|
||||
blocktxn = self.nodes[0].getblock(blockhash, True)["tx"]
|
||||
txlist.append(blocktxn[1])
|
||||
txlist.append(blocktxn[2])
|
||||
|
||||
assert_equal(self.nodes[2].verifytxoutproof(self.nodes[2].gettxoutproof([txid1])), [txid1])
|
||||
assert_equal(self.nodes[2].verifytxoutproof(self.nodes[2].gettxoutproof([txid1, txid2])), txlist)
|
||||
assert_equal(self.nodes[2].verifytxoutproof(self.nodes[2].gettxoutproof([txid1, txid2], blockhash)), txlist)
|
||||
|
||||
txin_spent = self.nodes[1].listunspent(1).pop()
|
||||
tx3 = self.nodes[1].createrawtransaction([txin_spent], {self.nodes[0].getnewaddress(): 50})
|
||||
self.nodes[0].sendrawtransaction(self.nodes[1].signrawtransaction(tx3)["hex"])
|
||||
self.nodes[0].generate(1)
|
||||
self.sync_all()
|
||||
|
||||
txid_spent = txin_spent["txid"]
|
||||
txid_unspent = txid1 if txin_spent["txid"] != txid1 else txid2
|
||||
|
||||
# We cant find the block from a fully-spent tx
|
||||
assert_raises(JSONRPCException, self.nodes[2].gettxoutproof, [txid_spent])
|
||||
# ...but we can if we specify the block
|
||||
assert_equal(self.nodes[2].verifytxoutproof(self.nodes[2].gettxoutproof([txid_spent], blockhash)), [txid_spent])
|
||||
# ...or if the first tx is not fully-spent
|
||||
assert_equal(self.nodes[2].verifytxoutproof(self.nodes[2].gettxoutproof([txid_unspent])), [txid_unspent])
|
||||
try:
|
||||
assert_equal(self.nodes[2].verifytxoutproof(self.nodes[2].gettxoutproof([txid1, txid2])), txlist)
|
||||
except JSONRPCException:
|
||||
assert_equal(self.nodes[2].verifytxoutproof(self.nodes[2].gettxoutproof([txid2, txid1])), txlist)
|
||||
# ...or if we have a -txindex
|
||||
assert_equal(self.nodes[2].verifytxoutproof(self.nodes[3].gettxoutproof([txid_spent])), [txid_spent])
|
||||
|
||||
if __name__ == '__main__':
|
||||
MerkleBlockTest().main()
|
1247
qa/rpc-tests/mininode.py
Executable file
1247
qa/rpc-tests/mininode.py
Executable file
File diff suppressed because it is too large
Load diff
146
qa/rpc-tests/proxy_test.py
Executable file
146
qa/rpc-tests/proxy_test.py
Executable file
|
@ -0,0 +1,146 @@
|
|||
#!/usr/bin/env python2
|
||||
# Copyright (c) 2015 The Bitcoin Core developers
|
||||
# Distributed under the MIT software license, see the accompanying
|
||||
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
import socket
|
||||
import traceback, sys
|
||||
from binascii import hexlify
|
||||
import time, os
|
||||
|
||||
from socks5 import Socks5Configuration, Socks5Command, Socks5Server, AddressType
|
||||
from test_framework import BitcoinTestFramework
|
||||
from util import *
|
||||
'''
|
||||
Test plan:
|
||||
- Start bitcoind's with different proxy configurations
|
||||
- Use addnode to initiate connections
|
||||
- Verify that proxies are connected to, and the right connection command is given
|
||||
- Proxy configurations to test on bitcoind side:
|
||||
- `-proxy` (proxy everything)
|
||||
- `-onion` (proxy just onions)
|
||||
- `-proxyrandomize` Circuit randomization
|
||||
- Proxy configurations to test on proxy side,
|
||||
- support no authentication (other proxy)
|
||||
- support no authentication + user/pass authentication (Tor)
|
||||
- proxy on IPv6
|
||||
|
||||
- Create various proxies (as threads)
|
||||
- Create bitcoinds that connect to them
|
||||
- Manipulate the bitcoinds using addnode (onetry) an observe effects
|
||||
|
||||
addnode connect to IPv4
|
||||
addnode connect to IPv6
|
||||
addnode connect to onion
|
||||
addnode connect to generic DNS name
|
||||
'''
|
||||
|
||||
class ProxyTest(BitcoinTestFramework):
|
||||
def __init__(self):
|
||||
# Create two proxies on different ports
|
||||
# ... one unauthenticated
|
||||
self.conf1 = Socks5Configuration()
|
||||
self.conf1.addr = ('127.0.0.1', 13000 + (os.getpid() % 1000))
|
||||
self.conf1.unauth = True
|
||||
self.conf1.auth = False
|
||||
# ... one supporting authenticated and unauthenticated (Tor)
|
||||
self.conf2 = Socks5Configuration()
|
||||
self.conf2.addr = ('127.0.0.1', 14000 + (os.getpid() % 1000))
|
||||
self.conf2.unauth = True
|
||||
self.conf2.auth = True
|
||||
# ... one on IPv6 with similar configuration
|
||||
self.conf3 = Socks5Configuration()
|
||||
self.conf3.af = socket.AF_INET6
|
||||
self.conf3.addr = ('::1', 15000 + (os.getpid() % 1000))
|
||||
self.conf3.unauth = True
|
||||
self.conf3.auth = True
|
||||
|
||||
self.serv1 = Socks5Server(self.conf1)
|
||||
self.serv1.start()
|
||||
self.serv2 = Socks5Server(self.conf2)
|
||||
self.serv2.start()
|
||||
self.serv3 = Socks5Server(self.conf3)
|
||||
self.serv3.start()
|
||||
|
||||
def setup_nodes(self):
|
||||
# Note: proxies are not used to connect to local nodes
|
||||
# this is because the proxy to use is based on CService.GetNetwork(), which return NET_UNROUTABLE for localhost
|
||||
return start_nodes(4, self.options.tmpdir, extra_args=[
|
||||
['-listen', '-debug=net', '-debug=proxy', '-proxy=%s:%i' % (self.conf1.addr),'-proxyrandomize=1'],
|
||||
['-listen', '-debug=net', '-debug=proxy', '-proxy=%s:%i' % (self.conf1.addr),'-onion=%s:%i' % (self.conf2.addr),'-proxyrandomize=0'],
|
||||
['-listen', '-debug=net', '-debug=proxy', '-proxy=%s:%i' % (self.conf2.addr),'-proxyrandomize=1'],
|
||||
['-listen', '-debug=net', '-debug=proxy', '-proxy=[%s]:%i' % (self.conf3.addr),'-proxyrandomize=0']
|
||||
])
|
||||
|
||||
def node_test(self, node, proxies, auth):
|
||||
rv = []
|
||||
# Test: outgoing IPv4 connection through node
|
||||
node.addnode("15.61.23.23:1234", "onetry")
|
||||
cmd = proxies[0].queue.get()
|
||||
assert(isinstance(cmd, Socks5Command))
|
||||
# Note: bitcoind's SOCKS5 implementation only sends atyp DOMAINNAME, even if connecting directly to IPv4/IPv6
|
||||
assert_equal(cmd.atyp, AddressType.DOMAINNAME)
|
||||
assert_equal(cmd.addr, "15.61.23.23")
|
||||
assert_equal(cmd.port, 1234)
|
||||
if not auth:
|
||||
assert_equal(cmd.username, None)
|
||||
assert_equal(cmd.password, None)
|
||||
rv.append(cmd)
|
||||
|
||||
# Test: outgoing IPv6 connection through node
|
||||
node.addnode("[1233:3432:2434:2343:3234:2345:6546:4534]:5443", "onetry")
|
||||
cmd = proxies[1].queue.get()
|
||||
assert(isinstance(cmd, Socks5Command))
|
||||
# Note: bitcoind's SOCKS5 implementation only sends atyp DOMAINNAME, even if connecting directly to IPv4/IPv6
|
||||
assert_equal(cmd.atyp, AddressType.DOMAINNAME)
|
||||
assert_equal(cmd.addr, "1233:3432:2434:2343:3234:2345:6546:4534")
|
||||
assert_equal(cmd.port, 5443)
|
||||
if not auth:
|
||||
assert_equal(cmd.username, None)
|
||||
assert_equal(cmd.password, None)
|
||||
rv.append(cmd)
|
||||
|
||||
# Test: outgoing onion connection through node
|
||||
node.addnode("bitcoinostk4e4re.onion:8333", "onetry")
|
||||
cmd = proxies[2].queue.get()
|
||||
assert(isinstance(cmd, Socks5Command))
|
||||
assert_equal(cmd.atyp, AddressType.DOMAINNAME)
|
||||
assert_equal(cmd.addr, "bitcoinostk4e4re.onion")
|
||||
assert_equal(cmd.port, 8333)
|
||||
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")
|
||||
cmd = proxies[3].queue.get()
|
||||
assert(isinstance(cmd, Socks5Command))
|
||||
assert_equal(cmd.atyp, AddressType.DOMAINNAME)
|
||||
assert_equal(cmd.addr, "node.noumenon")
|
||||
assert_equal(cmd.port, 8333)
|
||||
if not auth:
|
||||
assert_equal(cmd.username, None)
|
||||
assert_equal(cmd.password, None)
|
||||
rv.append(cmd)
|
||||
|
||||
return rv
|
||||
|
||||
def run_test(self):
|
||||
# basic -proxy
|
||||
self.node_test(self.nodes[0], [self.serv1, self.serv1, self.serv1, self.serv1], False)
|
||||
|
||||
# -proxy plus -onion
|
||||
self.node_test(self.nodes[1], [self.serv1, self.serv1, self.serv2, self.serv1], False)
|
||||
|
||||
# -proxy plus -onion, -proxyrandomize
|
||||
rv = self.node_test(self.nodes[2], [self.serv2, self.serv2, self.serv2, self.serv2], True)
|
||||
# Check that credentials as used for -proxyrandomize connections are unique
|
||||
credentials = set((x.username,x.password) for x in rv)
|
||||
assert_equal(len(credentials), 4)
|
||||
|
||||
# proxy on IPv6 localhost
|
||||
self.node_test(self.nodes[3], [self.serv3, self.serv3, self.serv3, self.serv3], False)
|
||||
|
||||
if __name__ == '__main__':
|
||||
ProxyTest().main()
|
||||
|
356
qa/rpc-tests/pruning.py
Executable file
356
qa/rpc-tests/pruning.py
Executable file
|
@ -0,0 +1,356 @@
|
|||
#!/usr/bin/env python2
|
||||
# Copyright (c) 2014 The Bitcoin Core developers
|
||||
# Distributed under the MIT software license, see the accompanying
|
||||
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#
|
||||
# Test pruning code
|
||||
# ********
|
||||
# WARNING:
|
||||
# This test uses 4GB of disk space and takes in excess of 30 mins to run
|
||||
# ********
|
||||
|
||||
from test_framework import BitcoinTestFramework
|
||||
from bitcoinrpc.authproxy import AuthServiceProxy, JSONRPCException
|
||||
from util import *
|
||||
import os.path
|
||||
|
||||
def calc_usage(blockdir):
|
||||
return sum(os.path.getsize(blockdir+f) for f in os.listdir(blockdir) if os.path.isfile(blockdir+f))/(1024*1024)
|
||||
|
||||
class PruneTest(BitcoinTestFramework):
|
||||
|
||||
def __init__(self):
|
||||
self.utxo = []
|
||||
self.address = ["",""]
|
||||
|
||||
# Some pre-processing to create a bunch of OP_RETURN txouts to insert into transactions we create
|
||||
# So we have big transactions and full blocks to fill up our block files
|
||||
|
||||
# create one script_pubkey
|
||||
script_pubkey = "6a4d0200" #OP_RETURN OP_PUSH2 512 bytes
|
||||
for i in xrange (512):
|
||||
script_pubkey = script_pubkey + "01"
|
||||
# concatenate 128 txouts of above script_pubkey which we'll insert before the txout for change
|
||||
self.txouts = "81"
|
||||
for k in xrange(128):
|
||||
# add txout value
|
||||
self.txouts = self.txouts + "0000000000000000"
|
||||
# add length of script_pubkey
|
||||
self.txouts = self.txouts + "fd0402"
|
||||
# add script_pubkey
|
||||
self.txouts = self.txouts + script_pubkey
|
||||
|
||||
|
||||
def setup_chain(self):
|
||||
print("Initializing test directory "+self.options.tmpdir)
|
||||
initialize_chain_clean(self.options.tmpdir, 3)
|
||||
|
||||
def setup_network(self):
|
||||
self.nodes = []
|
||||
self.is_network_split = False
|
||||
|
||||
# Create nodes 0 and 1 to mine
|
||||
self.nodes.append(start_node(0, self.options.tmpdir, ["-debug","-maxreceivebuffer=20000","-blockmaxsize=999000", "-checkblocks=5"], timewait=300))
|
||||
self.nodes.append(start_node(1, self.options.tmpdir, ["-debug","-maxreceivebuffer=20000","-blockmaxsize=999000", "-checkblocks=5"], timewait=300))
|
||||
|
||||
# Create node 2 to test pruning
|
||||
self.nodes.append(start_node(2, self.options.tmpdir, ["-debug","-maxreceivebuffer=20000","-prune=550"], timewait=300))
|
||||
self.prunedir = self.options.tmpdir+"/node2/regtest/blocks/"
|
||||
|
||||
self.address[0] = self.nodes[0].getnewaddress()
|
||||
self.address[1] = self.nodes[1].getnewaddress()
|
||||
|
||||
connect_nodes(self.nodes[0], 1)
|
||||
connect_nodes(self.nodes[1], 2)
|
||||
connect_nodes(self.nodes[2], 0)
|
||||
sync_blocks(self.nodes[0:3])
|
||||
|
||||
def create_big_chain(self):
|
||||
# Start by creating some coinbases we can spend later
|
||||
self.nodes[1].generate(200)
|
||||
sync_blocks(self.nodes[0:2])
|
||||
self.nodes[0].generate(150)
|
||||
# Then mine enough full blocks to create more than 550MB of data
|
||||
for i in xrange(645):
|
||||
self.mine_full_block(self.nodes[0], self.address[0])
|
||||
|
||||
sync_blocks(self.nodes[0:3])
|
||||
|
||||
def test_height_min(self):
|
||||
if not os.path.isfile(self.prunedir+"blk00000.dat"):
|
||||
raise AssertionError("blk00000.dat is missing, pruning too early")
|
||||
print "Success"
|
||||
print "Though we're already using more than 550MB, current usage:", calc_usage(self.prunedir)
|
||||
print "Mining 25 more blocks should cause the first block file to be pruned"
|
||||
# Pruning doesn't run until we're allocating another chunk, 20 full blocks past the height cutoff will ensure this
|
||||
for i in xrange(25):
|
||||
self.mine_full_block(self.nodes[0],self.address[0])
|
||||
|
||||
waitstart = time.time()
|
||||
while os.path.isfile(self.prunedir+"blk00000.dat"):
|
||||
time.sleep(0.1)
|
||||
if time.time() - waitstart > 10:
|
||||
raise AssertionError("blk00000.dat not pruned when it should be")
|
||||
|
||||
print "Success"
|
||||
usage = calc_usage(self.prunedir)
|
||||
print "Usage should be below target:", usage
|
||||
if (usage > 550):
|
||||
raise AssertionError("Pruning target not being met")
|
||||
|
||||
def create_chain_with_staleblocks(self):
|
||||
# Create stale blocks in manageable sized chunks
|
||||
print "Mine 24 (stale) blocks on Node 1, followed by 25 (main chain) block reorg from Node 0, for 12 rounds"
|
||||
|
||||
for j in xrange(12):
|
||||
# Disconnect node 0 so it can mine a longer reorg chain without knowing about node 1's soon-to-be-stale chain
|
||||
# Node 2 stays connected, so it hears about the stale blocks and then reorg's when node0 reconnects
|
||||
# Stopping node 0 also clears its mempool, so it doesn't have node1's transactions to accidentally mine
|
||||
stop_node(self.nodes[0],0)
|
||||
self.nodes[0]=start_node(0, self.options.tmpdir, ["-debug","-maxreceivebuffer=20000","-blockmaxsize=999000", "-checkblocks=5"], timewait=300)
|
||||
# Mine 24 blocks in node 1
|
||||
self.utxo = self.nodes[1].listunspent()
|
||||
for i in xrange(24):
|
||||
if j == 0:
|
||||
self.mine_full_block(self.nodes[1],self.address[1])
|
||||
else:
|
||||
self.nodes[1].generate(1) #tx's already in mempool from previous disconnects
|
||||
|
||||
# Reorg back with 25 block chain from node 0
|
||||
self.utxo = self.nodes[0].listunspent()
|
||||
for i in xrange(25):
|
||||
self.mine_full_block(self.nodes[0],self.address[0])
|
||||
|
||||
# Create connections in the order so both nodes can see the reorg at the same time
|
||||
connect_nodes(self.nodes[1], 0)
|
||||
connect_nodes(self.nodes[2], 0)
|
||||
sync_blocks(self.nodes[0:3])
|
||||
|
||||
print "Usage can be over target because of high stale rate:", calc_usage(self.prunedir)
|
||||
|
||||
def reorg_test(self):
|
||||
# Node 1 will mine a 300 block chain starting 287 blocks back from Node 0 and Node 2's tip
|
||||
# This will cause Node 2 to do a reorg requiring 288 blocks of undo data to the reorg_test chain
|
||||
# Reboot node 1 to clear its mempool (hopefully make the invalidate faster)
|
||||
# Lower the block max size so we don't keep mining all our big mempool transactions (from disconnected blocks)
|
||||
stop_node(self.nodes[1],1)
|
||||
self.nodes[1]=start_node(1, self.options.tmpdir, ["-debug","-maxreceivebuffer=20000","-blockmaxsize=5000", "-checkblocks=5", "-disablesafemode"], timewait=300)
|
||||
|
||||
height = self.nodes[1].getblockcount()
|
||||
print "Current block height:", height
|
||||
|
||||
invalidheight = height-287
|
||||
badhash = self.nodes[1].getblockhash(invalidheight)
|
||||
print "Invalidating block at height:",invalidheight,badhash
|
||||
self.nodes[1].invalidateblock(badhash)
|
||||
|
||||
# We've now switched to our previously mined-24 block fork on node 1, but thats not what we want
|
||||
# So invalidate that fork as well, until we're on the same chain as node 0/2 (but at an ancestor 288 blocks ago)
|
||||
mainchainhash = self.nodes[0].getblockhash(invalidheight - 1)
|
||||
curhash = self.nodes[1].getblockhash(invalidheight - 1)
|
||||
while curhash != mainchainhash:
|
||||
self.nodes[1].invalidateblock(curhash)
|
||||
curhash = self.nodes[1].getblockhash(invalidheight - 1)
|
||||
|
||||
assert(self.nodes[1].getblockcount() == invalidheight - 1)
|
||||
print "New best height", self.nodes[1].getblockcount()
|
||||
|
||||
# Reboot node1 to clear those giant tx's from mempool
|
||||
stop_node(self.nodes[1],1)
|
||||
self.nodes[1]=start_node(1, self.options.tmpdir, ["-debug","-maxreceivebuffer=20000","-blockmaxsize=5000", "-checkblocks=5", "-disablesafemode"], timewait=300)
|
||||
|
||||
print "Generating new longer chain of 300 more blocks"
|
||||
self.nodes[1].generate(300)
|
||||
|
||||
print "Reconnect nodes"
|
||||
connect_nodes(self.nodes[0], 1)
|
||||
connect_nodes(self.nodes[2], 1)
|
||||
sync_blocks(self.nodes[0:3])
|
||||
|
||||
print "Verify height on node 2:",self.nodes[2].getblockcount()
|
||||
print "Usage possibly still high bc of stale blocks in block files:", calc_usage(self.prunedir)
|
||||
|
||||
print "Mine 220 more blocks so we have requisite history (some blocks will be big and cause pruning of previous chain)"
|
||||
self.nodes[0].generate(220) #node 0 has many large tx's in its mempool from the disconnects
|
||||
sync_blocks(self.nodes[0:3])
|
||||
|
||||
usage = calc_usage(self.prunedir)
|
||||
print "Usage should be below target:", usage
|
||||
if (usage > 550):
|
||||
raise AssertionError("Pruning target not being met")
|
||||
|
||||
return invalidheight,badhash
|
||||
|
||||
def reorg_back(self):
|
||||
# Verify that a block on the old main chain fork has been pruned away
|
||||
try:
|
||||
self.nodes[2].getblock(self.forkhash)
|
||||
raise AssertionError("Old block wasn't pruned so can't test redownload")
|
||||
except JSONRPCException as e:
|
||||
print "Will need to redownload block",self.forkheight
|
||||
|
||||
# Verify that we have enough history to reorg back to the fork point
|
||||
# Although this is more than 288 blocks, because this chain was written more recently
|
||||
# and only its other 299 small and 220 large block are in the block files after it,
|
||||
# its expected to still be retained
|
||||
self.nodes[2].getblock(self.nodes[2].getblockhash(self.forkheight))
|
||||
|
||||
first_reorg_height = self.nodes[2].getblockcount()
|
||||
curchainhash = self.nodes[2].getblockhash(self.mainchainheight)
|
||||
self.nodes[2].invalidateblock(curchainhash)
|
||||
goalbestheight = self.mainchainheight
|
||||
goalbesthash = self.mainchainhash2
|
||||
|
||||
# As of 0.10 the current block download logic is not able to reorg to the original chain created in
|
||||
# create_chain_with_stale_blocks because it doesn't know of any peer thats on that chain from which to
|
||||
# redownload its missing blocks.
|
||||
# Invalidate the reorg_test chain in node 0 as well, it can successfully switch to the original chain
|
||||
# because it has all the block data.
|
||||
# However it must mine enough blocks to have a more work chain than the reorg_test chain in order
|
||||
# to trigger node 2's block download logic.
|
||||
# At this point node 2 is within 288 blocks of the fork point so it will preserve its ability to reorg
|
||||
if self.nodes[2].getblockcount() < self.mainchainheight:
|
||||
blocks_to_mine = first_reorg_height + 1 - self.mainchainheight
|
||||
print "Rewind node 0 to prev main chain to mine longer chain to trigger redownload. Blocks needed:", blocks_to_mine
|
||||
self.nodes[0].invalidateblock(curchainhash)
|
||||
assert(self.nodes[0].getblockcount() == self.mainchainheight)
|
||||
assert(self.nodes[0].getbestblockhash() == self.mainchainhash2)
|
||||
goalbesthash = self.nodes[0].generate(blocks_to_mine)[-1]
|
||||
goalbestheight = first_reorg_height + 1
|
||||
|
||||
print "Verify node 2 reorged back to the main chain, some blocks of which it had to redownload"
|
||||
waitstart = time.time()
|
||||
while self.nodes[2].getblockcount() < goalbestheight:
|
||||
time.sleep(0.1)
|
||||
if time.time() - waitstart > 300:
|
||||
raise AssertionError("Node 2 didn't reorg to proper height")
|
||||
assert(self.nodes[2].getbestblockhash() == goalbesthash)
|
||||
# Verify we can now have the data for a block previously pruned
|
||||
assert(self.nodes[2].getblock(self.forkhash)["height"] == self.forkheight)
|
||||
|
||||
def mine_full_block(self, node, address):
|
||||
# Want to create a full block
|
||||
# We'll generate a 66k transaction below, and 14 of them is close to the 1MB block limit
|
||||
for j in xrange(14):
|
||||
if len(self.utxo) < 14:
|
||||
self.utxo = node.listunspent()
|
||||
inputs=[]
|
||||
outputs = {}
|
||||
t = self.utxo.pop()
|
||||
inputs.append({ "txid" : t["txid"], "vout" : t["vout"]})
|
||||
remchange = t["amount"] - Decimal("0.001000")
|
||||
outputs[address]=remchange
|
||||
# Create a basic transaction that will send change back to ourself after account for a fee
|
||||
# And then insert the 128 generated transaction outs in the middle rawtx[92] is where the #
|
||||
# of txouts is stored and is the only thing we overwrite from the original transaction
|
||||
rawtx = node.createrawtransaction(inputs, outputs)
|
||||
newtx = rawtx[0:92]
|
||||
newtx = newtx + self.txouts
|
||||
newtx = newtx + rawtx[94:]
|
||||
# Appears to be ever so slightly faster to sign with SIGHASH_NONE
|
||||
signresult = node.signrawtransaction(newtx,None,None,"NONE")
|
||||
txid = node.sendrawtransaction(signresult["hex"], True)
|
||||
# Mine a full sized block which will be these transactions we just created
|
||||
node.generate(1)
|
||||
|
||||
|
||||
def run_test(self):
|
||||
print "Warning! This test requires 4GB of disk space and takes over 30 mins"
|
||||
print "Mining a big blockchain of 995 blocks"
|
||||
self.create_big_chain()
|
||||
# Chain diagram key:
|
||||
# * blocks on main chain
|
||||
# +,&,$,@ blocks on other forks
|
||||
# X invalidated block
|
||||
# N1 Node 1
|
||||
#
|
||||
# Start by mining a simple chain that all nodes have
|
||||
# N0=N1=N2 **...*(995)
|
||||
|
||||
print "Check that we haven't started pruning yet because we're below PruneAfterHeight"
|
||||
self.test_height_min()
|
||||
# Extend this chain past the PruneAfterHeight
|
||||
# N0=N1=N2 **...*(1020)
|
||||
|
||||
print "Check that we'll exceed disk space target if we have a very high stale block rate"
|
||||
self.create_chain_with_staleblocks()
|
||||
# Disconnect N0
|
||||
# And mine a 24 block chain on N1 and a separate 25 block chain on N0
|
||||
# N1=N2 **...*+...+(1044)
|
||||
# N0 **...**...**(1045)
|
||||
#
|
||||
# reconnect nodes causing reorg on N1 and N2
|
||||
# N1=N2 **...*(1020) *...**(1045)
|
||||
# \
|
||||
# +...+(1044)
|
||||
#
|
||||
# repeat this process until you have 12 stale forks hanging off the
|
||||
# main chain on N1 and N2
|
||||
# N0 *************************...***************************(1320)
|
||||
#
|
||||
# N1=N2 **...*(1020) *...**(1045) *.. ..**(1295) *...**(1320)
|
||||
# \ \ \
|
||||
# +...+(1044) &.. $...$(1319)
|
||||
|
||||
# Save some current chain state for later use
|
||||
self.mainchainheight = self.nodes[2].getblockcount() #1320
|
||||
self.mainchainhash2 = self.nodes[2].getblockhash(self.mainchainheight)
|
||||
|
||||
print "Check that we can survive a 288 block reorg still"
|
||||
(self.forkheight,self.forkhash) = self.reorg_test() #(1033, )
|
||||
# Now create a 288 block reorg by mining a longer chain on N1
|
||||
# First disconnect N1
|
||||
# Then invalidate 1033 on main chain and 1032 on fork so height is 1032 on main chain
|
||||
# N1 **...*(1020) **...**(1032)X..
|
||||
# \
|
||||
# ++...+(1031)X..
|
||||
#
|
||||
# Now mine 300 more blocks on N1
|
||||
# N1 **...*(1020) **...**(1032) @@...@(1332)
|
||||
# \ \
|
||||
# \ X...
|
||||
# \ \
|
||||
# ++...+(1031)X.. ..
|
||||
#
|
||||
# Reconnect nodes and mine 220 more blocks on N1
|
||||
# N1 **...*(1020) **...**(1032) @@...@@@(1552)
|
||||
# \ \
|
||||
# \ X...
|
||||
# \ \
|
||||
# ++...+(1031)X.. ..
|
||||
#
|
||||
# N2 **...*(1020) **...**(1032) @@...@@@(1552)
|
||||
# \ \
|
||||
# \ *...**(1320)
|
||||
# \ \
|
||||
# ++...++(1044) ..
|
||||
#
|
||||
# N0 ********************(1032) @@...@@@(1552)
|
||||
# \
|
||||
# *...**(1320)
|
||||
|
||||
print "Test that we can rerequest a block we previously pruned if needed for a reorg"
|
||||
self.reorg_back()
|
||||
# Verify that N2 still has block 1033 on current chain (@), but not on main chain (*)
|
||||
# Invalidate 1033 on current chain (@) on N2 and we should be able to reorg to
|
||||
# original main chain (*), but will require redownload of some blocks
|
||||
# In order to have a peer we think we can download from, must also perform this invalidation
|
||||
# on N0 and mine a new longest chain to trigger.
|
||||
# Final result:
|
||||
# N0 ********************(1032) **...****(1553)
|
||||
# \
|
||||
# X@...@@@(1552)
|
||||
#
|
||||
# N2 **...*(1020) **...**(1032) **...****(1553)
|
||||
# \ \
|
||||
# \ X@...@@@(1552)
|
||||
# \
|
||||
# +..
|
||||
#
|
||||
# N1 doesn't change because 1033 on main chain (*) is invalid
|
||||
|
||||
print "Done"
|
||||
|
||||
if __name__ == '__main__':
|
||||
PruneTest().main()
|
|
@ -69,7 +69,7 @@ class ReceivedByTest(BitcoinTestFramework):
|
|||
{ },
|
||||
True)
|
||||
#Bury Tx under 10 block so it will be returned by listreceivedbyaddress
|
||||
self.nodes[1].setgenerate(True, 10)
|
||||
self.nodes[1].generate(10)
|
||||
self.sync_all()
|
||||
check_array_result(self.nodes[1].listreceivedbyaddress(),
|
||||
{"address":addr},
|
||||
|
@ -106,7 +106,7 @@ class ReceivedByTest(BitcoinTestFramework):
|
|||
raise AssertionError("Wrong balance returned by getreceivedbyaddress, %0.2f"%(balance))
|
||||
|
||||
#Bury Tx under 10 block so it will be returned by the default getreceivedbyaddress
|
||||
self.nodes[1].setgenerate(True, 10)
|
||||
self.nodes[1].generate(10)
|
||||
self.sync_all()
|
||||
balance = self.nodes[1].getreceivedbyaddress(addr)
|
||||
if balance != Decimal("0.1"):
|
||||
|
@ -136,7 +136,7 @@ class ReceivedByTest(BitcoinTestFramework):
|
|||
if balance != balance_by_account:
|
||||
raise AssertionError("Wrong balance returned by getreceivedbyaccount, %0.2f"%(balance))
|
||||
|
||||
self.nodes[1].setgenerate(True, 10)
|
||||
self.nodes[1].generate(10)
|
||||
self.sync_all()
|
||||
# listreceivedbyaccount should return updated account balance
|
||||
check_array_result(self.nodes[1].listreceivedbyaccount(),
|
||||
|
|
34
qa/rpc-tests/reindex.py
Executable file
34
qa/rpc-tests/reindex.py
Executable file
|
@ -0,0 +1,34 @@
|
|||
#!/usr/bin/env python2
|
||||
# Copyright (c) 2014 The Bitcoin Core developers
|
||||
# Distributed under the MIT software license, see the accompanying
|
||||
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#
|
||||
# Test -reindex with CheckBlockIndex
|
||||
#
|
||||
from test_framework import BitcoinTestFramework
|
||||
from bitcoinrpc.authproxy import AuthServiceProxy, JSONRPCException
|
||||
from util import *
|
||||
import os.path
|
||||
|
||||
class ReindexTest(BitcoinTestFramework):
|
||||
|
||||
def setup_chain(self):
|
||||
print("Initializing test directory "+self.options.tmpdir)
|
||||
initialize_chain_clean(self.options.tmpdir, 1)
|
||||
|
||||
def setup_network(self):
|
||||
self.nodes = []
|
||||
self.is_network_split = False
|
||||
self.nodes.append(start_node(0, self.options.tmpdir))
|
||||
|
||||
def run_test(self):
|
||||
self.nodes[0].generate(3)
|
||||
stop_node(self.nodes[0], 0)
|
||||
wait_bitcoinds()
|
||||
self.nodes[0]=start_node(0, self.options.tmpdir, ["-debug", "-reindex", "-checkblockindex=1"])
|
||||
assert_equal(self.nodes[0].getblockcount(), 3)
|
||||
print "Success"
|
||||
|
||||
if __name__ == '__main__':
|
||||
ReindexTest().main()
|
|
@ -90,7 +90,7 @@ class RESTTest (BitcoinTestFramework):
|
|||
self.sync_all()
|
||||
|
||||
# now mine the transactions
|
||||
newblockhash = self.nodes[1].setgenerate(True, 1)
|
||||
newblockhash = self.nodes[1].generate(1)
|
||||
self.sync_all()
|
||||
|
||||
#check if the 3 tx show up in the new block
|
||||
|
|
896
qa/rpc-tests/script.py
Normal file
896
qa/rpc-tests/script.py
Normal file
|
@ -0,0 +1,896 @@
|
|||
#
|
||||
# script.py
|
||||
#
|
||||
# This file is modified from python-bitcoinlib.
|
||||
#
|
||||
# Distributed under the MIT/X11 software license, see the accompanying
|
||||
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
#
|
||||
|
||||
"""Scripts
|
||||
|
||||
Functionality to build scripts, as well as SignatureHash().
|
||||
"""
|
||||
|
||||
from __future__ import absolute_import, division, print_function, unicode_literals
|
||||
|
||||
from mininode import CTransaction, CTxOut, hash256
|
||||
|
||||
import sys
|
||||
bchr = chr
|
||||
bord = ord
|
||||
if sys.version > '3':
|
||||
long = int
|
||||
bchr = lambda x: bytes([x])
|
||||
bord = lambda x: x
|
||||
|
||||
import copy
|
||||
import struct
|
||||
|
||||
import bignum
|
||||
|
||||
MAX_SCRIPT_SIZE = 10000
|
||||
MAX_SCRIPT_ELEMENT_SIZE = 520
|
||||
MAX_SCRIPT_OPCODES = 201
|
||||
|
||||
OPCODE_NAMES = {}
|
||||
|
||||
_opcode_instances = []
|
||||
class CScriptOp(int):
|
||||
"""A single script opcode"""
|
||||
__slots__ = []
|
||||
|
||||
@staticmethod
|
||||
def encode_op_pushdata(d):
|
||||
"""Encode a PUSHDATA op, returning bytes"""
|
||||
if len(d) < 0x4c:
|
||||
return b'' + bchr(len(d)) + d # OP_PUSHDATA
|
||||
elif len(d) <= 0xff:
|
||||
return b'\x4c' + bchr(len(d)) + d # OP_PUSHDATA1
|
||||
elif len(d) <= 0xffff:
|
||||
return b'\x4d' + struct.pack(b'<H', len(d)) + d # OP_PUSHDATA2
|
||||
elif len(d) <= 0xffffffff:
|
||||
return b'\x4e' + struct.pack(b'<I', len(d)) + d # OP_PUSHDATA4
|
||||
else:
|
||||
raise ValueError("Data too long to encode in a PUSHDATA op")
|
||||
|
||||
@staticmethod
|
||||
def encode_op_n(n):
|
||||
"""Encode a small integer op, returning an opcode"""
|
||||
if not (0 <= n <= 16):
|
||||
raise ValueError('Integer must be in range 0 <= n <= 16, got %d' % n)
|
||||
|
||||
if n == 0:
|
||||
return OP_0
|
||||
else:
|
||||
return CScriptOp(OP_1 + n-1)
|
||||
|
||||
def decode_op_n(self):
|
||||
"""Decode a small integer opcode, returning an integer"""
|
||||
if self == OP_0:
|
||||
return 0
|
||||
|
||||
if not (self == OP_0 or OP_1 <= self <= OP_16):
|
||||
raise ValueError('op %r is not an OP_N' % self)
|
||||
|
||||
return int(self - OP_1+1)
|
||||
|
||||
def is_small_int(self):
|
||||
"""Return true if the op pushes a small integer to the stack"""
|
||||
if 0x51 <= self <= 0x60 or self == 0:
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
def __str__(self):
|
||||
return repr(self)
|
||||
|
||||
def __repr__(self):
|
||||
if self in OPCODE_NAMES:
|
||||
return OPCODE_NAMES[self]
|
||||
else:
|
||||
return 'CScriptOp(0x%x)' % self
|
||||
|
||||
def __new__(cls, n):
|
||||
try:
|
||||
return _opcode_instances[n]
|
||||
except IndexError:
|
||||
assert len(_opcode_instances) == n
|
||||
_opcode_instances.append(super(CScriptOp, cls).__new__(cls, n))
|
||||
return _opcode_instances[n]
|
||||
|
||||
# Populate opcode instance table
|
||||
for n in range(0xff+1):
|
||||
CScriptOp(n)
|
||||
|
||||
|
||||
# push value
|
||||
OP_0 = CScriptOp(0x00)
|
||||
OP_FALSE = OP_0
|
||||
OP_PUSHDATA1 = CScriptOp(0x4c)
|
||||
OP_PUSHDATA2 = CScriptOp(0x4d)
|
||||
OP_PUSHDATA4 = CScriptOp(0x4e)
|
||||
OP_1NEGATE = CScriptOp(0x4f)
|
||||
OP_RESERVED = CScriptOp(0x50)
|
||||
OP_1 = CScriptOp(0x51)
|
||||
OP_TRUE=OP_1
|
||||
OP_2 = CScriptOp(0x52)
|
||||
OP_3 = CScriptOp(0x53)
|
||||
OP_4 = CScriptOp(0x54)
|
||||
OP_5 = CScriptOp(0x55)
|
||||
OP_6 = CScriptOp(0x56)
|
||||
OP_7 = CScriptOp(0x57)
|
||||
OP_8 = CScriptOp(0x58)
|
||||
OP_9 = CScriptOp(0x59)
|
||||
OP_10 = CScriptOp(0x5a)
|
||||
OP_11 = CScriptOp(0x5b)
|
||||
OP_12 = CScriptOp(0x5c)
|
||||
OP_13 = CScriptOp(0x5d)
|
||||
OP_14 = CScriptOp(0x5e)
|
||||
OP_15 = CScriptOp(0x5f)
|
||||
OP_16 = CScriptOp(0x60)
|
||||
|
||||
# control
|
||||
OP_NOP = CScriptOp(0x61)
|
||||
OP_VER = CScriptOp(0x62)
|
||||
OP_IF = CScriptOp(0x63)
|
||||
OP_NOTIF = CScriptOp(0x64)
|
||||
OP_VERIF = CScriptOp(0x65)
|
||||
OP_VERNOTIF = CScriptOp(0x66)
|
||||
OP_ELSE = CScriptOp(0x67)
|
||||
OP_ENDIF = CScriptOp(0x68)
|
||||
OP_VERIFY = CScriptOp(0x69)
|
||||
OP_RETURN = CScriptOp(0x6a)
|
||||
|
||||
# stack ops
|
||||
OP_TOALTSTACK = CScriptOp(0x6b)
|
||||
OP_FROMALTSTACK = CScriptOp(0x6c)
|
||||
OP_2DROP = CScriptOp(0x6d)
|
||||
OP_2DUP = CScriptOp(0x6e)
|
||||
OP_3DUP = CScriptOp(0x6f)
|
||||
OP_2OVER = CScriptOp(0x70)
|
||||
OP_2ROT = CScriptOp(0x71)
|
||||
OP_2SWAP = CScriptOp(0x72)
|
||||
OP_IFDUP = CScriptOp(0x73)
|
||||
OP_DEPTH = CScriptOp(0x74)
|
||||
OP_DROP = CScriptOp(0x75)
|
||||
OP_DUP = CScriptOp(0x76)
|
||||
OP_NIP = CScriptOp(0x77)
|
||||
OP_OVER = CScriptOp(0x78)
|
||||
OP_PICK = CScriptOp(0x79)
|
||||
OP_ROLL = CScriptOp(0x7a)
|
||||
OP_ROT = CScriptOp(0x7b)
|
||||
OP_SWAP = CScriptOp(0x7c)
|
||||
OP_TUCK = CScriptOp(0x7d)
|
||||
|
||||
# splice ops
|
||||
OP_CAT = CScriptOp(0x7e)
|
||||
OP_SUBSTR = CScriptOp(0x7f)
|
||||
OP_LEFT = CScriptOp(0x80)
|
||||
OP_RIGHT = CScriptOp(0x81)
|
||||
OP_SIZE = CScriptOp(0x82)
|
||||
|
||||
# bit logic
|
||||
OP_INVERT = CScriptOp(0x83)
|
||||
OP_AND = CScriptOp(0x84)
|
||||
OP_OR = CScriptOp(0x85)
|
||||
OP_XOR = CScriptOp(0x86)
|
||||
OP_EQUAL = CScriptOp(0x87)
|
||||
OP_EQUALVERIFY = CScriptOp(0x88)
|
||||
OP_RESERVED1 = CScriptOp(0x89)
|
||||
OP_RESERVED2 = CScriptOp(0x8a)
|
||||
|
||||
# numeric
|
||||
OP_1ADD = CScriptOp(0x8b)
|
||||
OP_1SUB = CScriptOp(0x8c)
|
||||
OP_2MUL = CScriptOp(0x8d)
|
||||
OP_2DIV = CScriptOp(0x8e)
|
||||
OP_NEGATE = CScriptOp(0x8f)
|
||||
OP_ABS = CScriptOp(0x90)
|
||||
OP_NOT = CScriptOp(0x91)
|
||||
OP_0NOTEQUAL = CScriptOp(0x92)
|
||||
|
||||
OP_ADD = CScriptOp(0x93)
|
||||
OP_SUB = CScriptOp(0x94)
|
||||
OP_MUL = CScriptOp(0x95)
|
||||
OP_DIV = CScriptOp(0x96)
|
||||
OP_MOD = CScriptOp(0x97)
|
||||
OP_LSHIFT = CScriptOp(0x98)
|
||||
OP_RSHIFT = CScriptOp(0x99)
|
||||
|
||||
OP_BOOLAND = CScriptOp(0x9a)
|
||||
OP_BOOLOR = CScriptOp(0x9b)
|
||||
OP_NUMEQUAL = CScriptOp(0x9c)
|
||||
OP_NUMEQUALVERIFY = CScriptOp(0x9d)
|
||||
OP_NUMNOTEQUAL = CScriptOp(0x9e)
|
||||
OP_LESSTHAN = CScriptOp(0x9f)
|
||||
OP_GREATERTHAN = CScriptOp(0xa0)
|
||||
OP_LESSTHANOREQUAL = CScriptOp(0xa1)
|
||||
OP_GREATERTHANOREQUAL = CScriptOp(0xa2)
|
||||
OP_MIN = CScriptOp(0xa3)
|
||||
OP_MAX = CScriptOp(0xa4)
|
||||
|
||||
OP_WITHIN = CScriptOp(0xa5)
|
||||
|
||||
# crypto
|
||||
OP_RIPEMD160 = CScriptOp(0xa6)
|
||||
OP_SHA1 = CScriptOp(0xa7)
|
||||
OP_SHA256 = CScriptOp(0xa8)
|
||||
OP_HASH160 = CScriptOp(0xa9)
|
||||
OP_HASH256 = CScriptOp(0xaa)
|
||||
OP_CODESEPARATOR = CScriptOp(0xab)
|
||||
OP_CHECKSIG = CScriptOp(0xac)
|
||||
OP_CHECKSIGVERIFY = CScriptOp(0xad)
|
||||
OP_CHECKMULTISIG = CScriptOp(0xae)
|
||||
OP_CHECKMULTISIGVERIFY = CScriptOp(0xaf)
|
||||
|
||||
# expansion
|
||||
OP_NOP1 = CScriptOp(0xb0)
|
||||
OP_NOP2 = CScriptOp(0xb1)
|
||||
OP_NOP3 = CScriptOp(0xb2)
|
||||
OP_NOP4 = CScriptOp(0xb3)
|
||||
OP_NOP5 = CScriptOp(0xb4)
|
||||
OP_NOP6 = CScriptOp(0xb5)
|
||||
OP_NOP7 = CScriptOp(0xb6)
|
||||
OP_NOP8 = CScriptOp(0xb7)
|
||||
OP_NOP9 = CScriptOp(0xb8)
|
||||
OP_NOP10 = CScriptOp(0xb9)
|
||||
|
||||
# template matching params
|
||||
OP_SMALLINTEGER = CScriptOp(0xfa)
|
||||
OP_PUBKEYS = CScriptOp(0xfb)
|
||||
OP_PUBKEYHASH = CScriptOp(0xfd)
|
||||
OP_PUBKEY = CScriptOp(0xfe)
|
||||
|
||||
OP_INVALIDOPCODE = CScriptOp(0xff)
|
||||
|
||||
VALID_OPCODES = {
|
||||
OP_1NEGATE,
|
||||
OP_RESERVED,
|
||||
OP_1,
|
||||
OP_2,
|
||||
OP_3,
|
||||
OP_4,
|
||||
OP_5,
|
||||
OP_6,
|
||||
OP_7,
|
||||
OP_8,
|
||||
OP_9,
|
||||
OP_10,
|
||||
OP_11,
|
||||
OP_12,
|
||||
OP_13,
|
||||
OP_14,
|
||||
OP_15,
|
||||
OP_16,
|
||||
|
||||
OP_NOP,
|
||||
OP_VER,
|
||||
OP_IF,
|
||||
OP_NOTIF,
|
||||
OP_VERIF,
|
||||
OP_VERNOTIF,
|
||||
OP_ELSE,
|
||||
OP_ENDIF,
|
||||
OP_VERIFY,
|
||||
OP_RETURN,
|
||||
|
||||
OP_TOALTSTACK,
|
||||
OP_FROMALTSTACK,
|
||||
OP_2DROP,
|
||||
OP_2DUP,
|
||||
OP_3DUP,
|
||||
OP_2OVER,
|
||||
OP_2ROT,
|
||||
OP_2SWAP,
|
||||
OP_IFDUP,
|
||||
OP_DEPTH,
|
||||
OP_DROP,
|
||||
OP_DUP,
|
||||
OP_NIP,
|
||||
OP_OVER,
|
||||
OP_PICK,
|
||||
OP_ROLL,
|
||||
OP_ROT,
|
||||
OP_SWAP,
|
||||
OP_TUCK,
|
||||
|
||||
OP_CAT,
|
||||
OP_SUBSTR,
|
||||
OP_LEFT,
|
||||
OP_RIGHT,
|
||||
OP_SIZE,
|
||||
|
||||
OP_INVERT,
|
||||
OP_AND,
|
||||
OP_OR,
|
||||
OP_XOR,
|
||||
OP_EQUAL,
|
||||
OP_EQUALVERIFY,
|
||||
OP_RESERVED1,
|
||||
OP_RESERVED2,
|
||||
|
||||
OP_1ADD,
|
||||
OP_1SUB,
|
||||
OP_2MUL,
|
||||
OP_2DIV,
|
||||
OP_NEGATE,
|
||||
OP_ABS,
|
||||
OP_NOT,
|
||||
OP_0NOTEQUAL,
|
||||
|
||||
OP_ADD,
|
||||
OP_SUB,
|
||||
OP_MUL,
|
||||
OP_DIV,
|
||||
OP_MOD,
|
||||
OP_LSHIFT,
|
||||
OP_RSHIFT,
|
||||
|
||||
OP_BOOLAND,
|
||||
OP_BOOLOR,
|
||||
OP_NUMEQUAL,
|
||||
OP_NUMEQUALVERIFY,
|
||||
OP_NUMNOTEQUAL,
|
||||
OP_LESSTHAN,
|
||||
OP_GREATERTHAN,
|
||||
OP_LESSTHANOREQUAL,
|
||||
OP_GREATERTHANOREQUAL,
|
||||
OP_MIN,
|
||||
OP_MAX,
|
||||
|
||||
OP_WITHIN,
|
||||
|
||||
OP_RIPEMD160,
|
||||
OP_SHA1,
|
||||
OP_SHA256,
|
||||
OP_HASH160,
|
||||
OP_HASH256,
|
||||
OP_CODESEPARATOR,
|
||||
OP_CHECKSIG,
|
||||
OP_CHECKSIGVERIFY,
|
||||
OP_CHECKMULTISIG,
|
||||
OP_CHECKMULTISIGVERIFY,
|
||||
|
||||
OP_NOP1,
|
||||
OP_NOP2,
|
||||
OP_NOP3,
|
||||
OP_NOP4,
|
||||
OP_NOP5,
|
||||
OP_NOP6,
|
||||
OP_NOP7,
|
||||
OP_NOP8,
|
||||
OP_NOP9,
|
||||
OP_NOP10,
|
||||
|
||||
OP_SMALLINTEGER,
|
||||
OP_PUBKEYS,
|
||||
OP_PUBKEYHASH,
|
||||
OP_PUBKEY,
|
||||
}
|
||||
|
||||
OPCODE_NAMES.update({
|
||||
OP_0 : 'OP_0',
|
||||
OP_PUSHDATA1 : 'OP_PUSHDATA1',
|
||||
OP_PUSHDATA2 : 'OP_PUSHDATA2',
|
||||
OP_PUSHDATA4 : 'OP_PUSHDATA4',
|
||||
OP_1NEGATE : 'OP_1NEGATE',
|
||||
OP_RESERVED : 'OP_RESERVED',
|
||||
OP_1 : 'OP_1',
|
||||
OP_2 : 'OP_2',
|
||||
OP_3 : 'OP_3',
|
||||
OP_4 : 'OP_4',
|
||||
OP_5 : 'OP_5',
|
||||
OP_6 : 'OP_6',
|
||||
OP_7 : 'OP_7',
|
||||
OP_8 : 'OP_8',
|
||||
OP_9 : 'OP_9',
|
||||
OP_10 : 'OP_10',
|
||||
OP_11 : 'OP_11',
|
||||
OP_12 : 'OP_12',
|
||||
OP_13 : 'OP_13',
|
||||
OP_14 : 'OP_14',
|
||||
OP_15 : 'OP_15',
|
||||
OP_16 : 'OP_16',
|
||||
OP_NOP : 'OP_NOP',
|
||||
OP_VER : 'OP_VER',
|
||||
OP_IF : 'OP_IF',
|
||||
OP_NOTIF : 'OP_NOTIF',
|
||||
OP_VERIF : 'OP_VERIF',
|
||||
OP_VERNOTIF : 'OP_VERNOTIF',
|
||||
OP_ELSE : 'OP_ELSE',
|
||||
OP_ENDIF : 'OP_ENDIF',
|
||||
OP_VERIFY : 'OP_VERIFY',
|
||||
OP_RETURN : 'OP_RETURN',
|
||||
OP_TOALTSTACK : 'OP_TOALTSTACK',
|
||||
OP_FROMALTSTACK : 'OP_FROMALTSTACK',
|
||||
OP_2DROP : 'OP_2DROP',
|
||||
OP_2DUP : 'OP_2DUP',
|
||||
OP_3DUP : 'OP_3DUP',
|
||||
OP_2OVER : 'OP_2OVER',
|
||||
OP_2ROT : 'OP_2ROT',
|
||||
OP_2SWAP : 'OP_2SWAP',
|
||||
OP_IFDUP : 'OP_IFDUP',
|
||||
OP_DEPTH : 'OP_DEPTH',
|
||||
OP_DROP : 'OP_DROP',
|
||||
OP_DUP : 'OP_DUP',
|
||||
OP_NIP : 'OP_NIP',
|
||||
OP_OVER : 'OP_OVER',
|
||||
OP_PICK : 'OP_PICK',
|
||||
OP_ROLL : 'OP_ROLL',
|
||||
OP_ROT : 'OP_ROT',
|
||||
OP_SWAP : 'OP_SWAP',
|
||||
OP_TUCK : 'OP_TUCK',
|
||||
OP_CAT : 'OP_CAT',
|
||||
OP_SUBSTR : 'OP_SUBSTR',
|
||||
OP_LEFT : 'OP_LEFT',
|
||||
OP_RIGHT : 'OP_RIGHT',
|
||||
OP_SIZE : 'OP_SIZE',
|
||||
OP_INVERT : 'OP_INVERT',
|
||||
OP_AND : 'OP_AND',
|
||||
OP_OR : 'OP_OR',
|
||||
OP_XOR : 'OP_XOR',
|
||||
OP_EQUAL : 'OP_EQUAL',
|
||||
OP_EQUALVERIFY : 'OP_EQUALVERIFY',
|
||||
OP_RESERVED1 : 'OP_RESERVED1',
|
||||
OP_RESERVED2 : 'OP_RESERVED2',
|
||||
OP_1ADD : 'OP_1ADD',
|
||||
OP_1SUB : 'OP_1SUB',
|
||||
OP_2MUL : 'OP_2MUL',
|
||||
OP_2DIV : 'OP_2DIV',
|
||||
OP_NEGATE : 'OP_NEGATE',
|
||||
OP_ABS : 'OP_ABS',
|
||||
OP_NOT : 'OP_NOT',
|
||||
OP_0NOTEQUAL : 'OP_0NOTEQUAL',
|
||||
OP_ADD : 'OP_ADD',
|
||||
OP_SUB : 'OP_SUB',
|
||||
OP_MUL : 'OP_MUL',
|
||||
OP_DIV : 'OP_DIV',
|
||||
OP_MOD : 'OP_MOD',
|
||||
OP_LSHIFT : 'OP_LSHIFT',
|
||||
OP_RSHIFT : 'OP_RSHIFT',
|
||||
OP_BOOLAND : 'OP_BOOLAND',
|
||||
OP_BOOLOR : 'OP_BOOLOR',
|
||||
OP_NUMEQUAL : 'OP_NUMEQUAL',
|
||||
OP_NUMEQUALVERIFY : 'OP_NUMEQUALVERIFY',
|
||||
OP_NUMNOTEQUAL : 'OP_NUMNOTEQUAL',
|
||||
OP_LESSTHAN : 'OP_LESSTHAN',
|
||||
OP_GREATERTHAN : 'OP_GREATERTHAN',
|
||||
OP_LESSTHANOREQUAL : 'OP_LESSTHANOREQUAL',
|
||||
OP_GREATERTHANOREQUAL : 'OP_GREATERTHANOREQUAL',
|
||||
OP_MIN : 'OP_MIN',
|
||||
OP_MAX : 'OP_MAX',
|
||||
OP_WITHIN : 'OP_WITHIN',
|
||||
OP_RIPEMD160 : 'OP_RIPEMD160',
|
||||
OP_SHA1 : 'OP_SHA1',
|
||||
OP_SHA256 : 'OP_SHA256',
|
||||
OP_HASH160 : 'OP_HASH160',
|
||||
OP_HASH256 : 'OP_HASH256',
|
||||
OP_CODESEPARATOR : 'OP_CODESEPARATOR',
|
||||
OP_CHECKSIG : 'OP_CHECKSIG',
|
||||
OP_CHECKSIGVERIFY : 'OP_CHECKSIGVERIFY',
|
||||
OP_CHECKMULTISIG : 'OP_CHECKMULTISIG',
|
||||
OP_CHECKMULTISIGVERIFY : 'OP_CHECKMULTISIGVERIFY',
|
||||
OP_NOP1 : 'OP_NOP1',
|
||||
OP_NOP2 : 'OP_NOP2',
|
||||
OP_NOP3 : 'OP_NOP3',
|
||||
OP_NOP4 : 'OP_NOP4',
|
||||
OP_NOP5 : 'OP_NOP5',
|
||||
OP_NOP6 : 'OP_NOP6',
|
||||
OP_NOP7 : 'OP_NOP7',
|
||||
OP_NOP8 : 'OP_NOP8',
|
||||
OP_NOP9 : 'OP_NOP9',
|
||||
OP_NOP10 : 'OP_NOP10',
|
||||
OP_SMALLINTEGER : 'OP_SMALLINTEGER',
|
||||
OP_PUBKEYS : 'OP_PUBKEYS',
|
||||
OP_PUBKEYHASH : 'OP_PUBKEYHASH',
|
||||
OP_PUBKEY : 'OP_PUBKEY',
|
||||
OP_INVALIDOPCODE : 'OP_INVALIDOPCODE',
|
||||
})
|
||||
|
||||
OPCODES_BY_NAME = {
|
||||
'OP_0' : OP_0,
|
||||
'OP_PUSHDATA1' : OP_PUSHDATA1,
|
||||
'OP_PUSHDATA2' : OP_PUSHDATA2,
|
||||
'OP_PUSHDATA4' : OP_PUSHDATA4,
|
||||
'OP_1NEGATE' : OP_1NEGATE,
|
||||
'OP_RESERVED' : OP_RESERVED,
|
||||
'OP_1' : OP_1,
|
||||
'OP_2' : OP_2,
|
||||
'OP_3' : OP_3,
|
||||
'OP_4' : OP_4,
|
||||
'OP_5' : OP_5,
|
||||
'OP_6' : OP_6,
|
||||
'OP_7' : OP_7,
|
||||
'OP_8' : OP_8,
|
||||
'OP_9' : OP_9,
|
||||
'OP_10' : OP_10,
|
||||
'OP_11' : OP_11,
|
||||
'OP_12' : OP_12,
|
||||
'OP_13' : OP_13,
|
||||
'OP_14' : OP_14,
|
||||
'OP_15' : OP_15,
|
||||
'OP_16' : OP_16,
|
||||
'OP_NOP' : OP_NOP,
|
||||
'OP_VER' : OP_VER,
|
||||
'OP_IF' : OP_IF,
|
||||
'OP_NOTIF' : OP_NOTIF,
|
||||
'OP_VERIF' : OP_VERIF,
|
||||
'OP_VERNOTIF' : OP_VERNOTIF,
|
||||
'OP_ELSE' : OP_ELSE,
|
||||
'OP_ENDIF' : OP_ENDIF,
|
||||
'OP_VERIFY' : OP_VERIFY,
|
||||
'OP_RETURN' : OP_RETURN,
|
||||
'OP_TOALTSTACK' : OP_TOALTSTACK,
|
||||
'OP_FROMALTSTACK' : OP_FROMALTSTACK,
|
||||
'OP_2DROP' : OP_2DROP,
|
||||
'OP_2DUP' : OP_2DUP,
|
||||
'OP_3DUP' : OP_3DUP,
|
||||
'OP_2OVER' : OP_2OVER,
|
||||
'OP_2ROT' : OP_2ROT,
|
||||
'OP_2SWAP' : OP_2SWAP,
|
||||
'OP_IFDUP' : OP_IFDUP,
|
||||
'OP_DEPTH' : OP_DEPTH,
|
||||
'OP_DROP' : OP_DROP,
|
||||
'OP_DUP' : OP_DUP,
|
||||
'OP_NIP' : OP_NIP,
|
||||
'OP_OVER' : OP_OVER,
|
||||
'OP_PICK' : OP_PICK,
|
||||
'OP_ROLL' : OP_ROLL,
|
||||
'OP_ROT' : OP_ROT,
|
||||
'OP_SWAP' : OP_SWAP,
|
||||
'OP_TUCK' : OP_TUCK,
|
||||
'OP_CAT' : OP_CAT,
|
||||
'OP_SUBSTR' : OP_SUBSTR,
|
||||
'OP_LEFT' : OP_LEFT,
|
||||
'OP_RIGHT' : OP_RIGHT,
|
||||
'OP_SIZE' : OP_SIZE,
|
||||
'OP_INVERT' : OP_INVERT,
|
||||
'OP_AND' : OP_AND,
|
||||
'OP_OR' : OP_OR,
|
||||
'OP_XOR' : OP_XOR,
|
||||
'OP_EQUAL' : OP_EQUAL,
|
||||
'OP_EQUALVERIFY' : OP_EQUALVERIFY,
|
||||
'OP_RESERVED1' : OP_RESERVED1,
|
||||
'OP_RESERVED2' : OP_RESERVED2,
|
||||
'OP_1ADD' : OP_1ADD,
|
||||
'OP_1SUB' : OP_1SUB,
|
||||
'OP_2MUL' : OP_2MUL,
|
||||
'OP_2DIV' : OP_2DIV,
|
||||
'OP_NEGATE' : OP_NEGATE,
|
||||
'OP_ABS' : OP_ABS,
|
||||
'OP_NOT' : OP_NOT,
|
||||
'OP_0NOTEQUAL' : OP_0NOTEQUAL,
|
||||
'OP_ADD' : OP_ADD,
|
||||
'OP_SUB' : OP_SUB,
|
||||
'OP_MUL' : OP_MUL,
|
||||
'OP_DIV' : OP_DIV,
|
||||
'OP_MOD' : OP_MOD,
|
||||
'OP_LSHIFT' : OP_LSHIFT,
|
||||
'OP_RSHIFT' : OP_RSHIFT,
|
||||
'OP_BOOLAND' : OP_BOOLAND,
|
||||
'OP_BOOLOR' : OP_BOOLOR,
|
||||
'OP_NUMEQUAL' : OP_NUMEQUAL,
|
||||
'OP_NUMEQUALVERIFY' : OP_NUMEQUALVERIFY,
|
||||
'OP_NUMNOTEQUAL' : OP_NUMNOTEQUAL,
|
||||
'OP_LESSTHAN' : OP_LESSTHAN,
|
||||
'OP_GREATERTHAN' : OP_GREATERTHAN,
|
||||
'OP_LESSTHANOREQUAL' : OP_LESSTHANOREQUAL,
|
||||
'OP_GREATERTHANOREQUAL' : OP_GREATERTHANOREQUAL,
|
||||
'OP_MIN' : OP_MIN,
|
||||
'OP_MAX' : OP_MAX,
|
||||
'OP_WITHIN' : OP_WITHIN,
|
||||
'OP_RIPEMD160' : OP_RIPEMD160,
|
||||
'OP_SHA1' : OP_SHA1,
|
||||
'OP_SHA256' : OP_SHA256,
|
||||
'OP_HASH160' : OP_HASH160,
|
||||
'OP_HASH256' : OP_HASH256,
|
||||
'OP_CODESEPARATOR' : OP_CODESEPARATOR,
|
||||
'OP_CHECKSIG' : OP_CHECKSIG,
|
||||
'OP_CHECKSIGVERIFY' : OP_CHECKSIGVERIFY,
|
||||
'OP_CHECKMULTISIG' : OP_CHECKMULTISIG,
|
||||
'OP_CHECKMULTISIGVERIFY' : OP_CHECKMULTISIGVERIFY,
|
||||
'OP_NOP1' : OP_NOP1,
|
||||
'OP_NOP2' : OP_NOP2,
|
||||
'OP_NOP3' : OP_NOP3,
|
||||
'OP_NOP4' : OP_NOP4,
|
||||
'OP_NOP5' : OP_NOP5,
|
||||
'OP_NOP6' : OP_NOP6,
|
||||
'OP_NOP7' : OP_NOP7,
|
||||
'OP_NOP8' : OP_NOP8,
|
||||
'OP_NOP9' : OP_NOP9,
|
||||
'OP_NOP10' : OP_NOP10,
|
||||
'OP_SMALLINTEGER' : OP_SMALLINTEGER,
|
||||
'OP_PUBKEYS' : OP_PUBKEYS,
|
||||
'OP_PUBKEYHASH' : OP_PUBKEYHASH,
|
||||
'OP_PUBKEY' : OP_PUBKEY,
|
||||
}
|
||||
|
||||
class CScriptInvalidError(Exception):
|
||||
"""Base class for CScript exceptions"""
|
||||
pass
|
||||
|
||||
class CScriptTruncatedPushDataError(CScriptInvalidError):
|
||||
"""Invalid pushdata due to truncation"""
|
||||
def __init__(self, msg, data):
|
||||
self.data = data
|
||||
super(CScriptTruncatedPushDataError, self).__init__(msg)
|
||||
|
||||
# This is used, eg, for blockchain heights in coinbase scripts (bip34)
|
||||
class CScriptNum(object):
|
||||
def __init__(self, d=0):
|
||||
self.value = d
|
||||
|
||||
@staticmethod
|
||||
def encode(obj):
|
||||
r = bytearray(0)
|
||||
if obj.value == 0:
|
||||
return bytes(r)
|
||||
neg = obj.value < 0
|
||||
absvalue = -obj.value if neg else obj.value
|
||||
while (absvalue):
|
||||
r.append(chr(absvalue & 0xff))
|
||||
absvalue >>= 8
|
||||
if r[-1] & 0x80:
|
||||
r.append(0x80 if neg else 0)
|
||||
elif neg:
|
||||
r[-1] |= 0x80
|
||||
return bytes(bchr(len(r)) + r)
|
||||
|
||||
|
||||
class CScript(bytes):
|
||||
"""Serialized script
|
||||
|
||||
A bytes subclass, so you can use this directly whenever bytes are accepted.
|
||||
Note that this means that indexing does *not* work - you'll get an index by
|
||||
byte rather than opcode. This format was chosen for efficiency so that the
|
||||
general case would not require creating a lot of little CScriptOP objects.
|
||||
|
||||
iter(script) however does iterate by opcode.
|
||||
"""
|
||||
@classmethod
|
||||
def __coerce_instance(cls, other):
|
||||
# Coerce other into bytes
|
||||
if isinstance(other, CScriptOp):
|
||||
other = bchr(other)
|
||||
elif isinstance(other, CScriptNum):
|
||||
if (other.value == 0):
|
||||
other = bchr(CScriptOp(OP_0))
|
||||
else:
|
||||
other = CScriptNum.encode(other)
|
||||
elif isinstance(other, (int, long)):
|
||||
if 0 <= other <= 16:
|
||||
other = bytes(bchr(CScriptOp.encode_op_n(other)))
|
||||
elif other == -1:
|
||||
other = bytes(bchr(OP_1NEGATE))
|
||||
else:
|
||||
other = CScriptOp.encode_op_pushdata(bignum.bn2vch(other))
|
||||
elif isinstance(other, (bytes, bytearray)):
|
||||
other = CScriptOp.encode_op_pushdata(other)
|
||||
return other
|
||||
|
||||
def __add__(self, other):
|
||||
# Do the coercion outside of the try block so that errors in it are
|
||||
# noticed.
|
||||
other = self.__coerce_instance(other)
|
||||
|
||||
try:
|
||||
# bytes.__add__ always returns bytes instances unfortunately
|
||||
return CScript(super(CScript, self).__add__(other))
|
||||
except TypeError:
|
||||
raise TypeError('Can not add a %r instance to a CScript' % other.__class__)
|
||||
|
||||
def join(self, iterable):
|
||||
# join makes no sense for a CScript()
|
||||
raise NotImplementedError
|
||||
|
||||
def __new__(cls, value=b''):
|
||||
if isinstance(value, bytes) or isinstance(value, bytearray):
|
||||
return super(CScript, cls).__new__(cls, value)
|
||||
else:
|
||||
def coerce_iterable(iterable):
|
||||
for instance in iterable:
|
||||
yield cls.__coerce_instance(instance)
|
||||
# Annoyingly on both python2 and python3 bytes.join() always
|
||||
# returns a bytes instance even when subclassed.
|
||||
return super(CScript, cls).__new__(cls, b''.join(coerce_iterable(value)))
|
||||
|
||||
def raw_iter(self):
|
||||
"""Raw iteration
|
||||
|
||||
Yields tuples of (opcode, data, sop_idx) so that the different possible
|
||||
PUSHDATA encodings can be accurately distinguished, as well as
|
||||
determining the exact opcode byte indexes. (sop_idx)
|
||||
"""
|
||||
i = 0
|
||||
while i < len(self):
|
||||
sop_idx = i
|
||||
opcode = bord(self[i])
|
||||
i += 1
|
||||
|
||||
if opcode > OP_PUSHDATA4:
|
||||
yield (opcode, None, sop_idx)
|
||||
else:
|
||||
datasize = None
|
||||
pushdata_type = None
|
||||
if opcode < OP_PUSHDATA1:
|
||||
pushdata_type = 'PUSHDATA(%d)' % opcode
|
||||
datasize = opcode
|
||||
|
||||
elif opcode == OP_PUSHDATA1:
|
||||
pushdata_type = 'PUSHDATA1'
|
||||
if i >= len(self):
|
||||
raise CScriptInvalidError('PUSHDATA1: missing data length')
|
||||
datasize = bord(self[i])
|
||||
i += 1
|
||||
|
||||
elif opcode == OP_PUSHDATA2:
|
||||
pushdata_type = 'PUSHDATA2'
|
||||
if i + 1 >= len(self):
|
||||
raise CScriptInvalidError('PUSHDATA2: missing data length')
|
||||
datasize = bord(self[i]) + (bord(self[i+1]) << 8)
|
||||
i += 2
|
||||
|
||||
elif opcode == OP_PUSHDATA4:
|
||||
pushdata_type = 'PUSHDATA4'
|
||||
if i + 3 >= len(self):
|
||||
raise CScriptInvalidError('PUSHDATA4: missing data length')
|
||||
datasize = bord(self[i]) + (bord(self[i+1]) << 8) + (bord(self[i+2]) << 16) + (bord(self[i+3]) << 24)
|
||||
i += 4
|
||||
|
||||
else:
|
||||
assert False # shouldn't happen
|
||||
|
||||
|
||||
data = bytes(self[i:i+datasize])
|
||||
|
||||
# Check for truncation
|
||||
if len(data) < datasize:
|
||||
raise CScriptTruncatedPushDataError('%s: truncated data' % pushdata_type, data)
|
||||
|
||||
i += datasize
|
||||
|
||||
yield (opcode, data, sop_idx)
|
||||
|
||||
def __iter__(self):
|
||||
"""'Cooked' iteration
|
||||
|
||||
Returns either a CScriptOP instance, an integer, or bytes, as
|
||||
appropriate.
|
||||
|
||||
See raw_iter() if you need to distinguish the different possible
|
||||
PUSHDATA encodings.
|
||||
"""
|
||||
for (opcode, data, sop_idx) in self.raw_iter():
|
||||
if data is not None:
|
||||
yield data
|
||||
else:
|
||||
opcode = CScriptOp(opcode)
|
||||
|
||||
if opcode.is_small_int():
|
||||
yield opcode.decode_op_n()
|
||||
else:
|
||||
yield CScriptOp(opcode)
|
||||
|
||||
def __repr__(self):
|
||||
# For Python3 compatibility add b before strings so testcases don't
|
||||
# need to change
|
||||
def _repr(o):
|
||||
if isinstance(o, bytes):
|
||||
return "x('%s')" % binascii.hexlify(o).decode('utf8')
|
||||
else:
|
||||
return repr(o)
|
||||
|
||||
ops = []
|
||||
i = iter(self)
|
||||
while True:
|
||||
op = None
|
||||
try:
|
||||
op = _repr(next(i))
|
||||
except CScriptTruncatedPushDataError as err:
|
||||
op = '%s...<ERROR: %s>' % (_repr(err.data), err)
|
||||
break
|
||||
except CScriptInvalidError as err:
|
||||
op = '<ERROR: %s>' % err
|
||||
break
|
||||
except StopIteration:
|
||||
break
|
||||
finally:
|
||||
if op is not None:
|
||||
ops.append(op)
|
||||
|
||||
return "CScript([%s])" % ', '.join(ops)
|
||||
|
||||
def GetSigOpCount(self, fAccurate):
|
||||
"""Get the SigOp count.
|
||||
|
||||
fAccurate - Accurately count CHECKMULTISIG, see BIP16 for details.
|
||||
|
||||
Note that this is consensus-critical.
|
||||
"""
|
||||
n = 0
|
||||
lastOpcode = OP_INVALIDOPCODE
|
||||
for (opcode, data, sop_idx) in self.raw_iter():
|
||||
if opcode in (OP_CHECKSIG, OP_CHECKSIGVERIFY):
|
||||
n += 1
|
||||
elif opcode in (OP_CHECKMULTISIG, OP_CHECKMULTISIGVERIFY):
|
||||
if fAccurate and (OP_1 <= lastOpcode <= OP_16):
|
||||
n += opcode.decode_op_n()
|
||||
else:
|
||||
n += 20
|
||||
lastOpcode = opcode
|
||||
return n
|
||||
|
||||
|
||||
SIGHASH_ALL = 1
|
||||
SIGHASH_NONE = 2
|
||||
SIGHASH_SINGLE = 3
|
||||
SIGHASH_ANYONECANPAY = 0x80
|
||||
|
||||
def FindAndDelete(script, sig):
|
||||
"""Consensus critical, see FindAndDelete() in Satoshi codebase"""
|
||||
r = b''
|
||||
last_sop_idx = sop_idx = 0
|
||||
skip = True
|
||||
for (opcode, data, sop_idx) in script.raw_iter():
|
||||
if not skip:
|
||||
r += script[last_sop_idx:sop_idx]
|
||||
last_sop_idx = sop_idx
|
||||
if script[sop_idx:sop_idx + len(sig)] == sig:
|
||||
skip = True
|
||||
else:
|
||||
skip = False
|
||||
if not skip:
|
||||
r += script[last_sop_idx:]
|
||||
return CScript(r)
|
||||
|
||||
|
||||
def SignatureHash(script, txTo, inIdx, hashtype):
|
||||
"""Consensus-correct SignatureHash
|
||||
|
||||
Returns (hash, err) to precisely match the consensus-critical behavior of
|
||||
the SIGHASH_SINGLE bug. (inIdx is *not* checked for validity)
|
||||
"""
|
||||
HASH_ONE = b'\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
|
||||
|
||||
if inIdx >= len(txTo.vin):
|
||||
return (HASH_ONE, "inIdx %d out of range (%d)" % (inIdx, len(txTo.vin)))
|
||||
txtmp = CTransaction(txTo)
|
||||
|
||||
for txin in txtmp.vin:
|
||||
txin.scriptSig = b''
|
||||
txtmp.vin[inIdx].scriptSig = FindAndDelete(script, CScript([OP_CODESEPARATOR]))
|
||||
|
||||
if (hashtype & 0x1f) == SIGHASH_NONE:
|
||||
txtmp.vout = []
|
||||
|
||||
for i in range(len(txtmp.vin)):
|
||||
if i != inIdx:
|
||||
txtmp.vin[i].nSequence = 0
|
||||
|
||||
elif (hashtype & 0x1f) == SIGHASH_SINGLE:
|
||||
outIdx = inIdx
|
||||
if outIdx >= len(txtmp.vout):
|
||||
return (HASH_ONE, "outIdx %d out of range (%d)" % (outIdx, len(txtmp.vout)))
|
||||
|
||||
tmp = txtmp.vout[outIdx]
|
||||
txtmp.vout = []
|
||||
for i in range(outIdx):
|
||||
txtmp.vout.append(CTxOut())
|
||||
txtmp.vout.append(tmp)
|
||||
|
||||
for i in range(len(txtmp.vin)):
|
||||
if i != inIdx:
|
||||
txtmp.vin[i].nSequence = 0
|
||||
|
||||
if hashtype & SIGHASH_ANYONECANPAY:
|
||||
tmp = txtmp.vin[inIdx]
|
||||
txtmp.vin = []
|
||||
txtmp.vin.append(tmp)
|
||||
|
||||
s = txtmp.serialize()
|
||||
s += struct.pack(b"<I", hashtype)
|
||||
|
||||
hash = hash256(s)
|
||||
|
||||
return (hash, None)
|
253
qa/rpc-tests/script_test.py
Executable file
253
qa/rpc-tests/script_test.py
Executable file
|
@ -0,0 +1,253 @@
|
|||
#!/usr/bin/env python2
|
||||
#
|
||||
# Distributed under the MIT/X11 software license, see the accompanying
|
||||
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
#
|
||||
|
||||
'''
|
||||
Test notes:
|
||||
This test uses the script_valid and script_invalid tests from the unittest
|
||||
framework to do end-to-end testing where we compare that two nodes agree on
|
||||
whether blocks containing a given test script are valid.
|
||||
|
||||
We generally ignore the script flags associated with each test (since we lack
|
||||
the precision to test each script using those flags in this framework), but
|
||||
for tests with SCRIPT_VERIFY_P2SH, we can use a block time after the BIP16
|
||||
switchover date to try to test with that flag enabled (and for tests without
|
||||
that flag, we use a block time before the switchover date).
|
||||
|
||||
NOTE: This test is very slow and may take more than 40 minutes to run.
|
||||
'''
|
||||
|
||||
from test_framework import ComparisonTestFramework
|
||||
from util import *
|
||||
from comptool import TestInstance, TestManager
|
||||
from mininode import *
|
||||
from blocktools import *
|
||||
from script import *
|
||||
import logging
|
||||
import copy
|
||||
import json
|
||||
|
||||
script_valid_file = "../../src/test/data/script_valid.json"
|
||||
script_invalid_file = "../../src/test/data/script_invalid.json"
|
||||
|
||||
# Pass in a set of json files to open.
|
||||
class ScriptTestFile(object):
|
||||
|
||||
def __init__(self, files):
|
||||
self.files = files
|
||||
self.index = -1
|
||||
self.data = []
|
||||
|
||||
def load_files(self):
|
||||
for f in self.files:
|
||||
self.data.extend(json.loads(open(f).read()))
|
||||
|
||||
# Skip over records that are not long enough to be tests
|
||||
def get_records(self):
|
||||
while (self.index < len(self.data)):
|
||||
if len(self.data[self.index]) >= 3:
|
||||
yield self.data[self.index]
|
||||
self.index += 1
|
||||
|
||||
|
||||
# Helper for parsing the flags specified in the .json files
|
||||
SCRIPT_VERIFY_NONE = 0
|
||||
SCRIPT_VERIFY_P2SH = 1
|
||||
SCRIPT_VERIFY_STRICTENC = 1 << 1
|
||||
SCRIPT_VERIFY_DERSIG = 1 << 2
|
||||
SCRIPT_VERIFY_LOW_S = 1 << 3
|
||||
SCRIPT_VERIFY_NULLDUMMY = 1 << 4
|
||||
SCRIPT_VERIFY_SIGPUSHONLY = 1 << 5
|
||||
SCRIPT_VERIFY_MINIMALDATA = 1 << 6
|
||||
SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_NOPS = 1 << 7
|
||||
SCRIPT_VERIFY_CLEANSTACK = 1 << 8
|
||||
|
||||
flag_map = {
|
||||
"": SCRIPT_VERIFY_NONE,
|
||||
"NONE": SCRIPT_VERIFY_NONE,
|
||||
"P2SH": SCRIPT_VERIFY_P2SH,
|
||||
"STRICTENC": SCRIPT_VERIFY_STRICTENC,
|
||||
"DERSIG": SCRIPT_VERIFY_DERSIG,
|
||||
"LOW_S": SCRIPT_VERIFY_LOW_S,
|
||||
"NULLDUMMY": SCRIPT_VERIFY_NULLDUMMY,
|
||||
"SIGPUSHONLY": SCRIPT_VERIFY_SIGPUSHONLY,
|
||||
"MINIMALDATA": SCRIPT_VERIFY_MINIMALDATA,
|
||||
"DISCOURAGE_UPGRADABLE_NOPS": SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_NOPS,
|
||||
"CLEANSTACK": SCRIPT_VERIFY_CLEANSTACK,
|
||||
}
|
||||
|
||||
def ParseScriptFlags(flag_string):
|
||||
flags = 0
|
||||
for x in flag_string.split(","):
|
||||
if x in flag_map:
|
||||
flags |= flag_map[x]
|
||||
else:
|
||||
print "Error: unrecognized script flag: ", x
|
||||
return flags
|
||||
|
||||
'''
|
||||
Given a string that is a scriptsig or scriptpubkey from the .json files above,
|
||||
convert it to a CScript()
|
||||
'''
|
||||
# Replicates behavior from core_read.cpp
|
||||
def ParseScript(json_script):
|
||||
script = json_script.split(" ")
|
||||
parsed_script = CScript()
|
||||
for x in script:
|
||||
if len(x) == 0:
|
||||
# Empty string, ignore.
|
||||
pass
|
||||
elif x.isdigit() or (len(x) >= 1 and x[0] == "-" and x[1:].isdigit()):
|
||||
# Number
|
||||
n = int(x, 0)
|
||||
if (n == -1) or (n >= 1 and n <= 16):
|
||||
parsed_script = CScript(bytes(parsed_script) + bytes(CScript([n])))
|
||||
else:
|
||||
parsed_script += CScriptNum(int(x, 0))
|
||||
elif x.startswith("0x"):
|
||||
# Raw hex data, inserted NOT pushed onto stack:
|
||||
for i in xrange(2, len(x), 2):
|
||||
parsed_script = CScript(bytes(parsed_script) + bytes(chr(int(x[i:i+2],16))))
|
||||
elif x.startswith("'") and x.endswith("'") and len(x) >= 2:
|
||||
# Single-quoted string, pushed as data.
|
||||
parsed_script += CScript([x[1:-1]])
|
||||
else:
|
||||
# opcode, e.g. OP_ADD or ADD:
|
||||
tryopname = "OP_" + x
|
||||
if tryopname in OPCODES_BY_NAME:
|
||||
parsed_script += CScriptOp(OPCODES_BY_NAME["OP_" + x])
|
||||
else:
|
||||
print "ParseScript: error parsing '%s'" % x
|
||||
return ""
|
||||
return parsed_script
|
||||
|
||||
class TestBuilder(object):
|
||||
def create_credit_tx(self, scriptPubKey):
|
||||
# self.tx1 is a coinbase transaction, modeled after the one created by script_tests.cpp
|
||||
# This allows us to reuse signatures created in the unit test framework.
|
||||
self.tx1 = create_coinbase() # this has a bip34 scriptsig,
|
||||
self.tx1.vin[0].scriptSig = CScript([0, 0]) # but this matches the unit tests
|
||||
self.tx1.vout[0].nValue = 0
|
||||
self.tx1.vout[0].scriptPubKey = scriptPubKey
|
||||
self.tx1.rehash()
|
||||
def create_spend_tx(self, scriptSig):
|
||||
self.tx2 = create_transaction(self.tx1, 0, CScript(), 0)
|
||||
self.tx2.vin[0].scriptSig = scriptSig
|
||||
self.tx2.vout[0].scriptPubKey = CScript()
|
||||
self.tx2.rehash()
|
||||
def rehash(self):
|
||||
self.tx1.rehash()
|
||||
self.tx2.rehash()
|
||||
|
||||
# This test uses the (default) two nodes provided by ComparisonTestFramework,
|
||||
# specified on the command line with --testbinary and --refbinary.
|
||||
# See comptool.py
|
||||
class ScriptTest(ComparisonTestFramework):
|
||||
|
||||
def run_test(self):
|
||||
# Set up the comparison tool TestManager
|
||||
test = TestManager(self, self.options.tmpdir)
|
||||
test.add_all_connections(self.nodes)
|
||||
|
||||
# Load scripts
|
||||
self.scripts = ScriptTestFile([script_valid_file, script_invalid_file])
|
||||
self.scripts.load_files()
|
||||
|
||||
# Some variables we re-use between test instances (to build blocks)
|
||||
self.tip = None
|
||||
self.block_time = None
|
||||
|
||||
NetworkThread().start() # Start up network handling in another thread
|
||||
test.run()
|
||||
|
||||
def generate_test_instance(self, pubkeystring, scriptsigstring):
|
||||
scriptpubkey = ParseScript(pubkeystring)
|
||||
scriptsig = ParseScript(scriptsigstring)
|
||||
|
||||
test = TestInstance(sync_every_block=False)
|
||||
test_build = TestBuilder()
|
||||
test_build.create_credit_tx(scriptpubkey)
|
||||
test_build.create_spend_tx(scriptsig)
|
||||
test_build.rehash()
|
||||
|
||||
block = create_block(self.tip, test_build.tx1, self.block_time)
|
||||
self.block_time += 1
|
||||
block.solve()
|
||||
self.tip = block.sha256
|
||||
test.blocks_and_transactions = [[block, True]]
|
||||
|
||||
for i in xrange(100):
|
||||
block = create_block(self.tip, create_coinbase(), self.block_time)
|
||||
self.block_time += 1
|
||||
block.solve()
|
||||
self.tip = block.sha256
|
||||
test.blocks_and_transactions.append([block, True])
|
||||
|
||||
block = create_block(self.tip, create_coinbase(), self.block_time)
|
||||
self.block_time += 1
|
||||
block.vtx.append(test_build.tx2)
|
||||
block.hashMerkleRoot = block.calc_merkle_root()
|
||||
block.rehash()
|
||||
block.solve()
|
||||
test.blocks_and_transactions.append([block, None])
|
||||
return test
|
||||
|
||||
# This generates the tests for TestManager.
|
||||
def get_tests(self):
|
||||
self.tip = int ("0x" + self.nodes[0].getbestblockhash() + "L", 0)
|
||||
self.block_time = 1333230000 # before the BIP16 switchover
|
||||
|
||||
'''
|
||||
Create a new block with an anyone-can-spend coinbase
|
||||
'''
|
||||
block = create_block(self.tip, create_coinbase(), self.block_time)
|
||||
self.block_time += 1
|
||||
block.solve()
|
||||
self.tip = block.sha256
|
||||
yield TestInstance(objects=[[block, True]])
|
||||
|
||||
'''
|
||||
Build out to 100 blocks total, maturing the coinbase.
|
||||
'''
|
||||
test = TestInstance(objects=[], sync_every_block=False, sync_every_tx=False)
|
||||
for i in xrange(100):
|
||||
b = create_block(self.tip, create_coinbase(), self.block_time)
|
||||
b.solve()
|
||||
test.blocks_and_transactions.append([b, True])
|
||||
self.tip = b.sha256
|
||||
self.block_time += 1
|
||||
yield test
|
||||
|
||||
''' Iterate through script tests. '''
|
||||
counter = 0
|
||||
for script_test in self.scripts.get_records():
|
||||
''' Reset the blockchain to genesis block + 100 blocks. '''
|
||||
if self.nodes[0].getblockcount() > 101:
|
||||
self.nodes[0].invalidateblock(self.nodes[0].getblockhash(102))
|
||||
self.nodes[1].invalidateblock(self.nodes[1].getblockhash(102))
|
||||
|
||||
self.tip = int ("0x" + self.nodes[0].getbestblockhash() + "L", 0)
|
||||
|
||||
[scriptsig, scriptpubkey, flags] = script_test[0:3]
|
||||
flags = ParseScriptFlags(flags)
|
||||
|
||||
# We can use block time to determine whether the nodes should be
|
||||
# enforcing BIP16.
|
||||
#
|
||||
# We intentionally let the block time grow by 1 each time.
|
||||
# This forces the block hashes to differ between tests, so that
|
||||
# a call to invalidateblock doesn't interfere with a later test.
|
||||
if (flags & SCRIPT_VERIFY_P2SH):
|
||||
self.block_time = 1333238400 + counter # Advance to enforcing BIP16
|
||||
else:
|
||||
self.block_time = 1333230000 + counter # Before the BIP16 switchover
|
||||
|
||||
print "Script test: [%s]" % script_test
|
||||
|
||||
yield self.generate_test_instance(scriptpubkey, scriptsig)
|
||||
counter += 1
|
||||
|
||||
if __name__ == '__main__':
|
||||
ScriptTest().main()
|
|
@ -51,7 +51,7 @@ class EstimateFeeTest(BitcoinTestFramework):
|
|||
# Mine blocks with node2 until the memory pool clears:
|
||||
count_start = self.nodes[2].getblockcount()
|
||||
while len(self.nodes[2].getrawmempool()) > 0:
|
||||
self.nodes[2].setgenerate(True, 1)
|
||||
self.nodes[2].generate(1)
|
||||
self.sync_all()
|
||||
|
||||
all_estimates = [ self.nodes[0].estimatefee(i) for i in range(1,20) ]
|
||||
|
@ -70,7 +70,7 @@ class EstimateFeeTest(BitcoinTestFramework):
|
|||
Decimal("0.0"), min_fee, 20)
|
||||
tx_kbytes = (len(txhex)/2)/1000.0
|
||||
fees_per_kb.append(float(fee)/tx_kbytes)
|
||||
self.nodes[1].setgenerate(True, 1)
|
||||
self.nodes[1].generate(1)
|
||||
self.sync_all()
|
||||
|
||||
all_estimates = [ self.nodes[0].estimatefee(i) for i in range(1,20) ]
|
||||
|
@ -81,7 +81,7 @@ class EstimateFeeTest(BitcoinTestFramework):
|
|||
|
||||
# Finish by mining a normal-sized block:
|
||||
while len(self.nodes[0].getrawmempool()) > 0:
|
||||
self.nodes[0].setgenerate(True, 1)
|
||||
self.nodes[0].generate(1)
|
||||
self.sync_all()
|
||||
|
||||
final_estimates = [ self.nodes[0].estimatefee(i) for i in range(1,20) ]
|
||||
|
|
160
qa/rpc-tests/socks5.py
Normal file
160
qa/rpc-tests/socks5.py
Normal file
|
@ -0,0 +1,160 @@
|
|||
# Copyright (c) 2015 The Bitcoin Core developers
|
||||
# Distributed under the MIT software license, see the accompanying
|
||||
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
'''
|
||||
Dummy Socks5 server for testing.
|
||||
'''
|
||||
from __future__ import print_function, division, unicode_literals
|
||||
import socket, threading, Queue
|
||||
import traceback, sys
|
||||
|
||||
### Protocol constants
|
||||
class Command:
|
||||
CONNECT = 0x01
|
||||
|
||||
class AddressType:
|
||||
IPV4 = 0x01
|
||||
DOMAINNAME = 0x03
|
||||
IPV6 = 0x04
|
||||
|
||||
### Utility functions
|
||||
def recvall(s, n):
|
||||
'''Receive n bytes from a socket, or fail'''
|
||||
rv = bytearray()
|
||||
while n > 0:
|
||||
d = s.recv(n)
|
||||
if not d:
|
||||
raise IOError('Unexpected end of stream')
|
||||
rv.extend(d)
|
||||
n -= len(d)
|
||||
return rv
|
||||
|
||||
### Implementation classes
|
||||
class Socks5Configuration(object):
|
||||
'''Proxy configuration'''
|
||||
def __init__(self):
|
||||
self.addr = None # Bind address (must be set)
|
||||
self.af = socket.AF_INET # Bind address family
|
||||
self.unauth = False # Support unauthenticated
|
||||
self.auth = False # Support authentication
|
||||
|
||||
class Socks5Command(object):
|
||||
'''Information about an incoming socks5 command'''
|
||||
def __init__(self, cmd, atyp, addr, port, username, password):
|
||||
self.cmd = cmd # Command (one of Command.*)
|
||||
self.atyp = atyp # Address type (one of AddressType.*)
|
||||
self.addr = addr # Address
|
||||
self.port = port # Port to connect to
|
||||
self.username = username
|
||||
self.password = password
|
||||
def __repr__(self):
|
||||
return 'Socks5Command(%s,%s,%s,%s,%s,%s)' % (self.cmd, self.atyp, self.addr, self.port, self.username, self.password)
|
||||
|
||||
class Socks5Connection(object):
|
||||
def __init__(self, serv, conn, peer):
|
||||
self.serv = serv
|
||||
self.conn = conn
|
||||
self.peer = peer
|
||||
|
||||
def handle(self):
|
||||
'''
|
||||
Handle socks5 request according to RFC1928
|
||||
'''
|
||||
try:
|
||||
# Verify socks version
|
||||
ver = recvall(self.conn, 1)[0]
|
||||
if ver != 0x05:
|
||||
raise IOError('Invalid socks version %i' % ver)
|
||||
# Choose authentication method
|
||||
nmethods = recvall(self.conn, 1)[0]
|
||||
methods = bytearray(recvall(self.conn, nmethods))
|
||||
method = None
|
||||
if 0x02 in methods and self.serv.conf.auth:
|
||||
method = 0x02 # username/password
|
||||
elif 0x00 in methods and self.serv.conf.unauth:
|
||||
method = 0x00 # unauthenticated
|
||||
if method is None:
|
||||
raise IOError('No supported authentication method was offered')
|
||||
# Send response
|
||||
self.conn.sendall(bytearray([0x05, method]))
|
||||
# Read authentication (optional)
|
||||
username = None
|
||||
password = None
|
||||
if method == 0x02:
|
||||
ver = recvall(self.conn, 1)[0]
|
||||
if ver != 0x01:
|
||||
raise IOError('Invalid auth packet version %i' % ver)
|
||||
ulen = recvall(self.conn, 1)[0]
|
||||
username = str(recvall(self.conn, ulen))
|
||||
plen = recvall(self.conn, 1)[0]
|
||||
password = str(recvall(self.conn, plen))
|
||||
# Send authentication response
|
||||
self.conn.sendall(bytearray([0x01, 0x00]))
|
||||
|
||||
# Read connect request
|
||||
(ver,cmd,rsv,atyp) = recvall(self.conn, 4)
|
||||
if ver != 0x05:
|
||||
raise IOError('Invalid socks version %i in connect request' % ver)
|
||||
if cmd != Command.CONNECT:
|
||||
raise IOError('Unhandled command %i in connect request' % cmd)
|
||||
|
||||
if atyp == AddressType.IPV4:
|
||||
addr = recvall(self.conn, 4)
|
||||
elif atyp == AddressType.DOMAINNAME:
|
||||
n = recvall(self.conn, 1)[0]
|
||||
addr = str(recvall(self.conn, n))
|
||||
elif atyp == AddressType.IPV6:
|
||||
addr = recvall(self.conn, 16)
|
||||
else:
|
||||
raise IOError('Unknown address type %i' % atyp)
|
||||
port_hi,port_lo = recvall(self.conn, 2)
|
||||
port = (port_hi << 8) | port_lo
|
||||
|
||||
# Send dummy response
|
||||
self.conn.sendall(bytearray([0x05, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]))
|
||||
|
||||
cmdin = Socks5Command(cmd, atyp, addr, port, username, password)
|
||||
self.serv.queue.put(cmdin)
|
||||
print('Proxy: ', cmdin)
|
||||
# Fall through to disconnect
|
||||
except Exception,e:
|
||||
traceback.print_exc(file=sys.stderr)
|
||||
self.serv.queue.put(e)
|
||||
finally:
|
||||
self.conn.close()
|
||||
|
||||
class Socks5Server(object):
|
||||
def __init__(self, conf):
|
||||
self.conf = conf
|
||||
self.s = socket.socket(conf.af)
|
||||
self.s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
|
||||
self.s.bind(conf.addr)
|
||||
self.s.listen(5)
|
||||
self.running = False
|
||||
self.thread = None
|
||||
self.queue = Queue.Queue() # report connections and exceptions to client
|
||||
|
||||
def run(self):
|
||||
while self.running:
|
||||
(sockconn, peer) = self.s.accept()
|
||||
if self.running:
|
||||
conn = Socks5Connection(self, sockconn, peer)
|
||||
thread = threading.Thread(None, conn.handle)
|
||||
thread.daemon = True
|
||||
thread.start()
|
||||
|
||||
def start(self):
|
||||
assert(not self.running)
|
||||
self.running = True
|
||||
self.thread = threading.Thread(None, self.run)
|
||||
self.thread.daemon = True
|
||||
self.thread.start()
|
||||
|
||||
def stop(self):
|
||||
self.running = False
|
||||
# connect to self to end run loop
|
||||
s = socket.socket(self.conf.af)
|
||||
s.connect(self.conf.addr)
|
||||
s.close()
|
||||
self.thread.join()
|
||||
|
|
@ -89,8 +89,10 @@ class BitcoinTestFramework(object):
|
|||
parser = optparse.OptionParser(usage="%prog [options]")
|
||||
parser.add_option("--nocleanup", dest="nocleanup", default=False, action="store_true",
|
||||
help="Leave bitcoinds and test.* datadir on exit or error")
|
||||
parser.add_option("--noshutdown", dest="noshutdown", default=False, action="store_true",
|
||||
help="Don't stop bitcoinds after the test execution")
|
||||
parser.add_option("--srcdir", dest="srcdir", default="../../src",
|
||||
help="Source directory containing bitcoind/bitcoin-cli (default: %default%)")
|
||||
help="Source directory containing bitcoind/bitcoin-cli (default: %default)")
|
||||
parser.add_option("--tmpdir", dest="tmpdir", default=tempfile.mkdtemp(prefix="test"),
|
||||
help="Root directory for datadirs")
|
||||
parser.add_option("--tracerpc", dest="trace_rpc", default=False, action="store_true",
|
||||
|
@ -128,10 +130,15 @@ class BitcoinTestFramework(object):
|
|||
print("Unexpected exception caught during testing: "+str(e))
|
||||
traceback.print_tb(sys.exc_info()[2])
|
||||
|
||||
if not self.options.nocleanup:
|
||||
print("Cleaning up")
|
||||
if not self.options.noshutdown:
|
||||
print("Stopping nodes")
|
||||
stop_nodes(self.nodes)
|
||||
wait_bitcoinds()
|
||||
else:
|
||||
print("Note: bitcoinds were not stopped and may still be running")
|
||||
|
||||
if not self.options.nocleanup and not self.options.noshutdown:
|
||||
print("Cleaning up")
|
||||
shutil.rmtree(self.options.tmpdir)
|
||||
|
||||
if success:
|
||||
|
@ -140,3 +147,34 @@ class BitcoinTestFramework(object):
|
|||
else:
|
||||
print("Failed")
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
# Test framework for doing p2p comparison testing, which sets up some bitcoind
|
||||
# binaries:
|
||||
# 1 binary: test binary
|
||||
# 2 binaries: 1 test binary, 1 ref binary
|
||||
# n>2 binaries: 1 test binary, n-1 ref binaries
|
||||
|
||||
class ComparisonTestFramework(BitcoinTestFramework):
|
||||
|
||||
# Can override the num_nodes variable to indicate how many nodes to run.
|
||||
def __init__(self):
|
||||
self.num_nodes = 2
|
||||
|
||||
def add_options(self, parser):
|
||||
parser.add_option("--testbinary", dest="testbinary",
|
||||
default=os.getenv("BITCOIND", "bitcoind"),
|
||||
help="bitcoind binary to test")
|
||||
parser.add_option("--refbinary", dest="refbinary",
|
||||
default=os.getenv("BITCOIND", "bitcoind"),
|
||||
help="bitcoind binary to use for reference nodes (if any)")
|
||||
|
||||
def setup_chain(self):
|
||||
print "Initializing test directory "+self.options.tmpdir
|
||||
initialize_chain_clean(self.options.tmpdir, self.num_nodes)
|
||||
|
||||
def setup_network(self):
|
||||
self.nodes = start_nodes(self.num_nodes, self.options.tmpdir,
|
||||
extra_args=[['-debug', '-whitelist=127.0.0.1']] * self.num_nodes,
|
||||
binary=[self.options.testbinary] +
|
||||
[self.options.refbinary]*(self.num_nodes-1))
|
||||
|
|
|
@ -58,7 +58,7 @@ class TxnMallTest(BitcoinTestFramework):
|
|||
|
||||
# Have node0 mine a block:
|
||||
if (self.options.mine_block):
|
||||
self.nodes[0].setgenerate(True, 1)
|
||||
self.nodes[0].generate(1)
|
||||
sync_blocks(self.nodes[0:2])
|
||||
|
||||
tx1 = self.nodes[0].gettransaction(txid1)
|
||||
|
@ -88,11 +88,11 @@ class TxnMallTest(BitcoinTestFramework):
|
|||
# Now give doublespend to miner:
|
||||
mutated_txid = self.nodes[2].sendrawtransaction(doublespend["hex"])
|
||||
# ... mine a block...
|
||||
self.nodes[2].setgenerate(True, 1)
|
||||
self.nodes[2].generate(1)
|
||||
|
||||
# Reconnect the split network, and sync chain:
|
||||
connect_nodes(self.nodes[1], 2)
|
||||
self.nodes[2].setgenerate(True, 1) # Mine another block to make sure we sync
|
||||
self.nodes[2].generate(1) # Mine another block to make sure we sync
|
||||
sync_blocks(self.nodes)
|
||||
|
||||
# Re-fetch transaction info:
|
||||
|
|
|
@ -88,8 +88,12 @@ def initialize_chain(test_dir):
|
|||
if i > 0:
|
||||
args.append("-connect=127.0.0.1:"+str(p2p_port(0)))
|
||||
bitcoind_processes[i] = subprocess.Popen(args)
|
||||
if os.getenv("PYTHON_DEBUG", ""):
|
||||
print "initialize_chain: bitcoind started, calling bitcoin-cli -rpcwait getblockcount"
|
||||
subprocess.check_call([ os.getenv("BITCOINCLI", "bitcoin-cli"), "-datadir="+datadir,
|
||||
"-rpcwait", "getblockcount"], stdout=devnull)
|
||||
if os.getenv("PYTHON_DEBUG", ""):
|
||||
print "initialize_chain: bitcoin-cli -rpcwait getblockcount completed"
|
||||
devnull.close()
|
||||
rpcs = []
|
||||
for i in range(4):
|
||||
|
@ -109,7 +113,7 @@ def initialize_chain(test_dir):
|
|||
for peer in range(4):
|
||||
for j in range(25):
|
||||
set_node_times(rpcs, block_time)
|
||||
rpcs[peer].setgenerate(True, 1)
|
||||
rpcs[peer].generate(1)
|
||||
block_time += 10*60
|
||||
# Must sync before next peer starts generating blocks
|
||||
sync_blocks(rpcs)
|
||||
|
@ -158,30 +162,40 @@ def _rpchost_to_args(rpchost):
|
|||
rv += ['-rpcport=' + rpcport]
|
||||
return rv
|
||||
|
||||
def start_node(i, dirname, extra_args=None, rpchost=None):
|
||||
def start_node(i, dirname, extra_args=None, rpchost=None, timewait=None, binary=None):
|
||||
"""
|
||||
Start a bitcoind and return RPC connection to it
|
||||
"""
|
||||
datadir = os.path.join(dirname, "node"+str(i))
|
||||
args = [ os.getenv("BITCOIND", "bitcoind"), "-datadir="+datadir, "-keypool=1", "-discover=0", "-rest" ]
|
||||
if binary is None:
|
||||
binary = os.getenv("BITCOIND", "bitcoind")
|
||||
args = [ binary, "-datadir="+datadir, "-keypool=1", "-discover=0", "-rest" ]
|
||||
if extra_args is not None: args.extend(extra_args)
|
||||
bitcoind_processes[i] = subprocess.Popen(args)
|
||||
devnull = open("/dev/null", "w+")
|
||||
if os.getenv("PYTHON_DEBUG", ""):
|
||||
print "start_node: bitcoind started, calling bitcoin-cli -rpcwait getblockcount"
|
||||
subprocess.check_call([ os.getenv("BITCOINCLI", "bitcoin-cli"), "-datadir="+datadir] +
|
||||
_rpchost_to_args(rpchost) +
|
||||
["-rpcwait", "getblockcount"], stdout=devnull)
|
||||
if os.getenv("PYTHON_DEBUG", ""):
|
||||
print "start_node: calling bitcoin-cli -rpcwait getblockcount returned"
|
||||
devnull.close()
|
||||
url = "http://rt:rt@%s:%d" % (rpchost or '127.0.0.1', rpc_port(i))
|
||||
proxy = AuthServiceProxy(url)
|
||||
if timewait is not None:
|
||||
proxy = AuthServiceProxy(url, timeout=timewait)
|
||||
else:
|
||||
proxy = AuthServiceProxy(url)
|
||||
proxy.url = url # store URL on proxy for info
|
||||
return proxy
|
||||
|
||||
def start_nodes(num_nodes, dirname, extra_args=None, rpchost=None):
|
||||
def start_nodes(num_nodes, dirname, extra_args=None, rpchost=None, binary=None):
|
||||
"""
|
||||
Start multiple bitcoinds, return RPC connections to them
|
||||
"""
|
||||
if extra_args is None: extra_args = [ None for i in range(num_nodes) ]
|
||||
return [ start_node(i, dirname, extra_args[i], rpchost) for i in range(num_nodes) ]
|
||||
if binary is None: binary = [ None for i in range(num_nodes) ]
|
||||
return [ start_node(i, dirname, extra_args[i], rpchost, binary=binary[i]) for i in range(num_nodes) ]
|
||||
|
||||
def log_filename(dirname, n_node, logname):
|
||||
return os.path.join(dirname, "node"+str(n_node), "regtest", logname)
|
||||
|
|
|
@ -40,14 +40,14 @@ class WalletTest (BitcoinTestFramework):
|
|||
def run_test (self):
|
||||
print "Mining blocks..."
|
||||
|
||||
self.nodes[0].setgenerate(True, 1)
|
||||
self.nodes[0].generate(1)
|
||||
|
||||
walletinfo = self.nodes[0].getwalletinfo()
|
||||
assert_equal(walletinfo['immature_balance'], 50)
|
||||
assert_equal(walletinfo['balance'], 0)
|
||||
|
||||
self.sync_all()
|
||||
self.nodes[1].setgenerate(True, 101)
|
||||
self.nodes[1].generate(101)
|
||||
self.sync_all()
|
||||
|
||||
assert_equal(self.nodes[0].getbalance(), 50)
|
||||
|
@ -63,11 +63,11 @@ class WalletTest (BitcoinTestFramework):
|
|||
assert_equal(walletinfo['immature_balance'], 0)
|
||||
|
||||
# Have node0 mine a block, thus they will collect their own fee.
|
||||
self.nodes[0].setgenerate(True, 1)
|
||||
self.nodes[0].generate(1)
|
||||
self.sync_all()
|
||||
|
||||
# Have node1 generate 100 blocks (so node0 can recover the fee)
|
||||
self.nodes[1].setgenerate(True, 100)
|
||||
self.nodes[1].generate(100)
|
||||
self.sync_all()
|
||||
|
||||
# node0 should end up with 100 btc in block rewards plus fees, but
|
||||
|
@ -96,7 +96,7 @@ class WalletTest (BitcoinTestFramework):
|
|||
self.nodes[1].sendrawtransaction(txns_to_send[1]["hex"], True)
|
||||
|
||||
# Have node1 mine a block to confirm transactions:
|
||||
self.nodes[1].setgenerate(True, 1)
|
||||
self.nodes[1].generate(1)
|
||||
self.sync_all()
|
||||
|
||||
assert_equal(self.nodes[0].getbalance(), 0)
|
||||
|
@ -107,28 +107,28 @@ class WalletTest (BitcoinTestFramework):
|
|||
address = self.nodes[0].getnewaddress("test")
|
||||
self.nodes[2].settxfee(Decimal('0.001'))
|
||||
txid = self.nodes[2].sendtoaddress(address, 10, "", "", False)
|
||||
self.nodes[2].setgenerate(True, 1)
|
||||
self.nodes[2].generate(1)
|
||||
self.sync_all()
|
||||
assert_equal(self.nodes[2].getbalance(), Decimal('89.99900000'))
|
||||
assert_equal(self.nodes[0].getbalance(), Decimal('10.00000000'))
|
||||
|
||||
# Send 10 BTC with subtract fee from amount
|
||||
txid = self.nodes[2].sendtoaddress(address, 10, "", "", True)
|
||||
self.nodes[2].setgenerate(True, 1)
|
||||
self.nodes[2].generate(1)
|
||||
self.sync_all()
|
||||
assert_equal(self.nodes[2].getbalance(), Decimal('79.99900000'))
|
||||
assert_equal(self.nodes[0].getbalance(), Decimal('19.99900000'))
|
||||
|
||||
# Sendmany 10 BTC
|
||||
txid = self.nodes[2].sendmany('from1', {address: 10}, 0, "", [])
|
||||
self.nodes[2].setgenerate(True, 1)
|
||||
self.nodes[2].generate(1)
|
||||
self.sync_all()
|
||||
assert_equal(self.nodes[2].getbalance(), Decimal('69.99800000'))
|
||||
assert_equal(self.nodes[0].getbalance(), Decimal('29.99900000'))
|
||||
|
||||
# Sendmany 10 BTC with subtract fee from amount
|
||||
txid = self.nodes[2].sendmany('from1', {address: 10}, 0, "", [address])
|
||||
self.nodes[2].setgenerate(True, 1)
|
||||
self.nodes[2].generate(1)
|
||||
self.sync_all()
|
||||
assert_equal(self.nodes[2].getbalance(), Decimal('59.99800000'))
|
||||
assert_equal(self.nodes[0].getbalance(), Decimal('39.99800000'))
|
||||
|
@ -151,6 +151,33 @@ class WalletTest (BitcoinTestFramework):
|
|||
|
||||
assert(txid1 in self.nodes[3].getrawmempool())
|
||||
|
||||
#check if we can list zero value tx as available coins
|
||||
#1. create rawtx
|
||||
#2. hex-changed one output to 0.0
|
||||
#3. sign and send
|
||||
#4. check if recipient (node0) can list the zero value tx
|
||||
usp = self.nodes[1].listunspent()
|
||||
inputs = [{"txid":usp[0]['txid'], "vout":usp[0]['vout']}]
|
||||
outputs = {self.nodes[1].getnewaddress(): 49.998, self.nodes[0].getnewaddress(): 11.11}
|
||||
|
||||
rawTx = self.nodes[1].createrawtransaction(inputs, outputs).replace("c0833842", "00000000") #replace 11.11 with 0.0 (int32)
|
||||
decRawTx = self.nodes[1].decoderawtransaction(rawTx)
|
||||
signedRawTx = self.nodes[1].signrawtransaction(rawTx)
|
||||
decRawTx = self.nodes[1].decoderawtransaction(signedRawTx['hex'])
|
||||
zeroValueTxid= decRawTx['txid']
|
||||
sendResp = self.nodes[1].sendrawtransaction(signedRawTx['hex'])
|
||||
|
||||
self.sync_all()
|
||||
self.nodes[1].generate(1) #mine a block
|
||||
self.sync_all()
|
||||
|
||||
unspentTxs = self.nodes[0].listunspent() #zero value tx must be in listunspents output
|
||||
found = False
|
||||
for uTx in unspentTxs:
|
||||
if uTx['txid'] == zeroValueTxid:
|
||||
found = True
|
||||
assert_equal(uTx['amount'], Decimal('0.00000000'));
|
||||
assert(found)
|
||||
|
||||
#do some -walletbroadcast tests
|
||||
stop_nodes(self.nodes)
|
||||
|
@ -163,13 +190,13 @@ class WalletTest (BitcoinTestFramework):
|
|||
|
||||
txIdNotBroadcasted = self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(), 2);
|
||||
txObjNotBroadcasted = self.nodes[0].gettransaction(txIdNotBroadcasted)
|
||||
self.nodes[1].setgenerate(True, 1) #mine a block, tx should not be in there
|
||||
self.nodes[1].generate(1) #mine a block, tx should not be in there
|
||||
self.sync_all()
|
||||
assert_equal(self.nodes[2].getbalance(), Decimal('59.99800000')); #should not be changed because tx was not broadcasted
|
||||
|
||||
#now broadcast from another node, mine a block, sync, and check the balance
|
||||
self.nodes[1].sendrawtransaction(txObjNotBroadcasted['hex'])
|
||||
self.nodes[1].setgenerate(True, 1)
|
||||
self.nodes[1].generate(1)
|
||||
self.sync_all()
|
||||
txObjNotBroadcasted = self.nodes[0].gettransaction(txIdNotBroadcasted)
|
||||
assert_equal(self.nodes[2].getbalance(), Decimal('61.99800000')); #should not be
|
||||
|
@ -186,7 +213,7 @@ class WalletTest (BitcoinTestFramework):
|
|||
connect_nodes_bi(self.nodes,0,2)
|
||||
sync_blocks(self.nodes)
|
||||
|
||||
self.nodes[0].setgenerate(True, 1)
|
||||
self.nodes[0].generate(1)
|
||||
sync_blocks(self.nodes)
|
||||
|
||||
#tx should be added to balance because after restarting the nodes tx should be broadcastet
|
||||
|
|
|
@ -77,7 +77,7 @@ class WalletBackupTest(BitcoinTestFramework):
|
|||
# Have the miner (node3) mine a block.
|
||||
# Must sync mempools before mining.
|
||||
sync_mempools(self.nodes)
|
||||
self.nodes[3].setgenerate(True, 1)
|
||||
self.nodes[3].generate(1)
|
||||
|
||||
# As above, this mirrors the original bash test.
|
||||
def start_three(self):
|
||||
|
@ -101,13 +101,13 @@ class WalletBackupTest(BitcoinTestFramework):
|
|||
|
||||
def run_test(self):
|
||||
logging.info("Generating initial blockchain")
|
||||
self.nodes[0].setgenerate(True, 1)
|
||||
self.nodes[0].generate(1)
|
||||
sync_blocks(self.nodes)
|
||||
self.nodes[1].setgenerate(True, 1)
|
||||
self.nodes[1].generate(1)
|
||||
sync_blocks(self.nodes)
|
||||
self.nodes[2].setgenerate(True, 1)
|
||||
self.nodes[2].generate(1)
|
||||
sync_blocks(self.nodes)
|
||||
self.nodes[3].setgenerate(True, 100)
|
||||
self.nodes[3].generate(100)
|
||||
sync_blocks(self.nodes)
|
||||
|
||||
assert_equal(self.nodes[0].getbalance(), 50)
|
||||
|
@ -134,7 +134,7 @@ class WalletBackupTest(BitcoinTestFramework):
|
|||
self.do_one_round()
|
||||
|
||||
# Generate 101 more blocks, so any fees paid mature
|
||||
self.nodes[3].setgenerate(True, 101)
|
||||
self.nodes[3].generate(101)
|
||||
self.sync_all()
|
||||
|
||||
balance0 = self.nodes[0].getbalance()
|
||||
|
|
|
@ -23,9 +23,9 @@ class ZapWalletTXesTest (BitcoinTestFramework):
|
|||
|
||||
def run_test (self):
|
||||
print "Mining blocks..."
|
||||
self.nodes[0].setgenerate(True, 1)
|
||||
self.nodes[0].generate(1)
|
||||
self.sync_all()
|
||||
self.nodes[1].setgenerate(True, 101)
|
||||
self.nodes[1].generate(101)
|
||||
self.sync_all()
|
||||
|
||||
assert_equal(self.nodes[0].getbalance(), 50)
|
||||
|
@ -33,7 +33,7 @@ class ZapWalletTXesTest (BitcoinTestFramework):
|
|||
txid0 = self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(), 11)
|
||||
txid1 = self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(), 10)
|
||||
self.sync_all()
|
||||
self.nodes[0].setgenerate(True, 1)
|
||||
self.nodes[0].generate(1)
|
||||
self.sync_all()
|
||||
|
||||
txid2 = self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(), 11)
|
||||
|
|
|
@ -87,6 +87,7 @@ BITCOIN_CORE_H = \
|
|||
coins.h \
|
||||
compat.h \
|
||||
compressor.h \
|
||||
consensus/consensus.h \
|
||||
consensus/params.h \
|
||||
core_io.h \
|
||||
wallet/db.h \
|
||||
|
|
|
@ -39,6 +39,7 @@ BITCOIN_TESTS =\
|
|||
test/base32_tests.cpp \
|
||||
test/base58_tests.cpp \
|
||||
test/base64_tests.cpp \
|
||||
test/bip32_tests.cpp \
|
||||
test/bloom_tests.cpp \
|
||||
test/checkblock_tests.cpp \
|
||||
test/Checkpoints_tests.cpp \
|
||||
|
|
|
@ -67,9 +67,8 @@ double CAddrInfo::GetChance(int64_t nNow) const
|
|||
if (nSinceLastTry < 60 * 10)
|
||||
fChance *= 0.01;
|
||||
|
||||
// deprioritize 50% after each failed attempt
|
||||
for (int n = 0; n < nAttempts; n++)
|
||||
fChance /= 1.5;
|
||||
// deprioritize 66% after each failed attempt, but at most 1/28th to avoid the search taking forever or overly penalizing outages.
|
||||
fChance *= pow(0.66, min(nAttempts, 8));
|
||||
|
||||
return fChance;
|
||||
}
|
||||
|
@ -332,10 +331,10 @@ void CAddrMan::Attempt_(const CService& addr, int64_t nTime)
|
|||
info.nAttempts++;
|
||||
}
|
||||
|
||||
CAddress CAddrMan::Select_()
|
||||
CAddrInfo CAddrMan::Select_()
|
||||
{
|
||||
if (size() == 0)
|
||||
return CAddress();
|
||||
return CAddrInfo();
|
||||
|
||||
// Use a 50% chance for choosing between tried and new table entries.
|
||||
if (nTried > 0 && (nNew == 0 || GetRandInt(2) == 0)) {
|
||||
|
|
|
@ -22,6 +22,10 @@
|
|||
*/
|
||||
class CAddrInfo : public CAddress
|
||||
{
|
||||
public:
|
||||
//! last try whatsoever by us (memory only)
|
||||
int64_t nLastTry;
|
||||
|
||||
private:
|
||||
//! where knowledge about this address first came from
|
||||
CNetAddr source;
|
||||
|
@ -29,9 +33,6 @@ private:
|
|||
//! last successful connection by us
|
||||
int64_t nLastSuccess;
|
||||
|
||||
//! last try whatsoever by us:
|
||||
// int64_t CAddress::nLastTry
|
||||
|
||||
//! connection attempts since last successful attempt
|
||||
int nAttempts;
|
||||
|
||||
|
@ -231,7 +232,7 @@ protected:
|
|||
|
||||
//! Select an address to connect to.
|
||||
//! nUnkBias determines how much to favor new addresses over tried ones (min=0, max=100)
|
||||
CAddress Select_();
|
||||
CAddrInfo Select_();
|
||||
|
||||
#ifdef DEBUG_ADDRMAN
|
||||
//! Perform consistency check. Returns an error code or zero.
|
||||
|
@ -533,9 +534,9 @@ public:
|
|||
* Choose an address to connect to.
|
||||
* nUnkBias determines how much "new" entries are favored over "tried" ones (0-100).
|
||||
*/
|
||||
CAddress Select()
|
||||
CAddrInfo Select()
|
||||
{
|
||||
CAddress addrRet;
|
||||
CAddrInfo addrRet;
|
||||
{
|
||||
LOCK(cs);
|
||||
Check();
|
||||
|
|
|
@ -287,4 +287,4 @@ public:
|
|||
uint256 ArithToUint256(const arith_uint256 &);
|
||||
arith_uint256 UintToArith256(const uint256 &);
|
||||
|
||||
#endif // BITCOIN_UINT256_H
|
||||
#endif // BITCOIN_ARITH_UINT256_H
|
||||
|
|
|
@ -12,8 +12,6 @@
|
|||
|
||||
#include <boost/filesystem/operations.hpp>
|
||||
|
||||
#define _(x) std::string(x) /* Keep the _() around in case gettext or such will be used later to translate non-UI */
|
||||
|
||||
using namespace std;
|
||||
using namespace json_spirit;
|
||||
|
||||
|
|
|
@ -4,18 +4,17 @@
|
|||
|
||||
#include "base58.h"
|
||||
#include "clientversion.h"
|
||||
#include "primitives/block.h" // for MAX_BLOCK_SIZE
|
||||
#include "primitives/transaction.h"
|
||||
#include "core_io.h"
|
||||
#include "coins.h"
|
||||
#include "consensus/consensus.h"
|
||||
#include "core_io.h"
|
||||
#include "keystore.h"
|
||||
#include "primitives/transaction.h"
|
||||
#include "script/script.h"
|
||||
#include "script/sign.h"
|
||||
#include "ui_interface.h" // for _(...)
|
||||
#include "univalue/univalue.h"
|
||||
#include "util.h"
|
||||
#include "utilstrencodings.h"
|
||||
#include "utilmoneystr.h"
|
||||
#include "utilstrencodings.h"
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
|
@ -26,7 +25,6 @@ using namespace std;
|
|||
|
||||
static bool fCreateBlank;
|
||||
static map<string,UniValue> registers;
|
||||
CClientUIInterface uiInterface;
|
||||
|
||||
static bool AppInitRawTx(int argc, char* argv[])
|
||||
{
|
||||
|
|
|
@ -8,7 +8,6 @@
|
|||
#include "init.h"
|
||||
#include "main.h"
|
||||
#include "noui.h"
|
||||
#include "ui_interface.h"
|
||||
#include "util.h"
|
||||
|
||||
#include <boost/algorithm/string/predicate.hpp>
|
||||
|
@ -21,7 +20,7 @@
|
|||
*
|
||||
* \section intro_sec Introduction
|
||||
*
|
||||
* This is the developer documentation of the reference client for an experimental new digital currency called Bitcoin (http://www.bitcoin.org/),
|
||||
* This is the developer documentation of the reference client for an experimental new digital currency called Bitcoin (https://www.bitcoin.org/),
|
||||
* which enables instant payments to anyone, anywhere in the world. Bitcoin uses peer-to-peer technology to operate
|
||||
* with no central authority: managing transactions and issuing money are carried out collectively by the network.
|
||||
*
|
||||
|
|
|
@ -5,7 +5,6 @@
|
|||
|
||||
#include "chainparams.h"
|
||||
|
||||
#include "random.h"
|
||||
#include "util.h"
|
||||
#include "utilstrencodings.h"
|
||||
|
||||
|
@ -16,35 +15,11 @@
|
|||
|
||||
using namespace std;
|
||||
|
||||
struct SeedSpec6 {
|
||||
uint8_t addr[16];
|
||||
uint16_t port;
|
||||
};
|
||||
|
||||
#include "chainparamsseeds.h"
|
||||
|
||||
/**
|
||||
* Main network
|
||||
*/
|
||||
|
||||
//! Convert the pnSeeds6 array into usable address objects.
|
||||
static void convertSeed6(std::vector<CAddress> &vSeedsOut, const SeedSpec6 *data, unsigned int count)
|
||||
{
|
||||
// It'll only connect to one or two seed nodes because once it connects,
|
||||
// it'll get a pile of addresses with newer timestamps.
|
||||
// Seed nodes are given a random 'last seen time' of between one and two
|
||||
// weeks ago.
|
||||
const int64_t nOneWeek = 7*24*60*60;
|
||||
for (unsigned int i = 0; i < count; i++)
|
||||
{
|
||||
struct in6_addr ip;
|
||||
memcpy(&ip, data[i].addr, sizeof(ip));
|
||||
CAddress addr(CService(ip, data[i].port));
|
||||
addr.nTime = GetTime() - GetRand(nOneWeek) - nOneWeek;
|
||||
vSeedsOut.push_back(addr);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* What makes a good checkpoint block?
|
||||
* + Is surrounded by blocks with reasonable timestamps
|
||||
|
@ -110,7 +85,7 @@ public:
|
|||
consensus.nMajorityEnforceBlockUpgrade = 750;
|
||||
consensus.nMajorityRejectBlockOutdated = 950;
|
||||
consensus.nMajorityWindow = 1000;
|
||||
consensus.powLimit = ~arith_uint256(0) >> 16;
|
||||
consensus.powLimit = uint256S("0000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff");
|
||||
consensus.nPowTargetTimespan = 30 * 60 * 12;//14 * 24 * 60 * 60; // two weeks
|
||||
consensus.nPowTargetSpacing = 30;
|
||||
consensus.fPowAllowMinDifficultyBlocks = false;
|
||||
|
@ -126,6 +101,7 @@ public:
|
|||
vAlertPubKey = ParseHex("04fc9702847840aaf195de8442ebecedf5b095cdbb9bc716bda9110971b28a49e0ead8564ff0db22209e0374782c093bb899692d524e9d6a6956e7c5ecbcd68284");
|
||||
nDefaultPort = 8333;
|
||||
nMinerThreads = 2;
|
||||
nPruneAfterHeight = 100000;
|
||||
|
||||
/**
|
||||
* Build the genesis block. Note that the output of the genesis coinbase cannot
|
||||
|
@ -179,11 +155,11 @@ public:
|
|||
//assert(genesis.hashMerkleRoot == uint256S("0xa7d51d407092059a2beeffab22e65d6176cfb3c33b93515109480aa7c81c9141"));
|
||||
assert(genesis.hashMerkleRoot == uint256S("0x93621531f4de4b27d4ffdf785ef12855f2b18687e2141466ff50e2848d83f551"));
|
||||
|
||||
//vSeeds.push_back(CDNSSeedData("bitcoin.sipa.be", "seed.bitcoin.sipa.be"));
|
||||
//vSeeds.push_back(CDNSSeedData("bluematt.me", "dnsseed.bluematt.me"));
|
||||
//vSeeds.push_back(CDNSSeedData("dashjr.org", "dnsseed.bitcoin.dashjr.org"));
|
||||
//vSeeds.push_back(CDNSSeedData("bitcoinstats.com", "seed.bitcoinstats.com"));
|
||||
//vSeeds.push_back(CDNSSeedData("xf2.org", "bitseed.xf2.org"));
|
||||
//vSeeds.push_back(CDNSSeedData("bitcoin.sipa.be", "seed.bitcoin.sipa.be")); // Pieter Wuille
|
||||
//vSeeds.push_back(CDNSSeedData("bluematt.me", "dnsseed.bluematt.me")); // Matt Corallo
|
||||
//vSeeds.push_back(CDNSSeedData("dashjr.org", "dnsseed.bitcoin.dashjr.org")); // Luke Dashjr
|
||||
//vSeeds.push_back(CDNSSeedData("bitcoinstats.com", "seed.bitcoinstats.com")); // Addy Yeow
|
||||
//vSeeds.push_back(CDNSSeedData("xf2.org", "bitseed.xf2.org")); // Jeff Garzik
|
||||
|
||||
vSeeds.clear();
|
||||
vFixedSeeds.clear();
|
||||
|
@ -194,7 +170,7 @@ public:
|
|||
base58Prefixes[EXT_PUBLIC_KEY] = boost::assign::list_of(0x04)(0x88)(0xB2)(0x1E).convert_to_container<std::vector<unsigned char> >();
|
||||
base58Prefixes[EXT_SECRET_KEY] = boost::assign::list_of(0x04)(0x88)(0xAD)(0xE4).convert_to_container<std::vector<unsigned char> >();
|
||||
|
||||
convertSeed6(vFixedSeeds, pnSeed6_main, ARRAYLEN(pnSeed6_main));
|
||||
vFixedSeeds = std::vector<SeedSpec6>(pnSeed6_main, pnSeed6_main + ARRAYLEN(pnSeed6_main));
|
||||
|
||||
fRequireRPCPassword = true;
|
||||
fMiningRequiresPeers = true;
|
||||
|
@ -229,6 +205,7 @@ public:
|
|||
vAlertPubKey = ParseHex("04302390343f91cc401d56d68b123028bf52e5fca1939df127f63c6467cdf9c8e2c14b61104cf817d0b780da337893ecc4aaff1309e536162dabbdb45200ca2b0a");
|
||||
nDefaultPort = 18333;
|
||||
nMinerThreads = 0;
|
||||
nPruneAfterHeight = 1000;
|
||||
|
||||
//! Modify the testnet genesis block so the timestamp is valid for a later start.
|
||||
genesis.nTime = 1296688602;
|
||||
|
@ -249,7 +226,7 @@ public:
|
|||
base58Prefixes[EXT_PUBLIC_KEY] = boost::assign::list_of(0x04)(0x35)(0x87)(0xCF).convert_to_container<std::vector<unsigned char> >();
|
||||
base58Prefixes[EXT_SECRET_KEY] = boost::assign::list_of(0x04)(0x35)(0x83)(0x94).convert_to_container<std::vector<unsigned char> >();
|
||||
|
||||
convertSeed6(vFixedSeeds, pnSeed6_test, ARRAYLEN(pnSeed6_test));
|
||||
vFixedSeeds = std::vector<SeedSpec6>(pnSeed6_test, pnSeed6_test + ARRAYLEN(pnSeed6_test));
|
||||
|
||||
fRequireRPCPassword = true;
|
||||
fMiningRequiresPeers = true;
|
||||
|
@ -276,7 +253,7 @@ public:
|
|||
consensus.nMajorityEnforceBlockUpgrade = 750;
|
||||
consensus.nMajorityRejectBlockOutdated = 950;
|
||||
consensus.nMajorityWindow = 1000;
|
||||
consensus.powLimit = ~arith_uint256(0) >> 1;
|
||||
consensus.powLimit = uint256S("7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff");
|
||||
pchMessageStart[0] = 0xfa;
|
||||
pchMessageStart[1] = 0xbf;
|
||||
pchMessageStart[2] = 0xb5;
|
||||
|
@ -288,6 +265,7 @@ public:
|
|||
consensus.hashGenesisBlock = genesis.GetHash();
|
||||
nDefaultPort = 18444;
|
||||
//assert(consensus.hashGenesisBlock == uint256("0x0f9188f13cb7b2c71f2a335e3a4fc328bf5beb436012afca590b1a11466e2206"));
|
||||
nPruneAfterHeight = 1000;
|
||||
|
||||
vFixedSeeds.clear(); //! Regtest mode doesn't have any fixed seeds.
|
||||
vSeeds.clear(); //! Regtest mode doesn't have any DNS seeds.
|
||||
|
|
|
@ -6,7 +6,6 @@
|
|||
#ifndef BITCOIN_CHAINPARAMS_H
|
||||
#define BITCOIN_CHAINPARAMS_H
|
||||
|
||||
#include "arith_uint256.h"
|
||||
#include "chainparamsbase.h"
|
||||
#include "checkpoints.h"
|
||||
#include "consensus/params.h"
|
||||
|
@ -20,6 +19,12 @@ struct CDNSSeedData {
|
|||
CDNSSeedData(const std::string &strName, const std::string &strHost) : name(strName), host(strHost) {}
|
||||
};
|
||||
|
||||
struct SeedSpec6 {
|
||||
uint8_t addr[16];
|
||||
uint16_t port;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* CChainParams defines various tweakable parameters of a given instance of the
|
||||
* Bitcoin system. There are three: the main network on which people trade goods
|
||||
|
@ -41,11 +46,9 @@ public:
|
|||
};
|
||||
|
||||
const Consensus::Params& GetConsensus() const { return consensus; }
|
||||
const uint256& HashGenesisBlock() const { return consensus.hashGenesisBlock; }
|
||||
const CMessageHeader::MessageStartChars& MessageStart() const { return pchMessageStart; }
|
||||
const std::vector<unsigned char>& AlertKey() const { return vAlertPubKey; }
|
||||
int GetDefaultPort() const { return nDefaultPort; }
|
||||
const arith_uint256& ProofOfWorkLimit() const { return consensus.powLimit; }
|
||||
int SubsidyHalvingInterval() const { return consensus.nSubsidyHalvingInterval; }
|
||||
int EnforceBlockUpgradeMajority() const { return consensus.nMajorityEnforceBlockUpgrade; }
|
||||
int RejectBlockOutdatedMajority() const { return consensus.nMajorityRejectBlockOutdated; }
|
||||
|
@ -59,13 +62,9 @@ public:
|
|||
bool MiningRequiresPeers() const { return fMiningRequiresPeers; }
|
||||
/** Default value for -checkmempool and -checkblockindex argument */
|
||||
bool DefaultConsistencyChecks() const { return fDefaultConsistencyChecks; }
|
||||
/** Allow mining of a min-difficulty block */
|
||||
bool AllowMinDifficultyBlocks() const { return consensus.fPowAllowMinDifficultyBlocks; }
|
||||
/** Make standard checks */
|
||||
bool RequireStandard() const { return fRequireStandard; }
|
||||
int64_t TargetTimespan() const { return consensus.nPowTargetTimespan; }
|
||||
int64_t TargetSpacing() const { return consensus.nPowTargetSpacing; }
|
||||
int64_t DifficultyAdjustmentInterval() const { return consensus.nPowTargetTimespan / consensus.nPowTargetSpacing; }
|
||||
int64_t PruneAfterHeight() const { return nPruneAfterHeight; }
|
||||
/** Make miner stop after a block is found. In RPC, don't return until nGenProcLimit blocks are generated */
|
||||
bool MineBlocksOnDemand() const { return fMineBlocksOnDemand; }
|
||||
/** In the future use NetworkIDString() for RPC fields */
|
||||
|
@ -74,7 +73,7 @@ public:
|
|||
std::string NetworkIDString() const { return strNetworkID; }
|
||||
const std::vector<CDNSSeedData>& DNSSeeds() const { return vSeeds; }
|
||||
const std::vector<unsigned char>& Base58Prefix(Base58Type type) const { return base58Prefixes[type]; }
|
||||
const std::vector<CAddress>& FixedSeeds() const { return vFixedSeeds; }
|
||||
const std::vector<SeedSpec6>& FixedSeeds() const { return vFixedSeeds; }
|
||||
virtual const Checkpoints::CCheckpointData& Checkpoints() const = 0;
|
||||
protected:
|
||||
CChainParams() {}
|
||||
|
@ -85,11 +84,12 @@ protected:
|
|||
std::vector<unsigned char> vAlertPubKey;
|
||||
int nDefaultPort;
|
||||
int nMinerThreads;
|
||||
uint64_t nPruneAfterHeight;
|
||||
std::vector<CDNSSeedData> vSeeds;
|
||||
std::vector<unsigned char> base58Prefixes[MAX_BASE58_TYPES];
|
||||
std::string strNetworkID;
|
||||
CBlock genesis;
|
||||
std::vector<CAddress> vFixedSeeds;
|
||||
std::vector<SeedSpec6> vFixedSeeds;
|
||||
bool fRequireRPCPassword;
|
||||
bool fMiningRequiresPeers;
|
||||
bool fDefaultConsistencyChecks;
|
||||
|
|
18
src/consensus/consensus.h
Normal file
18
src/consensus/consensus.h
Normal file
|
@ -0,0 +1,18 @@
|
|||
// Copyright (c) 2009-2010 Satoshi Nakamoto
|
||||
// Copyright (c) 2009-2014 The Bitcoin Core developers
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#ifndef BITCOIN_CONSENSUS_CONSENSUS_H
|
||||
#define BITCOIN_CONSENSUS_CONSENSUS_H
|
||||
|
||||
/** The maximum allowed size for a serialized block, in bytes (network rule) */
|
||||
static const unsigned int MAX_BLOCK_SIZE = 1000000;
|
||||
/** The maximum allowed number of signature check operations in a block (network rule) */
|
||||
static const unsigned int MAX_BLOCK_SIGOPS = MAX_BLOCK_SIZE/50;
|
||||
/** Coinbase transaction outputs can only be spent after this number of new blocks (network rule) */
|
||||
static const int COINBASE_MATURITY = 100;
|
||||
/** Threshold for nLockTime: below this value it is interpreted as block number, otherwise as UNIX timestamp. */
|
||||
static const unsigned int LOCKTIME_THRESHOLD = 500000000; // Tue Nov 5 00:53:20 1985 UTC
|
||||
|
||||
#endif // BITCOIN_CONSENSUS_CONSENSUS_H
|
|
@ -3,10 +3,9 @@
|
|||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#ifndef BITCOIN_CONSENSUS_CONSENSUS_PARAMS_H
|
||||
#define BITCOIN_CONSENSUS_CONSENSUS_PARAMS_H
|
||||
#ifndef BITCOIN_CONSENSUS_PARAMS_H
|
||||
#define BITCOIN_CONSENSUS_PARAMS_H
|
||||
|
||||
#include "arith_uint256.h"
|
||||
#include "uint256.h"
|
||||
|
||||
namespace Consensus {
|
||||
|
@ -21,7 +20,7 @@ struct Params {
|
|||
int nMajorityRejectBlockOutdated;
|
||||
int nMajorityWindow;
|
||||
/** Proof of work parameters */
|
||||
arith_uint256 powLimit;
|
||||
uint256 powLimit;
|
||||
bool fPowAllowMinDifficultyBlocks;
|
||||
int64_t nPowTargetSpacing;
|
||||
int64_t nPowTargetTimespan;
|
||||
|
@ -29,4 +28,4 @@ struct Params {
|
|||
};
|
||||
} // namespace Consensus
|
||||
|
||||
#endif // BITCOIN_CONSENSUS_CONSENSUS_PARAMS_H
|
||||
#endif // BITCOIN_CONSENSUS_PARAMS_H
|
||||
|
|
121
src/init.cpp
121
src/init.cpp
|
@ -68,7 +68,7 @@ enum BindFlags {
|
|||
};
|
||||
|
||||
static const char* FEE_ESTIMATES_FILENAME="fee_estimates.dat";
|
||||
CClientUIInterface uiInterface;
|
||||
CClientUIInterface uiInterface; // Declared but not defined in ui_interface.h
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
|
@ -123,7 +123,7 @@ public:
|
|||
LogPrintf("Error reading from database: %s\n", e.what());
|
||||
// Starting the shutdown sequence and returning false to the caller would be
|
||||
// interpreted as 'entry not found' (as opposed to unable to read data), and
|
||||
// could lead to invalid interpration. Just exit immediately, as we can't
|
||||
// could lead to invalid interpretation. Just exit immediately, as we can't
|
||||
// continue anyway, and all writes should be atomic.
|
||||
abort();
|
||||
}
|
||||
|
@ -244,11 +244,6 @@ void OnRPCStopped()
|
|||
|
||||
void OnRPCPreCommand(const CRPCCommand& cmd)
|
||||
{
|
||||
#ifdef ENABLE_WALLET
|
||||
if (cmd.reqWallet && !pwalletMain)
|
||||
throw JSONRPCError(RPC_METHOD_NOT_FOUND, "Method not found (disabled)");
|
||||
#endif
|
||||
|
||||
// Observe safe mode
|
||||
string strWarning = GetWarnings("rpc");
|
||||
if (strWarning != "" && !GetBoolArg("-disablesafemode", false) &&
|
||||
|
@ -282,7 +277,12 @@ std::string HelpMessage(HelpMessageMode mode)
|
|||
#ifndef WIN32
|
||||
strUsage += HelpMessageOpt("-pid=<file>", strprintf(_("Specify pid file (default: %s)"), "bitcoind.pid"));
|
||||
#endif
|
||||
strUsage += HelpMessageOpt("-reindex", _("Rebuild block chain index from current blk000??.dat files") + " " + _("on startup"));
|
||||
strUsage += HelpMessageOpt("-prune=<n>", _("Reduce storage requirements by pruning (deleting) old blocks. This mode disables wallet support and is incompatible with -txindex.") + " " +
|
||||
_("Warning: Reverting this setting requires re-downloading the entire blockchain.") + " " +
|
||||
_("(default: 0 = disable pruning blocks,") + " " +
|
||||
strprintf(_(">%u = target size in MiB to use for block files)"), MIN_DISK_SPACE_FOR_BLOCK_FILES / 1024 / 1024));
|
||||
strUsage += HelpMessageOpt("-reindex", _("Rebuild block chain index from current blk000??.dat files") + " " + _("on startup"));
|
||||
|
||||
#if !defined(WIN32)
|
||||
strUsage += HelpMessageOpt("-sysperms", _("Create new files with system default permissions, instead of umask 077 (only effective with disabled wallet functionality)"));
|
||||
#endif
|
||||
|
@ -308,6 +308,7 @@ std::string HelpMessage(HelpMessageMode mode)
|
|||
strUsage += HelpMessageOpt("-permitbaremultisig", strprintf(_("Relay non-P2SH multisig (default: %u)"), 1));
|
||||
strUsage += HelpMessageOpt("-port=<port>", strprintf(_("Listen for connections on <port> (default: %u or testnet: %u)"), 8333, 18333));
|
||||
strUsage += HelpMessageOpt("-proxy=<ip:port>", _("Connect through SOCKS5 proxy"));
|
||||
strUsage += HelpMessageOpt("-proxyrandomize", strprintf(_("Randomize credentials for every proxy connection. This enables Tor stream isolation (default: %u)"), 1));
|
||||
strUsage += HelpMessageOpt("-seednode=<ip>", _("Connect to a node to retrieve peer addresses, and disconnect"));
|
||||
strUsage += HelpMessageOpt("-timeout=<n>", strprintf(_("Specify connection timeout in milliseconds (minimum: 1, default: %d)"), DEFAULT_CONNECT_TIMEOUT));
|
||||
#ifdef USE_UPNP
|
||||
|
@ -358,7 +359,7 @@ std::string HelpMessage(HelpMessageMode mode)
|
|||
strUsage += HelpMessageOpt("-flushwallet", strprintf(_("Run a thread to flush wallet periodically (default: %u)"), 1));
|
||||
strUsage += HelpMessageOpt("-stopafterblockimport", strprintf(_("Stop running after importing blocks from disk (default: %u)"), 0));
|
||||
}
|
||||
string debugCategories = "addrman, alert, bench, coindb, db, lock, rand, rpc, selectcoins, mempool, net"; // Don't translate these and qt below
|
||||
string debugCategories = "addrman, alert, bench, coindb, db, lock, rand, rpc, selectcoins, mempool, net, proxy, prune"; // Don't translate these and qt below
|
||||
if (mode == HMM_BITCOIN_QT)
|
||||
debugCategories += ", qt";
|
||||
strUsage += HelpMessageOpt("-debug=<category>", strprintf(_("Output debugging information (default: %u, supplying <category> is optional)"), 0) + ". " +
|
||||
|
@ -372,8 +373,8 @@ std::string HelpMessage(HelpMessageMode mode)
|
|||
strUsage += HelpMessageOpt("-logtimestamps", strprintf(_("Prepend debug output with timestamp (default: %u)"), 1));
|
||||
if (GetBoolArg("-help-debug", false))
|
||||
{
|
||||
strUsage += HelpMessageOpt("-limitfreerelay=<n>", strprintf(_("Continuously rate-limit free transactions to <n>*1000 bytes per minute (default:%u)"), 15));
|
||||
strUsage += HelpMessageOpt("-relaypriority", strprintf(_("Require high priority for relaying free or low-fee transactions (default:%u)"), 1));
|
||||
strUsage += HelpMessageOpt("-limitfreerelay=<n>", strprintf(_("Continuously rate-limit free transactions to <n>*1000 bytes per minute (default: %u)"), 15));
|
||||
strUsage += HelpMessageOpt("-relaypriority", strprintf(_("Require high priority for relaying free or low-fee transactions (default: %u)"), 1));
|
||||
strUsage += HelpMessageOpt("-maxsigcachesize=<n>", strprintf(_("Limit size of signature cache to <n> entries (default: %u)"), 50000));
|
||||
}
|
||||
strUsage += HelpMessageOpt("-minrelaytxfee=<amt>", strprintf(_("Fees (in BTC/Kb) smaller than this are considered zero fee for relaying (default: %s)"), FormatMoney(::minRelayTxFee.GetFeePerK())));
|
||||
|
@ -464,10 +465,33 @@ struct CImportingNow
|
|||
}
|
||||
};
|
||||
|
||||
|
||||
// If we're using -prune with -reindex, then delete block files that will be ignored by the
|
||||
// reindex. Since reindexing works by starting at block file 0 and looping until a blockfile
|
||||
// is missing, and since pruning works by deleting the oldest block file first, just check
|
||||
// for block file 0, and if it doesn't exist, delete all the block files in the
|
||||
// directory (since they won't be read by the reindex but will take up disk space).
|
||||
void DeleteAllBlockFiles()
|
||||
{
|
||||
if (boost::filesystem::exists(GetBlockPosFilename(CDiskBlockPos(0, 0), "blk")))
|
||||
return;
|
||||
|
||||
LogPrintf("Removing all blk?????.dat and rev?????.dat files for -reindex with -prune\n");
|
||||
boost::filesystem::path blocksdir = GetDataDir() / "blocks";
|
||||
for (boost::filesystem::directory_iterator it(blocksdir); it != boost::filesystem::directory_iterator(); it++) {
|
||||
if (is_regular_file(*it)) {
|
||||
if ((it->path().filename().string().length() == 12) &&
|
||||
(it->path().filename().string().substr(8,4) == ".dat") &&
|
||||
((it->path().filename().string().substr(0,3) == "blk") ||
|
||||
(it->path().filename().string().substr(0,3) == "rev")))
|
||||
boost::filesystem::remove(it->path());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ThreadImport(std::vector<boost::filesystem::path> vImportFiles)
|
||||
{
|
||||
RenameThread("bitcoin-loadblk");
|
||||
|
||||
// -reindex
|
||||
if (fReindex) {
|
||||
CImportingNow imp;
|
||||
|
@ -609,6 +633,7 @@ bool AppInit2(boost::thread_group& threadGroup)
|
|||
#endif
|
||||
|
||||
// ********************************************************* Step 2: parameter interactions
|
||||
const CChainParams& chainparams = Params();
|
||||
|
||||
// Set this early so that parameter interactions go to console
|
||||
fPrintToConsole = GetBoolArg("-printtoconsole", false);
|
||||
|
@ -679,6 +704,21 @@ bool AppInit2(boost::thread_group& threadGroup)
|
|||
if (nFD - MIN_CORE_FILEDESCRIPTORS < nMaxConnections)
|
||||
nMaxConnections = nFD - MIN_CORE_FILEDESCRIPTORS;
|
||||
|
||||
// if using block pruning, then disable txindex
|
||||
// also disable the wallet (for now, until SPV support is implemented in wallet)
|
||||
if (GetArg("-prune", 0)) {
|
||||
if (GetBoolArg("-txindex", false))
|
||||
return InitError(_("Prune mode is incompatible with -txindex."));
|
||||
#ifdef ENABLE_WALLET
|
||||
if (!GetBoolArg("-disablewallet", false)) {
|
||||
if (SoftSetBoolArg("-disablewallet", true))
|
||||
LogPrintf("%s : parameter interaction: -prune -> setting -disablewallet=1\n", __func__);
|
||||
else
|
||||
return InitError(_("Can't run with a wallet in prune mode."));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
// ********************************************************* Step 3: parameter-to-internal-flags
|
||||
|
||||
fDebug = !mapMultiArgs["-debug"].empty();
|
||||
|
@ -701,8 +741,8 @@ bool AppInit2(boost::thread_group& threadGroup)
|
|||
InitWarning(_("Warning: Unsupported argument -benchmark ignored, use -debug=bench."));
|
||||
|
||||
// Checkmempool and checkblockindex default to true in regtest mode
|
||||
mempool.setSanityCheck(GetBoolArg("-checkmempool", Params().DefaultConsistencyChecks()));
|
||||
fCheckBlockIndex = GetBoolArg("-checkblockindex", Params().DefaultConsistencyChecks());
|
||||
mempool.setSanityCheck(GetBoolArg("-checkmempool", chainparams.DefaultConsistencyChecks()));
|
||||
fCheckBlockIndex = GetBoolArg("-checkblockindex", chainparams.DefaultConsistencyChecks());
|
||||
Checkpoints::fEnabled = GetBoolArg("-checkpoints", true);
|
||||
|
||||
// -par=0 means autodetect, but nScriptCheckThreads==0 means no concurrency
|
||||
|
@ -715,6 +755,21 @@ bool AppInit2(boost::thread_group& threadGroup)
|
|||
nScriptCheckThreads = MAX_SCRIPTCHECK_THREADS;
|
||||
|
||||
fServer = GetBoolArg("-server", false);
|
||||
|
||||
// block pruning; get the amount of disk space (in MB) to allot for block & undo files
|
||||
int64_t nSignedPruneTarget = GetArg("-prune", 0) * 1024 * 1024;
|
||||
if (nSignedPruneTarget < 0) {
|
||||
return InitError(_("Prune cannot be configured with a negative value."));
|
||||
}
|
||||
nPruneTarget = (uint64_t) nSignedPruneTarget;
|
||||
if (nPruneTarget) {
|
||||
if (nPruneTarget < MIN_DISK_SPACE_FOR_BLOCK_FILES) {
|
||||
return InitError(strprintf(_("Prune configured below the minimum of %d MB. Please use a higher number."), MIN_DISK_SPACE_FOR_BLOCK_FILES / 1024 / 1024));
|
||||
}
|
||||
LogPrintf("Prune configured to target %uMiB on disk for block and undo files.\n", nPruneTarget / 1024 / 1024);
|
||||
fPruneMode = true;
|
||||
}
|
||||
|
||||
#ifdef ENABLE_WALLET
|
||||
bool fDisableWallet = GetBoolArg("-disablewallet", false);
|
||||
#endif
|
||||
|
@ -897,10 +952,10 @@ bool AppInit2(boost::thread_group& threadGroup)
|
|||
}
|
||||
}
|
||||
|
||||
CService addrProxy;
|
||||
proxyType addrProxy;
|
||||
bool fProxy = false;
|
||||
if (mapArgs.count("-proxy")) {
|
||||
addrProxy = CService(mapArgs["-proxy"], 9050);
|
||||
addrProxy = proxyType(CService(mapArgs["-proxy"], 9050), GetArg("-proxyrandomize", true));
|
||||
if (!addrProxy.IsValid())
|
||||
return InitError(strprintf(_("Invalid -proxy address: '%s'"), mapArgs["-proxy"]));
|
||||
|
||||
|
@ -910,14 +965,14 @@ bool AppInit2(boost::thread_group& threadGroup)
|
|||
fProxy = true;
|
||||
}
|
||||
|
||||
// -onion can override normal proxy, -noonion disables tor entirely
|
||||
// -onion can override normal proxy, -noonion disables connecting to .onion entirely
|
||||
if (!(mapArgs.count("-onion") && mapArgs["-onion"] == "0") &&
|
||||
(fProxy || mapArgs.count("-onion"))) {
|
||||
CService addrOnion;
|
||||
proxyType addrOnion;
|
||||
if (!mapArgs.count("-onion"))
|
||||
addrOnion = addrProxy;
|
||||
else
|
||||
addrOnion = CService(mapArgs["-onion"], 9050);
|
||||
addrOnion = proxyType(CService(mapArgs["-onion"], 9050), GetArg("-proxyrandomize", true));
|
||||
if (!addrOnion.IsValid())
|
||||
return InitError(strprintf(_("Invalid -onion address: '%s'"), mapArgs["-onion"]));
|
||||
SetProxy(NET_TOR, addrOnion);
|
||||
|
@ -1037,8 +1092,12 @@ bool AppInit2(boost::thread_group& threadGroup)
|
|||
pcoinsTip = new CCoinsViewCache(pcoinscatcher);
|
||||
pnccTrie = new CNCCTrie(false, fReindex);
|
||||
|
||||
if (fReindex)
|
||||
if (fReindex) {
|
||||
pblocktree->WriteReindexing(true);
|
||||
//If we're reindexing in prune mode, wipe away all our block and undo data files
|
||||
if (fPruneMode)
|
||||
DeleteAllBlockFiles();
|
||||
}
|
||||
|
||||
if (!LoadBlockIndex()) {
|
||||
strLoadError = _("Error loading block database");
|
||||
|
@ -1047,7 +1106,7 @@ bool AppInit2(boost::thread_group& threadGroup)
|
|||
|
||||
// If the loaded chain has a wrong genesis, bail out immediately
|
||||
// (we're likely using a testnet datadir, or the other way around).
|
||||
if (!mapBlockIndex.empty() && mapBlockIndex.count(Params().HashGenesisBlock()) == 0)
|
||||
if (!mapBlockIndex.empty() && mapBlockIndex.count(chainparams.GetConsensus().hashGenesisBlock) == 0)
|
||||
return InitError(_("Incorrect or no genesis block found. Wrong datadir for network?"));
|
||||
|
||||
// Initialize the block index (no-op if non-empty database was already loaded)
|
||||
|
@ -1068,7 +1127,18 @@ bool AppInit2(boost::thread_group& threadGroup)
|
|||
break;
|
||||
}
|
||||
|
||||
// Check for changed -prune state. What we are concerned about is a user who has pruned blocks
|
||||
// in the past, but is now trying to run unpruned.
|
||||
if (fHavePruned && !fPruneMode) {
|
||||
strLoadError = _("You need to rebuild the database using -reindex to go back to unpruned mode. This will redownload the entire blockchain");
|
||||
break;
|
||||
}
|
||||
|
||||
uiInterface.InitMessage(_("Verifying blocks..."));
|
||||
if (fHavePruned && GetArg("-checkblocks", 288) > MIN_BLOCKS_TO_KEEP) {
|
||||
LogPrintf("Prune: pruned datadir may not have more than %d blocks; -checkblocks=%d may fail\n",
|
||||
MIN_BLOCKS_TO_KEEP, GetArg("-checkblocks", 288));
|
||||
}
|
||||
if (!CVerifyDB().VerifyDB(pcoinsdbview, GetArg("-checklevel", 3),
|
||||
GetArg("-checkblocks", 288))) {
|
||||
strLoadError = _("Corrupted block database detected");
|
||||
|
@ -1119,6 +1189,15 @@ bool AppInit2(boost::thread_group& threadGroup)
|
|||
mempool.ReadFeeEstimates(est_filein);
|
||||
fFeeEstimatesInitialized = true;
|
||||
|
||||
// if prune mode, unset NODE_NETWORK and prune block files
|
||||
if (fPruneMode) {
|
||||
LogPrintf("Unsetting NODE_NETWORK on prune mode\n");
|
||||
nLocalServices &= ~NODE_NETWORK;
|
||||
if (!fReindex) {
|
||||
PruneAndFlush();
|
||||
}
|
||||
}
|
||||
|
||||
// ********************************************************* Step 8: load wallet
|
||||
#ifdef ENABLE_WALLET
|
||||
if (fDisableWallet) {
|
||||
|
|
369
src/main.cpp
369
src/main.cpp
|
@ -54,9 +54,12 @@ int nScriptCheckThreads = 0;
|
|||
bool fImporting = false;
|
||||
bool fReindex = false;
|
||||
bool fTxIndex = false;
|
||||
bool fHavePruned = false;
|
||||
bool fPruneMode = false;
|
||||
bool fIsBareMultisigStd = true;
|
||||
bool fCheckBlockIndex = false;
|
||||
unsigned int nCoinCacheSize = 5000;
|
||||
uint64_t nPruneTarget = 0;
|
||||
|
||||
/** Fees smaller than this (in satoshi) are considered zero fee (for relaying and mining) */
|
||||
CFeeRate minRelayTxFee = CFeeRate(1000);
|
||||
|
@ -112,17 +115,25 @@ namespace {
|
|||
|
||||
/**
|
||||
* The set of all CBlockIndex entries with BLOCK_VALID_TRANSACTIONS (for itself and all ancestors) and
|
||||
* as good as our current tip or better. Entries may be failed, though.
|
||||
* as good as our current tip or better. Entries may be failed, though, and pruning nodes may be
|
||||
* missing the data for the block.
|
||||
*/
|
||||
set<CBlockIndex*, CBlockIndexWorkComparator> setBlockIndexCandidates;
|
||||
/** Number of nodes with fSyncStarted. */
|
||||
int nSyncStarted = 0;
|
||||
/** All pairs A->B, where A (or one if its ancestors) misses transactions, but B has transactions. */
|
||||
/** All pairs A->B, where A (or one if its ancestors) misses transactions, but B has transactions.
|
||||
* Pruned nodes may have entries where B is missing data.
|
||||
*/
|
||||
multimap<CBlockIndex*, CBlockIndex*> mapBlocksUnlinked;
|
||||
|
||||
CCriticalSection cs_LastBlockFile;
|
||||
std::vector<CBlockFileInfo> vinfoBlockFile;
|
||||
int nLastBlockFile = 0;
|
||||
/** Global flag to indicate we should check to see if there are
|
||||
* block/undo files that should be deleted. Set on startup
|
||||
* or if we allocate more file space when we're in prune mode
|
||||
*/
|
||||
bool fCheckForPruning = false;
|
||||
|
||||
/**
|
||||
* Every received block is assigned a unique and increasing identifier, so we
|
||||
|
@ -1237,14 +1248,14 @@ void CheckForkWarningConditions()
|
|||
}
|
||||
if (pindexBestForkTip && pindexBestForkBase)
|
||||
{
|
||||
LogPrintf("CheckForkWarningConditions: Warning: Large valid fork found\n forking the chain at height %d (%s)\n lasting to height %d (%s).\nChain state database corruption likely.\n",
|
||||
LogPrintf("%s: Warning: Large valid fork found\n forking the chain at height %d (%s)\n lasting to height %d (%s).\nChain state database corruption likely.\n", __func__,
|
||||
pindexBestForkBase->nHeight, pindexBestForkBase->phashBlock->ToString(),
|
||||
pindexBestForkTip->nHeight, pindexBestForkTip->phashBlock->ToString());
|
||||
fLargeWorkForkFound = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
LogPrintf("CheckForkWarningConditions: Warning: Found invalid chain at least ~6 blocks longer than our best chain.\nChain state database corruption likely.\n");
|
||||
LogPrintf("%s: Warning: Found invalid chain at least ~6 blocks longer than our best chain.\nChain state database corruption likely.\n", __func__);
|
||||
fLargeWorkInvalidChainFound = true;
|
||||
}
|
||||
}
|
||||
|
@ -1302,10 +1313,10 @@ void Misbehaving(NodeId pnode, int howmuch)
|
|||
int banscore = GetArg("-banscore", 100);
|
||||
if (state->nMisbehavior >= banscore && state->nMisbehavior - howmuch < banscore)
|
||||
{
|
||||
LogPrintf("Misbehaving: %s (%d -> %d) BAN THRESHOLD EXCEEDED\n", state->name, state->nMisbehavior-howmuch, state->nMisbehavior);
|
||||
LogPrintf("%s: %s (%d -> %d) BAN THRESHOLD EXCEEDED\n", __func__, state->name, state->nMisbehavior-howmuch, state->nMisbehavior);
|
||||
state->fShouldBan = true;
|
||||
} else
|
||||
LogPrintf("Misbehaving: %s (%d -> %d)\n", state->name, state->nMisbehavior-howmuch, state->nMisbehavior);
|
||||
LogPrintf("%s: %s (%d -> %d)\n", __func__, state->name, state->nMisbehavior-howmuch, state->nMisbehavior);
|
||||
}
|
||||
|
||||
void static InvalidChainFound(CBlockIndex* pindexNew)
|
||||
|
@ -1313,11 +1324,11 @@ void static InvalidChainFound(CBlockIndex* pindexNew)
|
|||
if (!pindexBestInvalid || pindexNew->nChainWork > pindexBestInvalid->nChainWork)
|
||||
pindexBestInvalid = pindexNew;
|
||||
|
||||
LogPrintf("InvalidChainFound: invalid block=%s height=%d log2_work=%.8g date=%s\n",
|
||||
LogPrintf("%s: invalid block=%s height=%d log2_work=%.8g date=%s\n", __func__,
|
||||
pindexNew->GetBlockHash().ToString(), pindexNew->nHeight,
|
||||
log(pindexNew->nChainWork.getdouble())/log(2.0), DateTimeStrFormat("%Y-%m-%d %H:%M:%S",
|
||||
pindexNew->GetBlockTime()));
|
||||
LogPrintf("InvalidChainFound: current best=%s height=%d log2_work=%.8g date=%s\n",
|
||||
LogPrintf("%s: current best=%s height=%d log2_work=%.8g date=%s\n", __func__,
|
||||
chainActive.Tip()->GetBlockHash().ToString(), chainActive.Height(), log(chainActive.Tip()->nChainWork.getdouble())/log(2.0),
|
||||
DateTimeStrFormat("%Y-%m-%d %H:%M:%S", chainActive.Tip()->GetBlockTime()));
|
||||
CheckForkWarningConditions();
|
||||
|
@ -1722,6 +1733,7 @@ static int64_t nTimeTotal = 0;
|
|||
|
||||
bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pindex, CCoinsViewCache& view, CNCCTrieCache& trieCache, bool fJustCheck)
|
||||
{
|
||||
const CChainParams& chainparams = Params();
|
||||
AssertLockHeld(cs_main);
|
||||
// Check it again in case a previous version let a bad block in
|
||||
if (!CheckBlock(block, state, !fJustCheck, !fJustCheck))
|
||||
|
@ -1736,7 +1748,7 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin
|
|||
|
||||
// Special case for the genesis block, skipping connection of its transactions
|
||||
// (its coinbase is unspendable)
|
||||
if (block.GetHash() == Params().HashGenesisBlock()) {
|
||||
if (block.GetHash() == chainparams.GetConsensus().hashGenesisBlock) {
|
||||
if (!fJustCheck)
|
||||
{
|
||||
view.SetBestBlock(pindex->GetBlockHash());
|
||||
|
@ -1946,7 +1958,7 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin
|
|||
return true;
|
||||
|
||||
// Write undo information to disk
|
||||
if (!(block.GetHash() == Params().HashGenesisBlock()) && (pindex->GetUndoPos().IsNull() || !pindex->IsValid(BLOCK_VALID_SCRIPTS)))
|
||||
if (!(block.GetHash() == Params().GetConsensus().hashGenesisBlock) && (pindex->GetUndoPos().IsNull() || !pindex->IsValid(BLOCK_VALID_SCRIPTS)))
|
||||
{
|
||||
if (pindex->GetUndoPos().IsNull()) {
|
||||
CDiskBlockPos pos;
|
||||
|
@ -1987,6 +1999,7 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin
|
|||
}
|
||||
|
||||
enum FlushStateMode {
|
||||
FLUSH_STATE_NONE,
|
||||
FLUSH_STATE_IF_NEEDED,
|
||||
FLUSH_STATE_PERIODIC,
|
||||
FLUSH_STATE_ALWAYS
|
||||
|
@ -1994,16 +2007,30 @@ enum FlushStateMode {
|
|||
|
||||
/**
|
||||
* Update the on-disk chain state.
|
||||
* The caches and indexes are flushed if either they're too large, forceWrite is set, or
|
||||
* fast is not set and it's been a while since the last write.
|
||||
* The caches and indexes are flushed depending on the mode we're called with
|
||||
* if they're too large, if it's been a while since the last write,
|
||||
* or always and in all cases if we're in prune mode and are deleting files.
|
||||
*/
|
||||
bool static FlushStateToDisk(CValidationState &state, FlushStateMode mode) {
|
||||
LOCK(cs_main);
|
||||
LOCK2(cs_main, cs_LastBlockFile);
|
||||
static int64_t nLastWrite = 0;
|
||||
std::set<int> setFilesToPrune;
|
||||
bool fFlushForPrune = false;
|
||||
try {
|
||||
if (fPruneMode && fCheckForPruning) {
|
||||
FindFilesToPrune(setFilesToPrune);
|
||||
if (!setFilesToPrune.empty()) {
|
||||
fFlushForPrune = true;
|
||||
if (!fHavePruned) {
|
||||
pblocktree->WriteFlag("prunedblockfiles", true);
|
||||
fHavePruned = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if ((mode == FLUSH_STATE_ALWAYS) ||
|
||||
((mode == FLUSH_STATE_PERIODIC || mode == FLUSH_STATE_IF_NEEDED) && pcoinsTip->GetCacheSize() > nCoinCacheSize) ||
|
||||
(mode == FLUSH_STATE_PERIODIC && GetTimeMicros() > nLastWrite + DATABASE_WRITE_INTERVAL * 1000000)) {
|
||||
(mode == FLUSH_STATE_PERIODIC && GetTimeMicros() > nLastWrite + DATABASE_WRITE_INTERVAL * 1000000) ||
|
||||
fFlushForPrune) {
|
||||
// Typical CCoins structures on disk are around 100 bytes in size.
|
||||
// Pushing a new one to the database can cause it to be written
|
||||
// twice (once in the log, and once in the tables). This is already
|
||||
|
@ -2031,11 +2058,18 @@ bool static FlushStateToDisk(CValidationState &state, FlushStateMode mode) {
|
|||
return state.Abort("Files to write to block index database");
|
||||
}
|
||||
}
|
||||
// Finally flush the chainstate (which may refer to block index entries).
|
||||
// Flush the chainstate (which may refer to block index entries).
|
||||
if (!pnccTrie->WriteToDisk())
|
||||
return state.Abort("Failed to write to ncc trie database");
|
||||
if (!pcoinsTip->Flush())
|
||||
return state.Abort("Failed to write to coin database");
|
||||
|
||||
// Finally remove any pruned files
|
||||
if (fFlushForPrune) {
|
||||
UnlinkPrunedFiles(setFilesToPrune);
|
||||
fCheckForPruning = false;
|
||||
}
|
||||
|
||||
// Update best block in wallet (so we can detect restored wallets).
|
||||
if (mode != FLUSH_STATE_IF_NEEDED) {
|
||||
GetMainSignals().SetBestChain(chainActive.GetLocator());
|
||||
|
@ -2053,6 +2087,12 @@ void FlushStateToDisk() {
|
|||
FlushStateToDisk(state, FLUSH_STATE_ALWAYS);
|
||||
}
|
||||
|
||||
void PruneAndFlush() {
|
||||
CValidationState state;
|
||||
fCheckForPruning = true;
|
||||
FlushStateToDisk(state, FLUSH_STATE_NONE);
|
||||
}
|
||||
|
||||
/** Update chainActive and related internal data structures. */
|
||||
void static UpdateTip(CBlockIndex *pindexNew) {
|
||||
chainActive.SetTip(pindexNew);
|
||||
|
@ -2061,7 +2101,7 @@ void static UpdateTip(CBlockIndex *pindexNew) {
|
|||
nTimeBestReceived = GetTime();
|
||||
mempool.AddTransactionsUpdated(1);
|
||||
|
||||
LogPrintf("UpdateTip: new best=%s height=%d log2_work=%.8g tx=%lu date=%s progress=%f cache=%u\n",
|
||||
LogPrintf("%s: new best=%s height=%d log2_work=%.8g tx=%lu date=%s progress=%f cache=%u\n", __func__,
|
||||
chainActive.Tip()->GetBlockHash().ToString(), chainActive.Height(), log(chainActive.Tip()->nChainWork.getdouble())/log(2.0), (unsigned long)chainActive.Tip()->nChainTx,
|
||||
DateTimeStrFormat("%Y-%m-%d %H:%M:%S", chainActive.Tip()->GetBlockTime()),
|
||||
Checkpoints::GuessVerificationProgress(chainActive.Tip()), (unsigned int)pcoinsTip->GetCacheSize());
|
||||
|
@ -2081,7 +2121,7 @@ void static UpdateTip(CBlockIndex *pindexNew) {
|
|||
pindex = pindex->pprev;
|
||||
}
|
||||
if (nUpgraded > 0)
|
||||
LogPrintf("SetBestChain: %d of last 100 blocks above version %d\n", nUpgraded, (int)CBlock::CURRENT_VERSION);
|
||||
LogPrintf("%s: %d of last 100 blocks above version %d\n", __func__, nUpgraded, (int)CBlock::CURRENT_VERSION);
|
||||
if (nUpgraded > 100/2)
|
||||
{
|
||||
// strMiscWarning is read by GetWarnings(), called by Qt and the JSON-RPC code to warn the user:
|
||||
|
@ -2228,15 +2268,29 @@ static CBlockIndex* FindMostWorkChain() {
|
|||
CBlockIndex *pindexTest = pindexNew;
|
||||
bool fInvalidAncestor = false;
|
||||
while (pindexTest && !chainActive.Contains(pindexTest)) {
|
||||
assert(pindexTest->nStatus & BLOCK_HAVE_DATA);
|
||||
assert(pindexTest->nChainTx || pindexTest->nHeight == 0);
|
||||
if (pindexTest->nStatus & BLOCK_FAILED_MASK) {
|
||||
// Candidate has an invalid ancestor, remove entire chain from the set.
|
||||
if (pindexBestInvalid == NULL || pindexNew->nChainWork > pindexBestInvalid->nChainWork)
|
||||
|
||||
// Pruned nodes may have entries in setBlockIndexCandidates for
|
||||
// which block files have been deleted. Remove those as candidates
|
||||
// for the most work chain if we come across them; we can't switch
|
||||
// to a chain unless we have all the non-active-chain parent blocks.
|
||||
bool fFailedChain = pindexTest->nStatus & BLOCK_FAILED_MASK;
|
||||
bool fMissingData = !(pindexTest->nStatus & BLOCK_HAVE_DATA);
|
||||
if (fFailedChain || fMissingData) {
|
||||
// Candidate chain is not usable (either invalid or missing data)
|
||||
if (fFailedChain && (pindexBestInvalid == NULL || pindexNew->nChainWork > pindexBestInvalid->nChainWork))
|
||||
pindexBestInvalid = pindexNew;
|
||||
CBlockIndex *pindexFailed = pindexNew;
|
||||
// Remove the entire chain from the set.
|
||||
while (pindexTest != pindexFailed) {
|
||||
pindexFailed->nStatus |= BLOCK_FAILED_CHILD;
|
||||
if (fFailedChain) {
|
||||
pindexFailed->nStatus |= BLOCK_FAILED_CHILD;
|
||||
} else if (fMissingData) {
|
||||
// If we're missing data, then add back to mapBlocksUnlinked,
|
||||
// so that if the block arrives in the future we can try adding
|
||||
// to setBlockIndexCandidates again.
|
||||
mapBlocksUnlinked.insert(std::make_pair(pindexFailed->pprev, pindexFailed));
|
||||
}
|
||||
setBlockIndexCandidates.erase(pindexFailed);
|
||||
pindexFailed = pindexFailed->pprev;
|
||||
}
|
||||
|
@ -2364,7 +2418,9 @@ bool ActivateBestChain(CValidationState &state, CBlock *pblock) {
|
|||
uint256 hashNewTip = pindexNewTip->GetBlockHash();
|
||||
// Relay inventory, but don't relay old inventory during initial block download.
|
||||
int nBlockEstimate = Checkpoints::GetTotalBlocksEstimate();
|
||||
{
|
||||
// Don't relay blocks if pruning -- could cause a peer to try to download, resulting
|
||||
// in a stalled download if the block file is pruned before the request.
|
||||
if (nLocalServices & NODE_NETWORK) {
|
||||
LOCK(cs_vNodes);
|
||||
BOOST_FOREACH(CNode* pnode, vNodes)
|
||||
if (chainActive.Height() > (pnode->nStartingHeight != -1 ? pnode->nStartingHeight - 2000 : nBlockEstimate))
|
||||
|
@ -2495,10 +2551,6 @@ bool ReceivedBlockTransactions(const CBlock &block, CValidationState& state, CBl
|
|||
pindexNew->nUndoPos = 0;
|
||||
pindexNew->nStatus |= BLOCK_HAVE_DATA;
|
||||
pindexNew->RaiseValidity(BLOCK_VALID_TRANSACTIONS);
|
||||
{
|
||||
LOCK(cs_nBlockSequenceId);
|
||||
pindexNew->nSequenceId = nBlockSequenceId++;
|
||||
}
|
||||
setDirtyBlockIndex.insert(pindexNew);
|
||||
|
||||
if (pindexNew->pprev == NULL || pindexNew->pprev->nChainTx) {
|
||||
|
@ -2511,6 +2563,10 @@ bool ReceivedBlockTransactions(const CBlock &block, CValidationState& state, CBl
|
|||
CBlockIndex *pindex = queue.front();
|
||||
queue.pop_front();
|
||||
pindex->nChainTx = (pindex->pprev ? pindex->pprev->nChainTx : 0) + pindex->nTx;
|
||||
{
|
||||
LOCK(cs_nBlockSequenceId);
|
||||
pindex->nSequenceId = nBlockSequenceId++;
|
||||
}
|
||||
if (chainActive.Tip() == NULL || !setBlockIndexCandidates.value_comp()(pindex, chainActive.Tip())) {
|
||||
setBlockIndexCandidates.insert(pindex);
|
||||
}
|
||||
|
@ -2564,6 +2620,8 @@ bool FindBlockPos(CValidationState &state, CDiskBlockPos &pos, unsigned int nAdd
|
|||
unsigned int nOldChunks = (pos.nPos + BLOCKFILE_CHUNK_SIZE - 1) / BLOCKFILE_CHUNK_SIZE;
|
||||
unsigned int nNewChunks = (vinfoBlockFile[nFile].nSize + BLOCKFILE_CHUNK_SIZE - 1) / BLOCKFILE_CHUNK_SIZE;
|
||||
if (nNewChunks > nOldChunks) {
|
||||
if (fPruneMode)
|
||||
fCheckForPruning = true;
|
||||
if (CheckDiskSpace(nNewChunks * BLOCKFILE_CHUNK_SIZE - pos.nPos)) {
|
||||
FILE *file = OpenBlockFile(pos);
|
||||
if (file) {
|
||||
|
@ -2595,6 +2653,8 @@ bool FindUndoPos(CValidationState &state, int nFile, CDiskBlockPos &pos, unsigne
|
|||
unsigned int nOldChunks = (pos.nPos + UNDOFILE_CHUNK_SIZE - 1) / UNDOFILE_CHUNK_SIZE;
|
||||
unsigned int nNewChunks = (nNewSize + UNDOFILE_CHUNK_SIZE - 1) / UNDOFILE_CHUNK_SIZE;
|
||||
if (nNewChunks > nOldChunks) {
|
||||
if (fPruneMode)
|
||||
fCheckForPruning = true;
|
||||
if (CheckDiskSpace(nNewChunks * UNDOFILE_CHUNK_SIZE - pos.nPos)) {
|
||||
FILE *file = OpenUndoFile(pos);
|
||||
if (file) {
|
||||
|
@ -2687,8 +2747,9 @@ bool CheckBlock(const CBlock& block, CValidationState& state, bool fCheckPOW, bo
|
|||
|
||||
bool ContextualCheckBlockHeader(const CBlockHeader& block, CValidationState& state, CBlockIndex * const pindexPrev)
|
||||
{
|
||||
const Consensus::Params& consensusParams = Params().GetConsensus();
|
||||
uint256 hash = block.GetHash();
|
||||
if (hash == Params().HashGenesisBlock())
|
||||
if (hash == consensusParams.hashGenesisBlock)
|
||||
return true;
|
||||
|
||||
assert(pindexPrev);
|
||||
|
@ -2758,6 +2819,7 @@ bool ContextualCheckBlock(const CBlock& block, CValidationState& state, CBlockIn
|
|||
|
||||
bool AcceptBlockHeader(const CBlockHeader& block, CValidationState& state, CBlockIndex** ppindex)
|
||||
{
|
||||
const CChainParams& chainparams = Params();
|
||||
AssertLockHeld(cs_main);
|
||||
// Check for duplicate
|
||||
uint256 hash = block.GetHash();
|
||||
|
@ -2778,7 +2840,7 @@ bool AcceptBlockHeader(const CBlockHeader& block, CValidationState& state, CBloc
|
|||
|
||||
// Get prev block index
|
||||
CBlockIndex* pindexPrev = NULL;
|
||||
if (hash != Params().HashGenesisBlock()) {
|
||||
if (hash != chainparams.GetConsensus().hashGenesisBlock) {
|
||||
BlockMap::iterator mi = mapBlockIndex.find(block.hashPrevBlock);
|
||||
if (mi == mapBlockIndex.end())
|
||||
return state.DoS(10, error("%s: prev block not found", __func__), 0, "bad-prevblk");
|
||||
|
@ -2808,7 +2870,10 @@ bool AcceptBlock(CBlock& block, CValidationState& state, CBlockIndex** ppindex,
|
|||
if (!AcceptBlockHeader(block, state, &pindex))
|
||||
return false;
|
||||
|
||||
if (pindex->nStatus & BLOCK_HAVE_DATA) {
|
||||
// If we're pruning, ensure that we don't allow a peer to dump a copy
|
||||
// of old blocks. But we might need blocks that are not on the main chain
|
||||
// to handle a reorg, even if we've processed once.
|
||||
if (pindex->nStatus & BLOCK_HAVE_DATA || chainActive.Contains(pindex)) {
|
||||
// TODO: deal better with duplicate blocks.
|
||||
// return state.DoS(20, error("AcceptBlock(): already have block %d %s", pindex->nHeight, pindex->GetBlockHash().ToString()), REJECT_DUPLICATE, "duplicate");
|
||||
return true;
|
||||
|
@ -2841,6 +2906,9 @@ bool AcceptBlock(CBlock& block, CValidationState& state, CBlockIndex** ppindex,
|
|||
return state.Abort(std::string("System error: ") + e.what());
|
||||
}
|
||||
|
||||
if (fCheckForPruning)
|
||||
FlushStateToDisk(state, FLUSH_STATE_NONE); // we just allocated more disk space for block files
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -2929,6 +2997,112 @@ bool AbortNode(const std::string &strMessage, const std::string &userMessage) {
|
|||
return false;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* BLOCK PRUNING CODE
|
||||
*/
|
||||
|
||||
/* Calculate the amount of disk space the block & undo files currently use */
|
||||
uint64_t CalculateCurrentUsage()
|
||||
{
|
||||
uint64_t retval = 0;
|
||||
BOOST_FOREACH(const CBlockFileInfo &file, vinfoBlockFile) {
|
||||
retval += file.nSize + file.nUndoSize;
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
/* Prune a block file (modify associated database entries)*/
|
||||
void PruneOneBlockFile(const int fileNumber)
|
||||
{
|
||||
for (BlockMap::iterator it = mapBlockIndex.begin(); it != mapBlockIndex.end(); ++it) {
|
||||
CBlockIndex* pindex = it->second;
|
||||
if (pindex->nFile == fileNumber) {
|
||||
pindex->nStatus &= ~BLOCK_HAVE_DATA;
|
||||
pindex->nStatus &= ~BLOCK_HAVE_UNDO;
|
||||
pindex->nFile = 0;
|
||||
pindex->nDataPos = 0;
|
||||
pindex->nUndoPos = 0;
|
||||
setDirtyBlockIndex.insert(pindex);
|
||||
|
||||
// Prune from mapBlocksUnlinked -- any block we prune would have
|
||||
// to be downloaded again in order to consider its chain, at which
|
||||
// point it would be considered as a candidate for
|
||||
// mapBlocksUnlinked or setBlockIndexCandidates.
|
||||
std::pair<std::multimap<CBlockIndex*, CBlockIndex*>::iterator, std::multimap<CBlockIndex*, CBlockIndex*>::iterator> range = mapBlocksUnlinked.equal_range(pindex->pprev);
|
||||
while (range.first != range.second) {
|
||||
std::multimap<CBlockIndex *, CBlockIndex *>::iterator it = range.first;
|
||||
range.first++;
|
||||
if (it->second == pindex) {
|
||||
mapBlocksUnlinked.erase(it);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
vinfoBlockFile[fileNumber].SetNull();
|
||||
setDirtyFileInfo.insert(fileNumber);
|
||||
}
|
||||
|
||||
|
||||
void UnlinkPrunedFiles(std::set<int>& setFilesToPrune)
|
||||
{
|
||||
for (set<int>::iterator it = setFilesToPrune.begin(); it != setFilesToPrune.end(); ++it) {
|
||||
CDiskBlockPos pos(*it, 0);
|
||||
boost::filesystem::remove(GetBlockPosFilename(pos, "blk"));
|
||||
boost::filesystem::remove(GetBlockPosFilename(pos, "rev"));
|
||||
LogPrintf("Prune: %s deleted blk/rev (%05u)\n", __func__, *it);
|
||||
}
|
||||
}
|
||||
|
||||
/* Calculate the block/rev files that should be deleted to remain under target*/
|
||||
void FindFilesToPrune(std::set<int>& setFilesToPrune)
|
||||
{
|
||||
LOCK2(cs_main, cs_LastBlockFile);
|
||||
if (chainActive.Tip() == NULL || nPruneTarget == 0) {
|
||||
return;
|
||||
}
|
||||
if (chainActive.Tip()->nHeight <= Params().PruneAfterHeight()) {
|
||||
return;
|
||||
}
|
||||
|
||||
unsigned int nLastBlockWeMustKeep = chainActive.Tip()->nHeight - MIN_BLOCKS_TO_KEEP;
|
||||
uint64_t nCurrentUsage = CalculateCurrentUsage();
|
||||
// We don't check to prune until after we've allocated new space for files
|
||||
// So we should leave a buffer under our target to account for another allocation
|
||||
// before the next pruning.
|
||||
uint64_t nBuffer = BLOCKFILE_CHUNK_SIZE + UNDOFILE_CHUNK_SIZE;
|
||||
uint64_t nBytesToPrune;
|
||||
int count=0;
|
||||
|
||||
if (nCurrentUsage + nBuffer >= nPruneTarget) {
|
||||
for (int fileNumber = 0; fileNumber < nLastBlockFile; fileNumber++) {
|
||||
nBytesToPrune = vinfoBlockFile[fileNumber].nSize + vinfoBlockFile[fileNumber].nUndoSize;
|
||||
|
||||
if (vinfoBlockFile[fileNumber].nSize == 0)
|
||||
continue;
|
||||
|
||||
if (nCurrentUsage + nBuffer < nPruneTarget) // are we below our target?
|
||||
break;
|
||||
|
||||
// don't prune files that could have a block within MIN_BLOCKS_TO_KEEP of the main chain's tip
|
||||
if (vinfoBlockFile[fileNumber].nHeightLast > nLastBlockWeMustKeep)
|
||||
break;
|
||||
|
||||
PruneOneBlockFile(fileNumber);
|
||||
// Queue up the files for removal
|
||||
setFilesToPrune.insert(fileNumber);
|
||||
nCurrentUsage -= nBytesToPrune;
|
||||
count++;
|
||||
}
|
||||
}
|
||||
|
||||
LogPrint("prune", "Prune: target=%dMiB actual=%dMiB diff=%dMiB min_must_keep=%d removed %d blk/rev pairs\n",
|
||||
nPruneTarget/1024/1024, nCurrentUsage/1024/1024,
|
||||
((int64_t)nPruneTarget - (int64_t)nCurrentUsage)/1024/1024,
|
||||
nLastBlockWeMustKeep, count);
|
||||
}
|
||||
|
||||
bool CheckDiskSpace(uint64_t nAdditionalBytes)
|
||||
{
|
||||
uint64_t nFreeBytesAvailable = boost::filesystem::space(GetDataDir()).available;
|
||||
|
@ -3016,7 +3190,9 @@ bool static LoadBlockIndexDB()
|
|||
{
|
||||
CBlockIndex* pindex = item.second;
|
||||
pindex->nChainWork = (pindex->pprev ? pindex->pprev->nChainWork : 0) + GetBlockProof(*pindex);
|
||||
if (pindex->nStatus & BLOCK_HAVE_DATA) {
|
||||
// We can link the chain of blocks for which we've received transactions at some point.
|
||||
// Pruned nodes may have deleted the block.
|
||||
if (pindex->nTx > 0) {
|
||||
if (pindex->pprev) {
|
||||
if (pindex->pprev->nChainTx) {
|
||||
pindex->nChainTx = pindex->pprev->nChainTx + pindex->nTx;
|
||||
|
@ -3073,6 +3249,11 @@ bool static LoadBlockIndexDB()
|
|||
}
|
||||
}
|
||||
|
||||
// Check whether we have ever pruned block & undo files
|
||||
pblocktree->ReadFlag("prunedblockfiles", fHavePruned);
|
||||
if (fHavePruned)
|
||||
LogPrintf("LoadBlockIndexDB(): Block files have previously been pruned\n");
|
||||
|
||||
// Check whether we need to continue reindexing
|
||||
bool fReindexing = false;
|
||||
pblocktree->ReadReindexing(fReindexing);
|
||||
|
@ -3080,7 +3261,7 @@ bool static LoadBlockIndexDB()
|
|||
|
||||
// Check whether we have a transaction index
|
||||
pblocktree->ReadFlag("txindex", fTxIndex);
|
||||
LogPrintf("LoadBlockIndexDB(): transaction index %s\n", fTxIndex ? "enabled" : "disabled");
|
||||
LogPrintf("%s: transaction index %s\n", __func__, fTxIndex ? "enabled" : "disabled");
|
||||
|
||||
// Load pointer to end of best chain
|
||||
BlockMap::iterator it = mapBlockIndex.find(pcoinsTip->GetBestBlock());
|
||||
|
@ -3090,7 +3271,7 @@ bool static LoadBlockIndexDB()
|
|||
|
||||
PruneBlockIndexCandidates();
|
||||
|
||||
LogPrintf("LoadBlockIndexDB(): hashBestChain=%s height=%d date=%s progress=%f\n",
|
||||
LogPrintf("%s: hashBestChain=%s height=%d date=%s progress=%f\n", __func__,
|
||||
chainActive.Tip()->GetBlockHash().ToString(), chainActive.Height(),
|
||||
DateTimeStrFormat("%Y-%m-%d %H:%M:%S", chainActive.Tip()->GetBlockTime()),
|
||||
Checkpoints::GuessVerificationProgress(chainActive.Tip()));
|
||||
|
@ -3214,6 +3395,7 @@ void UnloadBlockIndex()
|
|||
delete entry.second;
|
||||
}
|
||||
mapBlockIndex.clear();
|
||||
fHavePruned = false;
|
||||
}
|
||||
|
||||
bool LoadBlockIndex()
|
||||
|
@ -3267,6 +3449,7 @@ bool InitBlockIndex() {
|
|||
|
||||
bool LoadExternalBlockFile(FILE* fileIn, CDiskBlockPos *dbp)
|
||||
{
|
||||
const CChainParams& chainparams = Params();
|
||||
// Map of disk positions for blocks with unknown parent (only used for reindex)
|
||||
static std::multimap<uint256, CDiskBlockPos> mapBlocksUnknownParent;
|
||||
int64_t nStart = GetTimeMillis();
|
||||
|
@ -3312,7 +3495,7 @@ bool LoadExternalBlockFile(FILE* fileIn, CDiskBlockPos *dbp)
|
|||
|
||||
// detect out of order blocks, and store them for later
|
||||
uint256 hash = block.GetHash();
|
||||
if (hash != Params().HashGenesisBlock() && mapBlockIndex.find(block.hashPrevBlock) == mapBlockIndex.end()) {
|
||||
if (hash != chainparams.GetConsensus().hashGenesisBlock && mapBlockIndex.find(block.hashPrevBlock) == mapBlockIndex.end()) {
|
||||
LogPrint("reindex", "%s: Out of order block %s, parent %s not known\n", __func__, hash.ToString(),
|
||||
block.hashPrevBlock.ToString());
|
||||
if (dbp)
|
||||
|
@ -3327,7 +3510,7 @@ bool LoadExternalBlockFile(FILE* fileIn, CDiskBlockPos *dbp)
|
|||
nLoaded++;
|
||||
if (state.IsError())
|
||||
break;
|
||||
} else if (hash != Params().HashGenesisBlock() && mapBlockIndex[hash]->nHeight % 1000 == 0) {
|
||||
} else if (hash != chainparams.GetConsensus().hashGenesisBlock && mapBlockIndex[hash]->nHeight % 1000 == 0) {
|
||||
LogPrintf("Block Import: already had block %s at height %d\n", hash.ToString(), mapBlockIndex[hash]->nHeight);
|
||||
}
|
||||
|
||||
|
@ -3369,12 +3552,21 @@ bool LoadExternalBlockFile(FILE* fileIn, CDiskBlockPos *dbp)
|
|||
|
||||
void static CheckBlockIndex()
|
||||
{
|
||||
const Consensus::Params& consensusParams = Params().GetConsensus();
|
||||
if (!fCheckBlockIndex) {
|
||||
return;
|
||||
}
|
||||
|
||||
LOCK(cs_main);
|
||||
|
||||
// During a reindex, we read the genesis block and call CheckBlockIndex before ActivateBestChain,
|
||||
// so we have the genesis block in mapBlockIndex but no active chain. (A few of the tests when
|
||||
// iterating the block tree require that chainActive has been initialized.)
|
||||
if (chainActive.Height() < 0) {
|
||||
assert(mapBlockIndex.size() <= 1);
|
||||
return;
|
||||
}
|
||||
|
||||
// Build forward-pointing map of the entire block tree.
|
||||
std::multimap<CBlockIndex*,CBlockIndex*> forward;
|
||||
for (BlockMap::iterator it = mapBlockIndex.begin(); it != mapBlockIndex.end(); it++) {
|
||||
|
@ -3395,6 +3587,7 @@ void static CheckBlockIndex()
|
|||
int nHeight = 0;
|
||||
CBlockIndex* pindexFirstInvalid = NULL; // Oldest ancestor of pindex which is invalid.
|
||||
CBlockIndex* pindexFirstMissing = NULL; // Oldest ancestor of pindex which does not have BLOCK_HAVE_DATA.
|
||||
CBlockIndex* pindexFirstNeverProcessed = NULL; // Oldest ancestor of pindex for which nTx == 0.
|
||||
CBlockIndex* pindexFirstNotTreeValid = NULL; // Oldest ancestor of pindex which does not have BLOCK_VALID_TREE (regardless of being valid or not).
|
||||
CBlockIndex* pindexFirstNotTransactionsValid = NULL; // Oldest ancestor of pindex which does not have BLOCK_VALID_TRANSACTIONS (regardless of being valid or not).
|
||||
CBlockIndex* pindexFirstNotChainValid = NULL; // Oldest ancestor of pindex which does not have BLOCK_VALID_CHAIN (regardless of being valid or not).
|
||||
|
@ -3403,6 +3596,7 @@ void static CheckBlockIndex()
|
|||
nNodes++;
|
||||
if (pindexFirstInvalid == NULL && pindex->nStatus & BLOCK_FAILED_VALID) pindexFirstInvalid = pindex;
|
||||
if (pindexFirstMissing == NULL && !(pindex->nStatus & BLOCK_HAVE_DATA)) pindexFirstMissing = pindex;
|
||||
if (pindexFirstNeverProcessed == NULL && pindex->nTx == 0) pindexFirstNeverProcessed = pindex;
|
||||
if (pindex->pprev != NULL && pindexFirstNotTreeValid == NULL && (pindex->nStatus & BLOCK_VALID_MASK) < BLOCK_VALID_TREE) pindexFirstNotTreeValid = pindex;
|
||||
if (pindex->pprev != NULL && pindexFirstNotTransactionsValid == NULL && (pindex->nStatus & BLOCK_VALID_MASK) < BLOCK_VALID_TRANSACTIONS) pindexFirstNotTransactionsValid = pindex;
|
||||
if (pindex->pprev != NULL && pindexFirstNotChainValid == NULL && (pindex->nStatus & BLOCK_VALID_MASK) < BLOCK_VALID_CHAIN) pindexFirstNotChainValid = pindex;
|
||||
|
@ -3411,14 +3605,24 @@ void static CheckBlockIndex()
|
|||
// Begin: actual consistency checks.
|
||||
if (pindex->pprev == NULL) {
|
||||
// Genesis block checks.
|
||||
assert(pindex->GetBlockHash() == Params().HashGenesisBlock()); // Genesis block's hash must match.
|
||||
assert(pindex->GetBlockHash() == consensusParams.hashGenesisBlock); // Genesis block's hash must match.
|
||||
assert(pindex == chainActive.Genesis()); // The current active chain's genesis block must be this block.
|
||||
}
|
||||
// HAVE_DATA is equivalent to VALID_TRANSACTIONS and equivalent to nTx > 0 (we stored the number of transactions in the block)
|
||||
assert(!(pindex->nStatus & BLOCK_HAVE_DATA) == (pindex->nTx == 0));
|
||||
assert(((pindex->nStatus & BLOCK_VALID_MASK) >= BLOCK_VALID_TRANSACTIONS) == (pindex->nTx > 0));
|
||||
// All parents having data is equivalent to all parents being VALID_TRANSACTIONS, which is equivalent to nChainTx being set.
|
||||
assert((pindexFirstMissing != NULL) == (pindex->nChainTx == 0)); // nChainTx == 0 is used to signal that all parent block's transaction data is available.
|
||||
if (pindex->nChainTx == 0) assert(pindex->nSequenceId == 0); // nSequenceId can't be set for blocks that aren't linked
|
||||
// VALID_TRANSACTIONS is equivalent to nTx > 0 for all nodes (whether or not pruning has occurred).
|
||||
// HAVE_DATA is only equivalent to nTx > 0 (or VALID_TRANSACTIONS) if no pruning has occurred.
|
||||
if (!fHavePruned) {
|
||||
// If we've never pruned, then HAVE_DATA should be equivalent to nTx > 0
|
||||
assert(!(pindex->nStatus & BLOCK_HAVE_DATA) == (pindex->nTx == 0));
|
||||
assert(pindexFirstMissing == pindexFirstNeverProcessed);
|
||||
} else {
|
||||
// If we have pruned, then we can only say that HAVE_DATA implies nTx > 0
|
||||
if (pindex->nStatus & BLOCK_HAVE_DATA) assert(pindex->nTx > 0);
|
||||
}
|
||||
if (pindex->nStatus & BLOCK_HAVE_UNDO) assert(pindex->nStatus & BLOCK_HAVE_DATA);
|
||||
assert(((pindex->nStatus & BLOCK_VALID_MASK) >= BLOCK_VALID_TRANSACTIONS) == (pindex->nTx > 0)); // This is pruning-independent.
|
||||
// All parents having had data (at some point) is equivalent to all parents being VALID_TRANSACTIONS, which is equivalent to nChainTx being set.
|
||||
assert((pindexFirstNeverProcessed != NULL) == (pindex->nChainTx == 0)); // nChainTx != 0 is used to signal that all parent blocks have been processed (but may have been pruned).
|
||||
assert((pindexFirstNotTransactionsValid != NULL) == (pindex->nChainTx == 0));
|
||||
assert(pindex->nHeight == nHeight); // nHeight must be consistent.
|
||||
assert(pindex->pprev == NULL || pindex->nChainWork >= pindex->pprev->nChainWork); // For every block except the genesis block, the chainwork must be larger than the parent's.
|
||||
|
@ -3431,11 +3635,20 @@ void static CheckBlockIndex()
|
|||
// Checks for not-invalid blocks.
|
||||
assert((pindex->nStatus & BLOCK_FAILED_MASK) == 0); // The failed mask cannot be set for blocks without invalid parents.
|
||||
}
|
||||
if (!CBlockIndexWorkComparator()(pindex, chainActive.Tip()) && pindexFirstMissing == NULL) {
|
||||
if (pindexFirstInvalid == NULL) { // If this block sorts at least as good as the current tip and is valid, it must be in setBlockIndexCandidates.
|
||||
assert(setBlockIndexCandidates.count(pindex));
|
||||
if (!CBlockIndexWorkComparator()(pindex, chainActive.Tip()) && pindexFirstNeverProcessed == NULL) {
|
||||
if (pindexFirstInvalid == NULL) {
|
||||
// If this block sorts at least as good as the current tip and
|
||||
// is valid and we have all data for its parents, it must be in
|
||||
// setBlockIndexCandidates. chainActive.Tip() must also be there
|
||||
// even if some data has been pruned.
|
||||
if (pindexFirstMissing == NULL || pindex == chainActive.Tip()) {
|
||||
assert(setBlockIndexCandidates.count(pindex));
|
||||
}
|
||||
// If some parent is missing, then it could be that this block was in
|
||||
// setBlockIndexCandidates but had to be removed because of the missing data.
|
||||
// In this case it must be in mapBlocksUnlinked -- see test below.
|
||||
}
|
||||
} else { // If this block sorts worse than the current tip, it cannot be in setBlockIndexCandidates.
|
||||
} else { // If this block sorts worse than the current tip or some ancestor's block has never been seen, it cannot be in setBlockIndexCandidates.
|
||||
assert(setBlockIndexCandidates.count(pindex) == 0);
|
||||
}
|
||||
// Check whether this block is in mapBlocksUnlinked.
|
||||
|
@ -3449,12 +3662,28 @@ void static CheckBlockIndex()
|
|||
}
|
||||
rangeUnlinked.first++;
|
||||
}
|
||||
if (pindex->pprev && pindex->nStatus & BLOCK_HAVE_DATA && pindexFirstMissing != NULL) {
|
||||
if (pindexFirstInvalid == NULL) { // If this block has block data available, some parent doesn't, and has no invalid parents, it must be in mapBlocksUnlinked.
|
||||
assert(foundInUnlinked);
|
||||
if (pindex->pprev && (pindex->nStatus & BLOCK_HAVE_DATA) && pindexFirstNeverProcessed != NULL && pindexFirstInvalid == NULL) {
|
||||
// If this block has block data available, some parent was never received, and has no invalid parents, it must be in mapBlocksUnlinked.
|
||||
assert(foundInUnlinked);
|
||||
}
|
||||
if (!(pindex->nStatus & BLOCK_HAVE_DATA)) assert(!foundInUnlinked); // Can't be in mapBlocksUnlinked if we don't HAVE_DATA
|
||||
if (pindexFirstMissing == NULL) assert(!foundInUnlinked); // We aren't missing data for any parent -- cannot be in mapBlocksUnlinked.
|
||||
if (pindex->pprev && (pindex->nStatus & BLOCK_HAVE_DATA) && pindexFirstNeverProcessed == NULL && pindexFirstMissing != NULL) {
|
||||
// We HAVE_DATA for this block, have received data for all parents at some point, but we're currently missing data for some parent.
|
||||
assert(fHavePruned); // We must have pruned.
|
||||
// This block may have entered mapBlocksUnlinked if:
|
||||
// - it has a descendant that at some point had more work than the
|
||||
// tip, and
|
||||
// - we tried switching to that descendant but were missing
|
||||
// data for some intermediate block between chainActive and the
|
||||
// tip.
|
||||
// So if this block is itself better than chainActive.Tip() and it wasn't in
|
||||
// setBlockIndexCandidates, then it must be in mapBlocksUnlinked.
|
||||
if (!CBlockIndexWorkComparator()(pindex, chainActive.Tip()) && setBlockIndexCandidates.count(pindex) == 0) {
|
||||
if (pindexFirstInvalid == NULL) {
|
||||
assert(foundInUnlinked);
|
||||
}
|
||||
}
|
||||
} else { // If this block does not have block data available, or all parents do, it cannot be in mapBlocksUnlinked.
|
||||
assert(!foundInUnlinked);
|
||||
}
|
||||
// assert(pindex->GetBlockHash() == pindex->GetBlockHeader().GetHash()); // Perhaps too slow
|
||||
// End: actual consistency checks.
|
||||
|
@ -3474,6 +3703,7 @@ void static CheckBlockIndex()
|
|||
// If pindex was the first with a certain property, unset the corresponding variable.
|
||||
if (pindex == pindexFirstInvalid) pindexFirstInvalid = NULL;
|
||||
if (pindex == pindexFirstMissing) pindexFirstMissing = NULL;
|
||||
if (pindex == pindexFirstNeverProcessed) pindexFirstNeverProcessed = NULL;
|
||||
if (pindex == pindexFirstNotTreeValid) pindexFirstNotTreeValid = NULL;
|
||||
if (pindex == pindexFirstNotTransactionsValid) pindexFirstNotTransactionsValid = NULL;
|
||||
if (pindex == pindexFirstNotChainValid) pindexFirstNotChainValid = NULL;
|
||||
|
@ -3593,7 +3823,6 @@ bool static AlreadyHave(const CInv& inv)
|
|||
return true;
|
||||
}
|
||||
|
||||
|
||||
void static ProcessGetData(CNode* pfrom)
|
||||
{
|
||||
std::deque<CInv>::iterator it = pfrom->vRecvGetData.begin();
|
||||
|
@ -3621,17 +3850,21 @@ void static ProcessGetData(CNode* pfrom)
|
|||
if (chainActive.Contains(mi->second)) {
|
||||
send = true;
|
||||
} else {
|
||||
static const int nOneMonth = 30 * 24 * 60 * 60;
|
||||
// To prevent fingerprinting attacks, only send blocks outside of the active
|
||||
// chain if they are valid, and no more than a month older than the best header
|
||||
// chain we know about.
|
||||
// chain if they are valid, and no more than a month older (both in time, and in
|
||||
// best equivalent proof of work) than the best header chain we know about.
|
||||
send = mi->second->IsValid(BLOCK_VALID_SCRIPTS) && (pindexBestHeader != NULL) &&
|
||||
(mi->second->GetBlockTime() > pindexBestHeader->GetBlockTime() - 30 * 24 * 60 * 60);
|
||||
(pindexBestHeader->GetBlockTime() - mi->second->GetBlockTime() < nOneMonth) &&
|
||||
(GetBlockProofEquivalentTime(*pindexBestHeader, *mi->second, *pindexBestHeader, Params().GetConsensus()) < nOneMonth);
|
||||
if (!send) {
|
||||
LogPrintf("ProcessGetData(): ignoring request from peer=%i for old block that isn't in the main chain\n", pfrom->GetId());
|
||||
LogPrintf("%s: ignoring request from peer=%i for old block that isn't in the main chain\n", __func__, pfrom->GetId());
|
||||
}
|
||||
}
|
||||
}
|
||||
if (send)
|
||||
// Pruned nodes may have deleted the block, so check whether
|
||||
// it's available before trying to send.
|
||||
if (send && (mi->second->nStatus & BLOCK_HAVE_DATA))
|
||||
{
|
||||
// Send block from disk
|
||||
CBlock block;
|
||||
|
@ -3725,6 +3958,7 @@ void static ProcessGetData(CNode* pfrom)
|
|||
|
||||
bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, int64_t nTimeReceived)
|
||||
{
|
||||
const CChainParams& chainparams = Params();
|
||||
RandAddSeedPerfmon();
|
||||
LogPrint("net", "received: %s (%u bytes) peer=%d\n", SanitizeString(strCommand), vRecv.size(), pfrom->id);
|
||||
if (mapArgs.count("-dropmessagestest") && GetRand(atoi(mapArgs["-dropmessagestest"])) == 0)
|
||||
|
@ -3984,7 +4218,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
|
|||
// not a direct successor.
|
||||
pfrom->PushMessage("getheaders", chainActive.GetLocator(pindexBestHeader), inv.hash);
|
||||
CNodeState *nodestate = State(pfrom->GetId());
|
||||
if (chainActive.Tip()->GetBlockTime() > GetAdjustedTime() - Params().TargetSpacing() * 20 &&
|
||||
if (chainActive.Tip()->GetBlockTime() > GetAdjustedTime() - chainparams.GetConsensus().nPowTargetSpacing * 20 &&
|
||||
nodestate->nBlocksInFlight < MAX_BLOCKS_IN_TRANSIT_PER_PEER) {
|
||||
vToFetch.push_back(inv);
|
||||
// Mark block as in flight already, even though the actual "getdata" message only goes out
|
||||
|
@ -4528,7 +4762,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
|
|||
bool ProcessMessages(CNode* pfrom)
|
||||
{
|
||||
//if (fDebug)
|
||||
// LogPrintf("ProcessMessages(%u messages)\n", pfrom->vRecvMsg.size());
|
||||
// LogPrintf("%s(%u messages)\n", __func__, pfrom->vRecvMsg.size());
|
||||
|
||||
//
|
||||
// Message format
|
||||
|
@ -4556,7 +4790,7 @@ bool ProcessMessages(CNode* pfrom)
|
|||
CNetMessage& msg = *it;
|
||||
|
||||
//if (fDebug)
|
||||
// LogPrintf("ProcessMessages(message %u msgsz, %u bytes, complete:%s)\n",
|
||||
// LogPrintf("%s(message %u msgsz, %u bytes, complete:%s)\n", __func__,
|
||||
// msg.hdr.nMessageSize, msg.vRecv.size(),
|
||||
// msg.complete() ? "Y" : "N");
|
||||
|
||||
|
@ -4592,7 +4826,7 @@ bool ProcessMessages(CNode* pfrom)
|
|||
unsigned int nChecksum = ReadLE32((unsigned char*)&hash);
|
||||
if (nChecksum != hdr.nChecksum)
|
||||
{
|
||||
LogPrintf("ProcessMessages(%s, %u bytes): CHECKSUM ERROR nChecksum=%08x hdr.nChecksum=%08x\n",
|
||||
LogPrintf("%s(%s, %u bytes): CHECKSUM ERROR nChecksum=%08x hdr.nChecksum=%08x\n", __func__,
|
||||
SanitizeString(strCommand), nMessageSize, nChecksum, hdr.nChecksum);
|
||||
continue;
|
||||
}
|
||||
|
@ -4610,12 +4844,12 @@ bool ProcessMessages(CNode* pfrom)
|
|||
if (strstr(e.what(), "end of data"))
|
||||
{
|
||||
// Allow exceptions from under-length message on vRecv
|
||||
LogPrintf("ProcessMessages(%s, %u bytes): Exception '%s' caught, normally caused by a message being shorter than its stated length\n", SanitizeString(strCommand), nMessageSize, e.what());
|
||||
LogPrintf("%s(%s, %u bytes): Exception '%s' caught, normally caused by a message being shorter than its stated length\n", __func__, SanitizeString(strCommand), nMessageSize, e.what());
|
||||
}
|
||||
else if (strstr(e.what(), "size too large"))
|
||||
{
|
||||
// Allow exceptions from over-long size
|
||||
LogPrintf("ProcessMessages(%s, %u bytes): Exception '%s' caught\n", SanitizeString(strCommand), nMessageSize, e.what());
|
||||
LogPrintf("%s(%s, %u bytes): Exception '%s' caught\n", __func__, SanitizeString(strCommand), nMessageSize, e.what());
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -4632,7 +4866,7 @@ bool ProcessMessages(CNode* pfrom)
|
|||
}
|
||||
|
||||
if (!fRet)
|
||||
LogPrintf("ProcessMessage(%s, %u bytes) FAILED peer=%d\n", SanitizeString(strCommand), nMessageSize, pfrom->id);
|
||||
LogPrintf("%s(%s, %u bytes) FAILED peer=%d\n", __func__, SanitizeString(strCommand), nMessageSize, pfrom->id);
|
||||
|
||||
break;
|
||||
}
|
||||
|
@ -4647,6 +4881,7 @@ bool ProcessMessages(CNode* pfrom)
|
|||
|
||||
bool SendMessages(CNode* pto, bool fSendTrickle)
|
||||
{
|
||||
const Consensus::Params& consensusParams = Params().GetConsensus();
|
||||
{
|
||||
// Don't send anything until we get their version message
|
||||
if (pto->nVersion == 0)
|
||||
|
@ -4753,9 +4988,9 @@ bool SendMessages(CNode* pto, bool fSendTrickle)
|
|||
if (pindexBestHeader == NULL)
|
||||
pindexBestHeader = chainActive.Tip();
|
||||
bool fFetch = state.fPreferredDownload || (nPreferredDownload == 0 && !pto->fClient && !pto->fOneShot); // Download if this is a nice peer, or we have no nice peers and this one might do.
|
||||
if (!state.fSyncStarted && !pto->fClient && fFetch && !fImporting && !fReindex) {
|
||||
if (!state.fSyncStarted && !pto->fClient && !fImporting && !fReindex) {
|
||||
// Only actively request headers from a single peer, unless we're close to today.
|
||||
if (nSyncStarted == 0 || pindexBestHeader->GetBlockTime() > GetAdjustedTime() - 24 * 60 * 60) {
|
||||
if ((nSyncStarted == 0 && fFetch) || pindexBestHeader->GetBlockTime() > GetAdjustedTime() - 24 * 60 * 60) {
|
||||
state.fSyncStarted = true;
|
||||
nSyncStarted++;
|
||||
CBlockIndex *pindexStart = pindexBestHeader->pprev ? pindexBestHeader->pprev : pindexBestHeader;
|
||||
|
@ -4834,7 +5069,7 @@ bool SendMessages(CNode* pto, bool fSendTrickle)
|
|||
// timeout. We compensate for in-flight blocks to prevent killing off peers due to our own downstream link
|
||||
// being saturated. We only count validated in-flight blocks so peers can't advertize nonexisting block hashes
|
||||
// to unreasonably increase our timeout.
|
||||
if (!pto->fDisconnect && state.vBlocksInFlight.size() > 0 && state.vBlocksInFlight.front().nTime < nNow - 500000 * Params().TargetSpacing() * (4 + state.vBlocksInFlight.front().nValidatedQueuedBefore)) {
|
||||
if (!pto->fDisconnect && state.vBlocksInFlight.size() > 0 && state.vBlocksInFlight.front().nTime < nNow - 500000 * consensusParams.nPowTargetSpacing * (4 + state.vBlocksInFlight.front().nValidatedQueuedBefore)) {
|
||||
LogPrintf("Timeout downloading block %s from peer=%d, disconnecting\n", state.vBlocksInFlight.front().hash.ToString(), pto->id);
|
||||
pto->fDisconnect = true;
|
||||
}
|
||||
|
@ -4843,7 +5078,7 @@ bool SendMessages(CNode* pto, bool fSendTrickle)
|
|||
// Message: getdata (blocks)
|
||||
//
|
||||
vector<CInv> vGetData;
|
||||
if (!pto->fDisconnect && !pto->fClient && fFetch && state.nBlocksInFlight < MAX_BLOCKS_IN_TRANSIT_PER_PEER) {
|
||||
if (!pto->fDisconnect && !pto->fClient && (fFetch || !IsInitialBlockDownload()) && state.nBlocksInFlight < MAX_BLOCKS_IN_TRANSIT_PER_PEER) {
|
||||
vector<CBlockIndex*> vToDownload;
|
||||
NodeId staller = -1;
|
||||
FindNextBlocksToDownload(pto->GetId(), MAX_BLOCKS_IN_TRANSIT_PER_PEER - state.nBlocksInFlight, vToDownload, staller);
|
||||
|
|
54
src/main.h
54
src/main.h
|
@ -14,10 +14,11 @@
|
|||
#include "chain.h"
|
||||
#include "chainparams.h"
|
||||
#include "coins.h"
|
||||
#include "consensus/consensus.h"
|
||||
#include "net.h"
|
||||
#include "primitives/block.h"
|
||||
#include "primitives/transaction.h"
|
||||
#include "ncctrie.h"
|
||||
#include "net.h"
|
||||
#include "script/script.h"
|
||||
#include "script/sigcache.h"
|
||||
#include "script/standard.h"
|
||||
|
@ -54,8 +55,6 @@ static const unsigned int DEFAULT_BLOCK_MIN_SIZE = 0;
|
|||
static const unsigned int DEFAULT_BLOCK_PRIORITY_SIZE = 50000;
|
||||
/** The maximum size for transactions we're willing to relay/mine */
|
||||
static const unsigned int MAX_STANDARD_TX_SIZE = 100000;
|
||||
/** The maximum allowed number of signature check operations in a block (network rule) */
|
||||
static const unsigned int MAX_BLOCK_SIGOPS = MAX_BLOCK_SIZE/50;
|
||||
/** Maximum number of signature check operations in an IsStandard() P2SH script */
|
||||
static const unsigned int MAX_P2SH_SIGOPS = 15;
|
||||
/** The maximum number of sigops we're willing to relay/mine in a single tx */
|
||||
|
@ -68,10 +67,6 @@ static const unsigned int MAX_BLOCKFILE_SIZE = 0x8000000; // 128 MiB
|
|||
static const unsigned int BLOCKFILE_CHUNK_SIZE = 0x1000000; // 16 MiB
|
||||
/** The pre-allocation chunk size for rev?????.dat files (since 0.8) */
|
||||
static const unsigned int UNDOFILE_CHUNK_SIZE = 0x100000; // 1 MiB
|
||||
/** Coinbase transaction outputs can only be spent after this number of new blocks (network rule) */
|
||||
static const int COINBASE_MATURITY = 100;
|
||||
/** Threshold for nLockTime: below this value it is interpreted as block number, otherwise as UNIX timestamp. */
|
||||
static const unsigned int LOCKTIME_THRESHOLD = 500000000; // Tue Nov 5 00:53:20 1985 UTC
|
||||
/** Maximum number of script-checking threads allowed */
|
||||
static const int MAX_SCRIPTCHECK_THREADS = 16;
|
||||
/** -par default (number of script-checking threads, 0 = auto) */
|
||||
|
@ -133,6 +128,26 @@ extern CBlockIndex *pindexBestHeader;
|
|||
/** Minimum disk space required - used in CheckDiskSpace() */
|
||||
static const uint64_t nMinDiskSpace = 52428800;
|
||||
|
||||
/** Pruning-related variables and constants */
|
||||
/** True if any block files have ever been pruned. */
|
||||
extern bool fHavePruned;
|
||||
/** True if we're running in -prune mode. */
|
||||
extern bool fPruneMode;
|
||||
/** Number of MiB of block files that we're trying to stay below. */
|
||||
extern uint64_t nPruneTarget;
|
||||
/** Block files containing a block-height within MIN_BLOCKS_TO_KEEP of chainActive.Tip() will not be pruned. */
|
||||
static const signed int MIN_BLOCKS_TO_KEEP = 288;
|
||||
|
||||
// Require that user allocate at least 550MB for block & undo files (blk???.dat and rev???.dat)
|
||||
// At 1MB per block, 288 blocks = 288MB.
|
||||
// Add 15% for Undo data = 331MB
|
||||
// Add 20% for Orphan block rate = 397MB
|
||||
// We want the low water mark after pruning to be at least 397 MB and since we prune in
|
||||
// full block file chunks, we need the high water mark which triggers the prune to be
|
||||
// one 128MB block file + added 15% undo data = 147MB greater for a total of 545MB
|
||||
// Setting the target to > than 550MB will make it likely we can respect the target.
|
||||
static const signed int MIN_DISK_SPACE_FOR_BLOCK_FILES = 550 * 1024 * 1024;
|
||||
|
||||
/** Register with a network node to receive its signals */
|
||||
void RegisterNodeSignals(CNodeSignals& nodeSignals);
|
||||
/** Unregister a network node */
|
||||
|
@ -187,6 +202,28 @@ bool GetTransaction(const uint256 &hash, CTransaction &tx, uint256 &hashBlock, b
|
|||
bool ActivateBestChain(CValidationState &state, CBlock *pblock = NULL);
|
||||
CAmount GetBlockValue(int nHeight, const CAmount& nFees);
|
||||
|
||||
/**
|
||||
* Prune block and undo files (blk???.dat and undo???.dat) so that the disk space used is less than a user-defined target.
|
||||
* The user sets the target (in MB) on the command line or in config file. This will be run on startup and whenever new
|
||||
* space is allocated in a block or undo file, staying below the target. Changing back to unpruned requires a reindex
|
||||
* (which in this case means the blockchain must be re-downloaded.)
|
||||
*
|
||||
* Pruning functions are called from FlushStateToDisk when the global fCheckForPruning flag has been set.
|
||||
* Block and undo files are deleted in lock-step (when blk00003.dat is deleted, so is rev00003.dat.)
|
||||
* Pruning cannot take place until the longest chain is at least a certain length (100000 on mainnet, 1000 on testnet, 10 on regtest).
|
||||
* Pruning will never delete a block within a defined distance (currently 288) from the active chain's tip.
|
||||
* The block index is updated by unsetting HAVE_DATA and HAVE_UNDO for any blocks that were stored in the deleted files.
|
||||
* A db flag records the fact that at least some block files have been pruned.
|
||||
*
|
||||
* @param[out] setFilesToPrune The set of file indices that can be unlinked will be returned
|
||||
*/
|
||||
void FindFilesToPrune(std::set<int>& setFilesToPrune);
|
||||
|
||||
/**
|
||||
* Actually unlink the specified files
|
||||
*/
|
||||
void UnlinkPrunedFiles(std::set<int>& setFilesToPrune);
|
||||
|
||||
/** Create a new block index entry for a given block hash */
|
||||
CBlockIndex * InsertBlockIndex(uint256 hash);
|
||||
/** Abort with a message */
|
||||
|
@ -197,7 +234,8 @@ bool GetNodeStateStats(NodeId nodeid, CNodeStateStats &stats);
|
|||
void Misbehaving(NodeId nodeid, int howmuch);
|
||||
/** Flush all state, indexes and buffers to disk. */
|
||||
void FlushStateToDisk();
|
||||
|
||||
/** Prune block files and flush state to disk. */
|
||||
void PruneAndFlush();
|
||||
|
||||
/** (try to) add transaction to memory pool **/
|
||||
bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransaction &tx, bool fLimitFree,
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
#include "merkleblock.h"
|
||||
|
||||
#include "hash.h"
|
||||
#include "primitives/block.h" // for MAX_BLOCK_SIZE
|
||||
#include "consensus/consensus.h"
|
||||
#include "utilstrencodings.h"
|
||||
|
||||
using namespace std;
|
||||
|
@ -37,6 +37,29 @@ CMerkleBlock::CMerkleBlock(const CBlock& block, CBloomFilter& filter)
|
|||
txn = CPartialMerkleTree(vHashes, vMatch);
|
||||
}
|
||||
|
||||
CMerkleBlock::CMerkleBlock(const CBlock& block, const std::set<uint256>& txids)
|
||||
{
|
||||
header = block.GetBlockHeader();
|
||||
|
||||
vector<bool> vMatch;
|
||||
vector<uint256> vHashes;
|
||||
|
||||
vMatch.reserve(block.vtx.size());
|
||||
vHashes.reserve(block.vtx.size());
|
||||
|
||||
for (unsigned int i = 0; i < block.vtx.size(); i++)
|
||||
{
|
||||
const uint256& hash = block.vtx[i].GetHash();
|
||||
if (txids.count(hash))
|
||||
vMatch.push_back(true);
|
||||
else
|
||||
vMatch.push_back(false);
|
||||
vHashes.push_back(hash);
|
||||
}
|
||||
|
||||
txn = CPartialMerkleTree(vHashes, vMatch);
|
||||
}
|
||||
|
||||
uint256 CPartialMerkleTree::CalcHash(int height, unsigned int pos, const std::vector<uint256> &vTxid) {
|
||||
if (height == 0) {
|
||||
// hash at height 0 is the txids themself
|
||||
|
|
|
@ -139,6 +139,11 @@ public:
|
|||
*/
|
||||
CMerkleBlock(const CBlock& block, CBloomFilter& filter);
|
||||
|
||||
// Create from a CBlock, matching the txids in the set
|
||||
CMerkleBlock(const CBlock& block, const std::set<uint256>& txids);
|
||||
|
||||
CMerkleBlock() {}
|
||||
|
||||
ADD_SERIALIZE_METHODS;
|
||||
|
||||
template <typename Stream, typename Operation>
|
||||
|
|
|
@ -6,13 +6,15 @@
|
|||
#include "miner.h"
|
||||
|
||||
#include "amount.h"
|
||||
#include "primitives/transaction.h"
|
||||
#include "chainparams.h"
|
||||
#include "consensus/consensus.h"
|
||||
#include "hash.h"
|
||||
#include "main.h"
|
||||
#include "ncc.h"
|
||||
#include "ncctrie.h"
|
||||
#include "net.h"
|
||||
#include "pow.h"
|
||||
#include "primitives/transaction.h"
|
||||
#include "timedata.h"
|
||||
#include "util.h"
|
||||
#include "utilmoneystr.h"
|
||||
|
@ -80,13 +82,13 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
void UpdateTime(CBlockHeader* pblock, const CBlockIndex* pindexPrev)
|
||||
void UpdateTime(CBlockHeader* pblock, const Consensus::Params& consensusParams, const CBlockIndex* pindexPrev)
|
||||
{
|
||||
pblock->nTime = std::max(pindexPrev->GetMedianTimePast()+1, GetAdjustedTime());
|
||||
|
||||
// Updating time can change work required on testnet:
|
||||
if (Params().AllowMinDifficultyBlocks())
|
||||
pblock->nBits = GetNextWorkRequired(pindexPrev, pblock, Params().GetConsensus());
|
||||
if (consensusParams.fPowAllowMinDifficultyBlocks)
|
||||
pblock->nBits = GetNextWorkRequired(pindexPrev, pblock, consensusParams);
|
||||
}
|
||||
|
||||
CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn)
|
||||
|
@ -387,7 +389,7 @@ CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn)
|
|||
|
||||
// Fill in header
|
||||
pblock->hashPrevBlock = pindexPrev->GetBlockHash();
|
||||
UpdateTime(pblock, pindexPrev);
|
||||
UpdateTime(pblock, Params().GetConsensus(), pindexPrev);
|
||||
pblock->nBits = GetNextWorkRequired(pindexPrev, pblock, Params().GetConsensus());
|
||||
pblock->nNonce = 0;
|
||||
pblocktemplate->vTxSigOps[0] = GetLegacySigOpCount(pblock->vtx[0]);
|
||||
|
@ -505,6 +507,7 @@ void static BitcoinMiner(CWallet *pwallet)
|
|||
LogPrintf("BitcoinMiner started\n");
|
||||
SetThreadPriority(THREAD_PRIORITY_LOWEST);
|
||||
RenameThread("bitcoin-miner");
|
||||
const CChainParams& chainparams = Params();
|
||||
|
||||
// Each thread has its own key and counter
|
||||
CReserveKey reservekey(pwallet);
|
||||
|
@ -512,7 +515,7 @@ void static BitcoinMiner(CWallet *pwallet)
|
|||
|
||||
try {
|
||||
while (true) {
|
||||
if (Params().MiningRequiresPeers()) {
|
||||
if (chainparams.MiningRequiresPeers()) {
|
||||
// Busy-wait for the network to come online so we don't waste time mining
|
||||
// on an obsolete chain. In regtest mode we expect to fly solo.
|
||||
while (vNodes.empty())
|
||||
|
@ -561,7 +564,7 @@ void static BitcoinMiner(CWallet *pwallet)
|
|||
SetThreadPriority(THREAD_PRIORITY_LOWEST);
|
||||
|
||||
// In regression test mode, stop mining after a block is found.
|
||||
if (Params().MineBlocksOnDemand())
|
||||
if (chainparams.MineBlocksOnDemand())
|
||||
throw boost::thread_interrupted();
|
||||
|
||||
break;
|
||||
|
@ -571,7 +574,7 @@ void static BitcoinMiner(CWallet *pwallet)
|
|||
// Check for stop or if block needs to be rebuilt
|
||||
boost::this_thread::interruption_point();
|
||||
// Regtest mode doesn't require peers
|
||||
if (vNodes.empty() && Params().MiningRequiresPeers())
|
||||
if (vNodes.empty() && chainparams.MiningRequiresPeers())
|
||||
break;
|
||||
if (nNonce >= 0xffff0000)
|
||||
break;
|
||||
|
@ -581,8 +584,8 @@ void static BitcoinMiner(CWallet *pwallet)
|
|||
break;
|
||||
|
||||
// Update nTime every few seconds
|
||||
UpdateTime(pblock, pindexPrev);
|
||||
if (Params().AllowMinDifficultyBlocks())
|
||||
UpdateTime(pblock, chainparams.GetConsensus(), pindexPrev);
|
||||
if (chainparams.GetConsensus().fPowAllowMinDifficultyBlocks)
|
||||
{
|
||||
// Changing pblock->nTime can change work required on testnet:
|
||||
hashTarget.SetCompact(pblock->nBits);
|
||||
|
|
|
@ -14,6 +14,7 @@ class CBlockIndex;
|
|||
class CReserveKey;
|
||||
class CScript;
|
||||
class CWallet;
|
||||
namespace Consensus { struct Params; };
|
||||
|
||||
struct CBlockTemplate
|
||||
{
|
||||
|
@ -29,6 +30,6 @@ CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn);
|
|||
CBlockTemplate* CreateNewBlockWithKey(CReserveKey& reservekey);
|
||||
/** Modify the extranonce in a block */
|
||||
void IncrementExtraNonce(CBlock* pblock, CBlockIndex* pindexPrev, unsigned int& nExtraNonce);
|
||||
void UpdateTime(CBlockHeader* block, const CBlockIndex* pindexPrev);
|
||||
void UpdateTime(CBlockHeader* pblock, const Consensus::Params& consensusParams, const CBlockIndex* pindexPrev);
|
||||
|
||||
#endif // BITCOIN_MINER_H
|
||||
|
|
35
src/net.cpp
35
src/net.cpp
|
@ -100,6 +100,7 @@ NodeId nLastNodeId = 0;
|
|||
CCriticalSection cs_nLastNodeId;
|
||||
|
||||
static CSemaphore *semOutbound = NULL;
|
||||
boost::condition_variable messageHandlerCondition;
|
||||
|
||||
// Signals for message handling
|
||||
static CNodeSignals g_signals;
|
||||
|
@ -141,6 +142,27 @@ bool GetLocal(CService& addr, const CNetAddr *paddrPeer)
|
|||
return nBestScore >= 0;
|
||||
}
|
||||
|
||||
//! Convert the pnSeeds6 array into usable address objects.
|
||||
static std::vector<CAddress> convertSeed6(const std::vector<SeedSpec6> &vSeedsIn)
|
||||
{
|
||||
// It'll only connect to one or two seed nodes because once it connects,
|
||||
// it'll get a pile of addresses with newer timestamps.
|
||||
// Seed nodes are given a random 'last seen time' of between one and two
|
||||
// weeks ago.
|
||||
const int64_t nOneWeek = 7*24*60*60;
|
||||
std::vector<CAddress> vSeedsOut;
|
||||
vSeedsOut.reserve(vSeedsIn.size());
|
||||
for (std::vector<SeedSpec6>::const_iterator i(vSeedsIn.begin()); i != vSeedsIn.end(); ++i)
|
||||
{
|
||||
struct in6_addr ip;
|
||||
memcpy(&ip, i->addr, sizeof(ip));
|
||||
CAddress addr(CService(ip, i->port));
|
||||
addr.nTime = GetTime() - GetRand(nOneWeek) - nOneWeek;
|
||||
vSeedsOut.push_back(addr);
|
||||
}
|
||||
return vSeedsOut;
|
||||
}
|
||||
|
||||
// get best local address for a particular peer as a CAddress
|
||||
// Otherwise, return the unroutable 0.0.0.0 but filled in with
|
||||
// the normal parameters, since the IP may be changed to a useful
|
||||
|
@ -532,8 +554,10 @@ bool CNode::ReceiveMsgBytes(const char *pch, unsigned int nBytes)
|
|||
pch += handled;
|
||||
nBytes -= handled;
|
||||
|
||||
if (msg.complete())
|
||||
if (msg.complete()) {
|
||||
msg.nTime = GetTimeMicros();
|
||||
messageHandlerCondition.notify_one();
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
|
@ -1192,7 +1216,7 @@ void ThreadOpenConnections()
|
|||
static bool done = false;
|
||||
if (!done) {
|
||||
LogPrintf("Adding fixed seed nodes as DNS doesn't seem to be available.\n");
|
||||
addrman.Add(Params().FixedSeeds(), CNetAddr("127.0.0.1"));
|
||||
addrman.Add(convertSeed6(Params().FixedSeeds()), CNetAddr("127.0.0.1"));
|
||||
done = true;
|
||||
}
|
||||
}
|
||||
|
@ -1221,7 +1245,7 @@ void ThreadOpenConnections()
|
|||
int nTries = 0;
|
||||
while (true)
|
||||
{
|
||||
CAddress addr = addrman.Select();
|
||||
CAddrInfo addr = addrman.Select();
|
||||
|
||||
// if we selected an invalid address, restart
|
||||
if (!addr.IsValid() || setConnected.count(addr.GetGroup()) || IsLocal(addr))
|
||||
|
@ -1358,6 +1382,9 @@ bool OpenNetworkConnection(const CAddress& addrConnect, CSemaphoreGrant *grantOu
|
|||
|
||||
void ThreadMessageHandler()
|
||||
{
|
||||
boost::mutex condition_mutex;
|
||||
boost::unique_lock<boost::mutex> lock(condition_mutex);
|
||||
|
||||
SetThreadPriority(THREAD_PRIORITY_BELOW_NORMAL);
|
||||
while (true)
|
||||
{
|
||||
|
@ -1417,7 +1444,7 @@ void ThreadMessageHandler()
|
|||
}
|
||||
|
||||
if (fSleep)
|
||||
MilliSleep(100);
|
||||
messageHandlerCondition.timed_wait(lock, boost::posix_time::microsec_clock::universal_time() + boost::posix_time::milliseconds(100));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
180
src/netbase.cpp
180
src/netbase.cpp
|
@ -12,6 +12,7 @@
|
|||
#include "hash.h"
|
||||
#include "sync.h"
|
||||
#include "uint256.h"
|
||||
#include "random.h"
|
||||
#include "util.h"
|
||||
#include "utilstrencodings.h"
|
||||
|
||||
|
@ -38,7 +39,7 @@ using namespace std;
|
|||
|
||||
// Settings
|
||||
static proxyType proxyInfo[NET_MAX];
|
||||
static CService nameProxy;
|
||||
static proxyType nameProxy;
|
||||
static CCriticalSection cs_proxyInfos;
|
||||
int nConnectTimeout = DEFAULT_CONNECT_TIMEOUT;
|
||||
bool fNameLookup = false;
|
||||
|
@ -285,59 +286,100 @@ bool static InterruptibleRecv(char* data, size_t len, int timeout, SOCKET& hSock
|
|||
return len == 0;
|
||||
}
|
||||
|
||||
bool static Socks5(string strDest, int port, SOCKET& hSocket)
|
||||
struct ProxyCredentials
|
||||
{
|
||||
std::string username;
|
||||
std::string password;
|
||||
};
|
||||
|
||||
/** Connect using SOCKS5 (as described in RFC1928) */
|
||||
static bool Socks5(const std::string& strDest, int port, const ProxyCredentials *auth, SOCKET& hSocket)
|
||||
{
|
||||
LogPrintf("SOCKS5 connecting %s\n", strDest);
|
||||
if (strDest.size() > 255)
|
||||
{
|
||||
if (strDest.size() > 255) {
|
||||
CloseSocket(hSocket);
|
||||
return error("Hostname too long");
|
||||
}
|
||||
char pszSocks5Init[] = "\5\1\0";
|
||||
ssize_t nSize = sizeof(pszSocks5Init) - 1;
|
||||
|
||||
ssize_t ret = send(hSocket, pszSocks5Init, nSize, MSG_NOSIGNAL);
|
||||
if (ret != nSize)
|
||||
{
|
||||
// Accepted authentication methods
|
||||
std::vector<uint8_t> vSocks5Init;
|
||||
vSocks5Init.push_back(0x05);
|
||||
if (auth) {
|
||||
vSocks5Init.push_back(0x02); // # METHODS
|
||||
vSocks5Init.push_back(0x00); // X'00' NO AUTHENTICATION REQUIRED
|
||||
vSocks5Init.push_back(0x02); // X'02' USERNAME/PASSWORD (RFC1929)
|
||||
} else {
|
||||
vSocks5Init.push_back(0x01); // # METHODS
|
||||
vSocks5Init.push_back(0x00); // X'00' NO AUTHENTICATION REQUIRED
|
||||
}
|
||||
ssize_t ret = send(hSocket, (const char*)begin_ptr(vSocks5Init), vSocks5Init.size(), MSG_NOSIGNAL);
|
||||
if (ret != (ssize_t)vSocks5Init.size()) {
|
||||
CloseSocket(hSocket);
|
||||
return error("Error sending to proxy");
|
||||
}
|
||||
char pchRet1[2];
|
||||
if (!InterruptibleRecv(pchRet1, 2, SOCKS5_RECV_TIMEOUT, hSocket))
|
||||
{
|
||||
if (!InterruptibleRecv(pchRet1, 2, SOCKS5_RECV_TIMEOUT, hSocket)) {
|
||||
CloseSocket(hSocket);
|
||||
return error("Error reading proxy response");
|
||||
}
|
||||
if (pchRet1[0] != 0x05 || pchRet1[1] != 0x00)
|
||||
{
|
||||
if (pchRet1[0] != 0x05) {
|
||||
CloseSocket(hSocket);
|
||||
return error("Proxy failed to initialize");
|
||||
}
|
||||
string strSocks5("\5\1");
|
||||
strSocks5 += '\000'; strSocks5 += '\003';
|
||||
strSocks5 += static_cast<char>(std::min((int)strDest.size(), 255));
|
||||
strSocks5 += strDest;
|
||||
strSocks5 += static_cast<char>((port >> 8) & 0xFF);
|
||||
strSocks5 += static_cast<char>((port >> 0) & 0xFF);
|
||||
ret = send(hSocket, strSocks5.data(), strSocks5.size(), MSG_NOSIGNAL);
|
||||
if (ret != (ssize_t)strSocks5.size())
|
||||
{
|
||||
if (pchRet1[1] == 0x02 && auth) {
|
||||
// Perform username/password authentication (as described in RFC1929)
|
||||
std::vector<uint8_t> vAuth;
|
||||
vAuth.push_back(0x01);
|
||||
if (auth->username.size() > 255 || auth->password.size() > 255)
|
||||
return error("Proxy username or password too long");
|
||||
vAuth.push_back(auth->username.size());
|
||||
vAuth.insert(vAuth.end(), auth->username.begin(), auth->username.end());
|
||||
vAuth.push_back(auth->password.size());
|
||||
vAuth.insert(vAuth.end(), auth->password.begin(), auth->password.end());
|
||||
ret = send(hSocket, (const char*)begin_ptr(vAuth), vAuth.size(), MSG_NOSIGNAL);
|
||||
if (ret != (ssize_t)vAuth.size()) {
|
||||
CloseSocket(hSocket);
|
||||
return error("Error sending authentication to proxy");
|
||||
}
|
||||
LogPrint("proxy", "SOCKS5 sending proxy authentication %s:%s\n", auth->username, auth->password);
|
||||
char pchRetA[2];
|
||||
if (!InterruptibleRecv(pchRetA, 2, SOCKS5_RECV_TIMEOUT, hSocket)) {
|
||||
CloseSocket(hSocket);
|
||||
return error("Error reading proxy authentication response");
|
||||
}
|
||||
if (pchRetA[0] != 0x01 || pchRetA[1] != 0x00) {
|
||||
CloseSocket(hSocket);
|
||||
return error("Proxy authentication unsuccesful");
|
||||
}
|
||||
} else if (pchRet1[1] == 0x00) {
|
||||
// Perform no authentication
|
||||
} else {
|
||||
CloseSocket(hSocket);
|
||||
return error("Proxy requested wrong authentication method %02x", pchRet1[1]);
|
||||
}
|
||||
std::vector<uint8_t> vSocks5;
|
||||
vSocks5.push_back(0x05); // VER protocol version
|
||||
vSocks5.push_back(0x01); // CMD CONNECT
|
||||
vSocks5.push_back(0x00); // RSV Reserved
|
||||
vSocks5.push_back(0x03); // ATYP DOMAINNAME
|
||||
vSocks5.push_back(strDest.size()); // Length<=255 is checked at beginning of function
|
||||
vSocks5.insert(vSocks5.end(), strDest.begin(), strDest.end());
|
||||
vSocks5.push_back((port >> 8) & 0xFF);
|
||||
vSocks5.push_back((port >> 0) & 0xFF);
|
||||
ret = send(hSocket, (const char*)begin_ptr(vSocks5), vSocks5.size(), MSG_NOSIGNAL);
|
||||
if (ret != (ssize_t)vSocks5.size()) {
|
||||
CloseSocket(hSocket);
|
||||
return error("Error sending to proxy");
|
||||
}
|
||||
char pchRet2[4];
|
||||
if (!InterruptibleRecv(pchRet2, 4, SOCKS5_RECV_TIMEOUT, hSocket))
|
||||
{
|
||||
if (!InterruptibleRecv(pchRet2, 4, SOCKS5_RECV_TIMEOUT, hSocket)) {
|
||||
CloseSocket(hSocket);
|
||||
return error("Error reading proxy response");
|
||||
}
|
||||
if (pchRet2[0] != 0x05)
|
||||
{
|
||||
if (pchRet2[0] != 0x05) {
|
||||
CloseSocket(hSocket);
|
||||
return error("Proxy failed to accept request");
|
||||
}
|
||||
if (pchRet2[1] != 0x00)
|
||||
{
|
||||
if (pchRet2[1] != 0x00) {
|
||||
CloseSocket(hSocket);
|
||||
switch (pchRet2[1])
|
||||
{
|
||||
|
@ -352,8 +394,7 @@ bool static Socks5(string strDest, int port, SOCKET& hSocket)
|
|||
default: return error("Proxy error: unknown");
|
||||
}
|
||||
}
|
||||
if (pchRet2[2] != 0x00)
|
||||
{
|
||||
if (pchRet2[2] != 0x00) {
|
||||
CloseSocket(hSocket);
|
||||
return error("Error: malformed proxy response");
|
||||
}
|
||||
|
@ -375,13 +416,11 @@ bool static Socks5(string strDest, int port, SOCKET& hSocket)
|
|||
}
|
||||
default: CloseSocket(hSocket); return error("Error: malformed proxy response");
|
||||
}
|
||||
if (!ret)
|
||||
{
|
||||
if (!ret) {
|
||||
CloseSocket(hSocket);
|
||||
return error("Error reading from proxy");
|
||||
}
|
||||
if (!InterruptibleRecv(pchRet3, 2, SOCKS5_RECV_TIMEOUT, hSocket))
|
||||
{
|
||||
if (!InterruptibleRecv(pchRet3, 2, SOCKS5_RECV_TIMEOUT, hSocket)) {
|
||||
CloseSocket(hSocket);
|
||||
return error("Error reading from proxy");
|
||||
}
|
||||
|
@ -471,7 +510,7 @@ bool static ConnectSocketDirectly(const CService &addrConnect, SOCKET& hSocketRe
|
|||
return true;
|
||||
}
|
||||
|
||||
bool SetProxy(enum Network net, CService addrProxy) {
|
||||
bool SetProxy(enum Network net, const proxyType &addrProxy) {
|
||||
assert(net >= 0 && net < NET_MAX);
|
||||
if (!addrProxy.IsValid())
|
||||
return false;
|
||||
|
@ -489,7 +528,7 @@ bool GetProxy(enum Network net, proxyType &proxyInfoOut) {
|
|||
return true;
|
||||
}
|
||||
|
||||
bool SetNameProxy(CService addrProxy) {
|
||||
bool SetNameProxy(const proxyType &addrProxy) {
|
||||
if (!addrProxy.IsValid())
|
||||
return false;
|
||||
LOCK(cs_proxyInfos);
|
||||
|
@ -497,7 +536,7 @@ bool SetNameProxy(CService addrProxy) {
|
|||
return true;
|
||||
}
|
||||
|
||||
bool GetNameProxy(CService &nameProxyOut) {
|
||||
bool GetNameProxy(proxyType &nameProxyOut) {
|
||||
LOCK(cs_proxyInfos);
|
||||
if(!nameProxy.IsValid())
|
||||
return false;
|
||||
|
@ -513,35 +552,47 @@ bool HaveNameProxy() {
|
|||
bool IsProxy(const CNetAddr &addr) {
|
||||
LOCK(cs_proxyInfos);
|
||||
for (int i = 0; i < NET_MAX; i++) {
|
||||
if (addr == (CNetAddr)proxyInfo[i])
|
||||
if (addr == (CNetAddr)proxyInfo[i].proxy)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool ConnectThroughProxy(const proxyType &proxy, const std::string& strDest, int port, SOCKET& hSocketRet, int nTimeout, bool *outProxyConnectionFailed)
|
||||
{
|
||||
SOCKET hSocket = INVALID_SOCKET;
|
||||
// first connect to proxy server
|
||||
if (!ConnectSocketDirectly(proxy.proxy, hSocket, nTimeout)) {
|
||||
if (outProxyConnectionFailed)
|
||||
*outProxyConnectionFailed = true;
|
||||
return false;
|
||||
}
|
||||
// do socks negotiation
|
||||
if (proxy.randomize_credentials) {
|
||||
ProxyCredentials random_auth;
|
||||
random_auth.username = strprintf("%i", insecure_rand());
|
||||
random_auth.password = strprintf("%i", insecure_rand());
|
||||
if (!Socks5(strDest, (unsigned short)port, &random_auth, hSocket))
|
||||
return false;
|
||||
} else {
|
||||
if (!Socks5(strDest, (unsigned short)port, 0, hSocket))
|
||||
return false;
|
||||
}
|
||||
|
||||
hSocketRet = hSocket;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ConnectSocket(const CService &addrDest, SOCKET& hSocketRet, int nTimeout, bool *outProxyConnectionFailed)
|
||||
{
|
||||
proxyType proxy;
|
||||
if (outProxyConnectionFailed)
|
||||
*outProxyConnectionFailed = false;
|
||||
// no proxy needed (none set for target network)
|
||||
if (!GetProxy(addrDest.GetNetwork(), proxy))
|
||||
|
||||
if (GetProxy(addrDest.GetNetwork(), proxy))
|
||||
return ConnectThroughProxy(proxy, addrDest.ToStringIP(), addrDest.GetPort(), hSocketRet, nTimeout, outProxyConnectionFailed);
|
||||
else // no proxy needed (none set for target network)
|
||||
return ConnectSocketDirectly(addrDest, hSocketRet, nTimeout);
|
||||
|
||||
SOCKET hSocket = INVALID_SOCKET;
|
||||
|
||||
// first connect to proxy server
|
||||
if (!ConnectSocketDirectly(proxy, hSocket, nTimeout)) {
|
||||
if (outProxyConnectionFailed)
|
||||
*outProxyConnectionFailed = true;
|
||||
return false;
|
||||
}
|
||||
// do socks negotiation
|
||||
if (!Socks5(addrDest.ToStringIP(), addrDest.GetPort(), hSocket))
|
||||
return false;
|
||||
|
||||
hSocketRet = hSocket;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ConnectSocketByName(CService &addr, SOCKET& hSocketRet, const char *pszDest, int portDefault, int nTimeout, bool *outProxyConnectionFailed)
|
||||
|
@ -554,9 +605,7 @@ bool ConnectSocketByName(CService &addr, SOCKET& hSocketRet, const char *pszDest
|
|||
|
||||
SplitHostPort(string(pszDest), port, strDest);
|
||||
|
||||
SOCKET hSocket = INVALID_SOCKET;
|
||||
|
||||
CService nameProxy;
|
||||
proxyType nameProxy;
|
||||
GetNameProxy(nameProxy);
|
||||
|
||||
CService addrResolved(CNetAddr(strDest, fNameLookup && !HaveNameProxy()), port);
|
||||
|
@ -569,18 +618,7 @@ bool ConnectSocketByName(CService &addr, SOCKET& hSocketRet, const char *pszDest
|
|||
|
||||
if (!HaveNameProxy())
|
||||
return false;
|
||||
// first connect to name proxy server
|
||||
if (!ConnectSocketDirectly(nameProxy, hSocket, nTimeout)) {
|
||||
if (outProxyConnectionFailed)
|
||||
*outProxyConnectionFailed = true;
|
||||
return false;
|
||||
}
|
||||
// do socks negotiation
|
||||
if (!Socks5(strDest, (unsigned short)port, hSocket))
|
||||
return false;
|
||||
|
||||
hSocketRet = hSocket;
|
||||
return true;
|
||||
return ConnectThroughProxy(nameProxy, strDest, port, hSocketRet, nTimeout, outProxyConnectionFailed);
|
||||
}
|
||||
|
||||
void CNetAddr::Init()
|
||||
|
|
|
@ -168,15 +168,25 @@ class CService : public CNetAddr
|
|||
}
|
||||
};
|
||||
|
||||
typedef CService proxyType;
|
||||
class proxyType
|
||||
{
|
||||
public:
|
||||
proxyType(): randomize_credentials(false) {}
|
||||
proxyType(const CService &proxy, bool randomize_credentials=false): proxy(proxy), randomize_credentials(randomize_credentials) {}
|
||||
|
||||
bool IsValid() const { return proxy.IsValid(); }
|
||||
|
||||
CService proxy;
|
||||
bool randomize_credentials;
|
||||
};
|
||||
|
||||
enum Network ParseNetwork(std::string net);
|
||||
std::string GetNetworkName(enum Network net);
|
||||
void SplitHostPort(std::string in, int &portOut, std::string &hostOut);
|
||||
bool SetProxy(enum Network net, CService addrProxy);
|
||||
bool SetProxy(enum Network net, const proxyType &addrProxy);
|
||||
bool GetProxy(enum Network net, proxyType &proxyInfoOut);
|
||||
bool IsProxy(const CNetAddr &addr);
|
||||
bool SetNameProxy(CService addrProxy);
|
||||
bool SetNameProxy(const proxyType &addrProxy);
|
||||
bool HaveNameProxy();
|
||||
bool LookupHost(const char *pszName, std::vector<CNetAddr>& vIP, unsigned int nMaxSolutions = 0, bool fAllowLookup = true);
|
||||
bool Lookup(const char *pszName, CService& addr, int portDefault = 0, bool fAllowLookup = true);
|
||||
|
|
26
src/pow.cpp
26
src/pow.cpp
|
@ -13,7 +13,7 @@
|
|||
|
||||
unsigned int GetNextWorkRequired(const CBlockIndex* pindexLast, const CBlockHeader *pblock, const Consensus::Params& params)
|
||||
{
|
||||
unsigned int nProofOfWorkLimit = params.powLimit.GetCompact();
|
||||
unsigned int nProofOfWorkLimit = UintToArith256(params.powLimit).GetCompact();
|
||||
|
||||
// Genesis block
|
||||
if (pindexLast == NULL)
|
||||
|
@ -61,6 +61,7 @@ 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);
|
||||
|
@ -68,8 +69,8 @@ unsigned int CalculateNextWorkRequired(const CBlockIndex* pindexLast, int64_t nF
|
|||
bnNew *= nActualTimespan;
|
||||
bnNew /= params.nPowTargetTimespan;
|
||||
|
||||
if (bnNew > params.powLimit)
|
||||
bnNew = params.powLimit;
|
||||
if (bnNew > bnPowLimit)
|
||||
bnNew = bnPowLimit;
|
||||
|
||||
/// debug print
|
||||
LogPrintf("GetNextWorkRequired RETARGET\n");
|
||||
|
@ -89,7 +90,7 @@ bool CheckProofOfWork(uint256 hash, unsigned int nBits, const Consensus::Params&
|
|||
bnTarget.SetCompact(nBits, &fNegative, &fOverflow);
|
||||
|
||||
// Check range
|
||||
if (fNegative || bnTarget == 0 || fOverflow || bnTarget > params.powLimit)
|
||||
if (fNegative || bnTarget == 0 || fOverflow || bnTarget > UintToArith256(params.powLimit))
|
||||
return error("CheckProofOfWork(): nBits below minimum work");
|
||||
|
||||
// Check proof of work matches claimed amount
|
||||
|
@ -113,3 +114,20 @@ arith_uint256 GetBlockProof(const CBlockIndex& block)
|
|||
// or ~bnTarget / (nTarget+1) + 1.
|
||||
return (~bnTarget / (bnTarget + 1)) + 1;
|
||||
}
|
||||
|
||||
int64_t GetBlockProofEquivalentTime(const CBlockIndex& to, const CBlockIndex& from, const CBlockIndex& tip, const Consensus::Params& params)
|
||||
{
|
||||
arith_uint256 r;
|
||||
int sign = 1;
|
||||
if (to.nChainWork > from.nChainWork) {
|
||||
r = to.nChainWork - from.nChainWork;
|
||||
} else {
|
||||
r = from.nChainWork - to.nChainWork;
|
||||
sign = -1;
|
||||
}
|
||||
r = r * arith_uint256(params.nPowTargetSpacing) / GetBlockProof(tip);
|
||||
if (r.bits() > 63) {
|
||||
return sign * std::numeric_limits<int64_t>::max();
|
||||
}
|
||||
return sign * r.GetLow64();
|
||||
}
|
||||
|
|
|
@ -22,4 +22,7 @@ unsigned int CalculateNextWorkRequired(const CBlockIndex* pindexLast, int64_t nF
|
|||
bool CheckProofOfWork(uint256 hash, unsigned int nBits, const Consensus::Params&);
|
||||
arith_uint256 GetBlockProof(const CBlockIndex& block);
|
||||
|
||||
/** Return the time it would take to redo the work difference between from and to, assuming the current hashrate corresponds to the difficulty at tip, in seconds. */
|
||||
int64_t GetBlockProofEquivalentTime(const CBlockIndex& to, const CBlockIndex& from, const CBlockIndex& tip, const Consensus::Params&);
|
||||
|
||||
#endif // BITCOIN_POW_H
|
||||
|
|
|
@ -10,9 +10,6 @@
|
|||
#include "serialize.h"
|
||||
#include "uint256.h"
|
||||
|
||||
/** The maximum allowed size for a serialized block, in bytes (network rule) */
|
||||
static const unsigned int MAX_BLOCK_SIZE = 1000000;
|
||||
|
||||
/** Nodes collect new transactions into a block, hash them into a hash tree,
|
||||
* and scan through nonce values to make the block's hash satisfy proof-of-work
|
||||
* requirements. When they solve the proof-of-work, they broadcast the block
|
||||
|
|
|
@ -89,7 +89,6 @@ void CAddress::Init()
|
|||
{
|
||||
nServices = NODE_NETWORK;
|
||||
nTime = 100000000;
|
||||
nLastTry = 0;
|
||||
}
|
||||
|
||||
CInv::CInv()
|
||||
|
|
|
@ -116,9 +116,6 @@ public:
|
|||
|
||||
// disk and network only
|
||||
unsigned int nTime;
|
||||
|
||||
// memory only
|
||||
int64_t nLastTry;
|
||||
};
|
||||
|
||||
/** inv message data */
|
||||
|
|
|
@ -107,7 +107,6 @@ static QString GetLangTerritory()
|
|||
/** Set up translations */
|
||||
static void initTranslations(QTranslator &qtTranslatorBase, QTranslator &qtTranslator, QTranslator &translatorBase, QTranslator &translator)
|
||||
{
|
||||
|
||||
// Remove old translators
|
||||
QApplication::removeTranslator(&qtTranslatorBase);
|
||||
QApplication::removeTranslator(&qtTranslator);
|
||||
|
@ -533,7 +532,7 @@ int main(int argc, char *argv[])
|
|||
// Now that QSettings are accessible, initialize translations
|
||||
QTranslator qtTranslatorBase, qtTranslator, translatorBase, translator;
|
||||
initTranslations(qtTranslatorBase, qtTranslator, translatorBase, translator);
|
||||
uiInterface.Translate.connect(Translate);
|
||||
translationInterface.Translate.connect(Translate);
|
||||
|
||||
// Show help message immediately after parsing command-line options (for "-lang") and setting locale,
|
||||
// but before showing splash screen.
|
||||
|
|
|
@ -164,7 +164,7 @@ BitcoinGUI::BitcoinGUI(const NetworkStyle *networkStyle, QWidget *parent) :
|
|||
|
||||
// Create status bar
|
||||
statusBar();
|
||||
|
||||
|
||||
// Disable size grip because it looks ugly and nobody needs it
|
||||
statusBar()->setSizeGripEnabled(false);
|
||||
|
||||
|
|
|
@ -10,18 +10,6 @@
|
|||
#endif
|
||||
static const char UNUSED *bitcoin_strings[] = {
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", ""
|
||||
"%s, you must set a rpcpassword in the configuration file:\n"
|
||||
"%s\n"
|
||||
"It is recommended you use the following random password:\n"
|
||||
"rpcuser=bitcoinrpc\n"
|
||||
"rpcpassword=%s\n"
|
||||
"(you do not need to remember this password)\n"
|
||||
"The username and password MUST NOT be the same.\n"
|
||||
"If the file does not exist, create it with owner-readable-only file "
|
||||
"permissions.\n"
|
||||
"It is also recommended to set alertnotify so you are notified of problems;\n"
|
||||
"for example: alertnotify=echo %%s | mail -s \"Bitcoin Alert\" admin@foo.com\n"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", ""
|
||||
"(1 = keep tx meta data e.g. account owner and payment request information, 2 "
|
||||
"= drop tx meta data)"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", ""
|
||||
|
@ -46,7 +34,7 @@ QT_TRANSLATE_NOOP("bitcoin-core", ""
|
|||
"running."),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", ""
|
||||
"Continuously rate-limit free transactions to <n>*1000 bytes per minute "
|
||||
"(default:%u)"),
|
||||
"(default: %u)"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", ""
|
||||
"Create new files with system default permissions, instead of umask 077 (only "
|
||||
"effective with disabled wallet functionality)"),
|
||||
|
@ -54,6 +42,9 @@ QT_TRANSLATE_NOOP("bitcoin-core", ""
|
|||
"Delete all wallet transactions and only recover those parts of the "
|
||||
"blockchain through -rescan on startup"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", ""
|
||||
"Discover own IP addresses (default: 1 when listening and no -externalip or -"
|
||||
"proxy)"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", ""
|
||||
"Distributed under the MIT software license, see the accompanying file "
|
||||
"COPYING or <http://www.opensource.org/licenses/mit-license.php>."),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", ""
|
||||
|
@ -62,13 +53,6 @@ QT_TRANSLATE_NOOP("bitcoin-core", ""
|
|||
QT_TRANSLATE_NOOP("bitcoin-core", ""
|
||||
"Error: Listening for incoming connections failed (listen returned error %s)"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", ""
|
||||
"Error: The transaction was rejected! This might happen if some of the coins "
|
||||
"in your wallet were already spent, such as if you used a copy of wallet.dat "
|
||||
"and coins were spent in the copy but not marked as spent here."),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", ""
|
||||
"Error: This transaction requires a transaction fee of at least %s because of "
|
||||
"its amount, complexity, or use of recently received funds!"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", ""
|
||||
"Error: Unsupported argument -socks found. Setting SOCKS version isn't "
|
||||
"possible anymore, only SOCKS5 proxies are supported."),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", ""
|
||||
|
@ -92,12 +76,15 @@ QT_TRANSLATE_NOOP("bitcoin-core", ""
|
|||
QT_TRANSLATE_NOOP("bitcoin-core", ""
|
||||
"How thorough the block verification of -checkblocks is (0-4, default: %u)"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", ""
|
||||
"If paytxfee is not set, include enough fee so transactions are confirmed on "
|
||||
"average within n blocks (default: %u)"),
|
||||
"If paytxfee is not set, include enough fee so transactions begin "
|
||||
"confirmation on average within n blocks (default: %u)"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", ""
|
||||
"In this mode -genproclimit controls how many blocks are generated "
|
||||
"immediately."),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", ""
|
||||
"Invalid amount for -maxtxfee=<amount>: '%s' (must be at least the minrelay "
|
||||
"fee of %s to prevent stuck transactions)"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", ""
|
||||
"Log transaction priority and fee per kB when mining blocks (default: %u)"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", ""
|
||||
"Maintain a full transaction index, used by the getrawtransaction rpc call "
|
||||
|
@ -106,13 +93,26 @@ QT_TRANSLATE_NOOP("bitcoin-core", ""
|
|||
"Maximum size of data in data carrier transactions we relay and mine "
|
||||
"(default: %u)"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", ""
|
||||
"Maximum total fees to use in a single wallet transaction, setting too low "
|
||||
"may abort large transactions (default: %s)"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", ""
|
||||
"Number of seconds to keep misbehaving peers from reconnecting (default: %u)"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", ""
|
||||
"Output debugging information (default: %u, supplying <category> is optional)"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", ""
|
||||
"Prune configured below the minimum of %d MB. Please use a higher number."),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", ""
|
||||
"Query for peer addresses via DNS lookup, if low on addresses (default: 1 "
|
||||
"unless -connect)"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", ""
|
||||
"Randomize credentials for every proxy connection. This enables Tor stream "
|
||||
"isolation (default: %u)"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", ""
|
||||
"Reduce storage requirements by pruning (deleting) old blocks. This mode "
|
||||
"disables wallet support and is incompatible with -txindex."),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", ""
|
||||
"Require high priority for relaying free or low-fee transactions (default: %u)"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", ""
|
||||
"Set maximum size of high-priority/low-fee transactions in bytes (default: %d)"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", ""
|
||||
"Set the number of script verification threads (%u to %d, 0 = auto, <0 = "
|
||||
|
@ -121,6 +121,8 @@ QT_TRANSLATE_NOOP("bitcoin-core", ""
|
|||
"Set the number of threads for coin generation if enabled (-1 = all cores, "
|
||||
"default: %d)"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", ""
|
||||
"The transaction amount is too small to send after the fee has been deducted"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", ""
|
||||
"This is a pre-release test build - use at your own risk - do not use for "
|
||||
"mining or merchant applications"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", ""
|
||||
|
@ -128,18 +130,37 @@ QT_TRANSLATE_NOOP("bitcoin-core", ""
|
|||
"the OpenSSL Toolkit <https://www.openssl.org/> and cryptographic software "
|
||||
"written by Eric Young and UPnP software written by Thomas Bernard."),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", ""
|
||||
"To use bitcoind, or the -server option to bitcoin-qt, you must set an "
|
||||
"rpcpassword in the configuration file:\n"
|
||||
"%s\n"
|
||||
"It is recommended you use the following random password:\n"
|
||||
"rpcuser=bitcoinrpc\n"
|
||||
"rpcpassword=%s\n"
|
||||
"(you do not need to remember this password)\n"
|
||||
"The username and password MUST NOT be the same.\n"
|
||||
"If the file does not exist, create it with owner-readable-only file "
|
||||
"permissions.\n"
|
||||
"It is also recommended to set alertnotify so you are notified of problems;\n"
|
||||
"for example: alertnotify=echo %%s | mail -s \"Bitcoin Alert\" admin@foo.com\n"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", ""
|
||||
"Unable to bind to %s on this computer. Bitcoin Core is probably already "
|
||||
"running."),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", ""
|
||||
"Use separate SOCKS5 proxy to reach peers via Tor hidden services (default: "
|
||||
"%s)"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", ""
|
||||
"Warning: -maxtxfee is set very high! Fees this large could be paid on a "
|
||||
"single transaction."),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", ""
|
||||
"Warning: -paytxfee is set very high! This is the transaction fee you will "
|
||||
"pay if you send a transaction."),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", ""
|
||||
"Warning: Please check that your computer's date and time are correct! If "
|
||||
"your clock is wrong Bitcoin Core will not work properly."),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", ""
|
||||
"Warning: Reverting this setting requires re-downloading the entire "
|
||||
"blockchain."),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", ""
|
||||
"Warning: The network does not appear to fully agree! Some miners appear to "
|
||||
"be experiencing issues."),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", ""
|
||||
|
@ -158,22 +179,32 @@ QT_TRANSLATE_NOOP("bitcoin-core", ""
|
|||
QT_TRANSLATE_NOOP("bitcoin-core", ""
|
||||
"Whitelisted peers cannot be DoS banned and their transactions are always "
|
||||
"relayed, even if they are already in the mempool, useful e.g. for a gateway"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", ""
|
||||
"You need to rebuild the database using -reindex to go back to unpruned "
|
||||
"mode. This will redownload the entire blockchain"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "(default: %s)"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "(default: %u)"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "(default: 0 = disable pruning blocks,"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "(default: 1)"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "<category> can be:"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", ">%u = target size in MiB to use for block files)"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Accept command line and JSON-RPC commands"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Accept connections from outside (default: 1 if no -proxy or -connect)"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Accept public REST requests (default: %u)"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Acceptable ciphers (default: %s)"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Add a node to connect to and attempt to keep the connection open"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Allow DNS lookups for -addnode, -seednode and -connect"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Allow self signed root certificates (default: 0)"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Always query for peer addresses via DNS lookup (default: %u)"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Attempt to recover private keys from a corrupt wallet.dat"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Block creation options:"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Can't run with a wallet in prune mode."),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Cannot downgrade wallet"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Cannot resolve -bind address: '%s'"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Cannot resolve -externalip address: '%s'"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Cannot resolve -whitebind address: '%s'"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Cannot write default address"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Choose data directory on startup (default: 0)"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Connect only to the specified node(s)"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Connect through SOCKS5 proxy"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Connect to a node to retrieve peer addresses, and disconnect"),
|
||||
|
@ -183,7 +214,6 @@ QT_TRANSLATE_NOOP("bitcoin-core", "Corrupted block database detected"),
|
|||
QT_TRANSLATE_NOOP("bitcoin-core", "Could not parse -rpcbind value %s as network address"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Debugging/Testing options:"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Disable safemode, override a real safe mode event (default: %u)"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Discover own IP address (default: 1 when listening and no -externalip)"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Do not load the wallet and disable wallet RPC calls"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Do you want to rebuild the block database now?"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Done loading"),
|
||||
|
@ -194,11 +224,11 @@ QT_TRANSLATE_NOOP("bitcoin-core", "Error loading wallet.dat"),
|
|||
QT_TRANSLATE_NOOP("bitcoin-core", "Error loading wallet.dat: Wallet corrupted"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Error loading wallet.dat: Wallet requires newer version of Bitcoin Core"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Error opening block database"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Error reading from database, shutting down."),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Error"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Error: A fatal internal error occured, see debug.log for details"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Error: Disk space is low!"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Error: Unsupported argument -tor found, use -onion."),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Error: Wallet locked, unable to create transaction!"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Failed to listen on any port. Use -listen=0 if you want this."),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Fee (in BTC/kB) to add to transactions you send (default: %s)"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Force safe mode (default: %u)"),
|
||||
|
@ -214,13 +244,12 @@ QT_TRANSLATE_NOOP("bitcoin-core", "Initialization sanity check failed. Bitcoin C
|
|||
QT_TRANSLATE_NOOP("bitcoin-core", "Insufficient funds"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Invalid -onion address: '%s'"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Invalid -proxy address: '%s'"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Invalid amount for -maxtxfee=<amount>: '%s'"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Invalid amount for -minrelaytxfee=<amount>: '%s'"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Invalid amount for -mintxfee=<amount>: '%s'"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Invalid amount for -paytxfee=<amount>: '%s' (must be at least %s)"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Invalid amount for -paytxfee=<amount>: '%s'"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Invalid amount"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Invalid netmask specified in -whitelist: '%s'"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Keep at most <n> unconnectable blocks in memory (default: %u)"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Keep at most <n> unconnectable transactions in memory (default: %u)"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Limit size of signature cache to <n> entries (default: %u)"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Listen for JSON-RPC connections on <port> (default: %u or testnet: %u)"),
|
||||
|
@ -229,6 +258,7 @@ QT_TRANSLATE_NOOP("bitcoin-core", "Loading addresses..."),
|
|||
QT_TRANSLATE_NOOP("bitcoin-core", "Loading block index..."),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Loading wallet..."),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Maintain at most <n> connections to peers (default: %u)"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Make the wallet broadcast transactions"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Maximum per-connection receive buffer, <n>*1000 bytes (default: %u)"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Maximum per-connection send buffer, <n>*1000 bytes (default: %u)"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Need to specify a port with -whitebind: '%s'"),
|
||||
|
@ -239,10 +269,11 @@ QT_TRANSLATE_NOOP("bitcoin-core", "Only connect to nodes in network <net> (ipv4,
|
|||
QT_TRANSLATE_NOOP("bitcoin-core", "Options:"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Password for JSON-RPC connections"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Prepend debug output with timestamp (default: %u)"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Print block on startup, if found in block index"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Print block tree on startup (default: %u)"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Prune cannot be configured with a negative value."),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Prune mode is incompatible with -txindex."),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "RPC SSL options: (see the Bitcoin Wiki for SSL setup instructions)"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "RPC server options:"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "RPC support for HTTP persistent connections (default: %d)"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Randomly drop 1 of every <n> network messages"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Randomly fuzz 1 of every <n> network messages"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Rebuild block chain index from current blk000??.dat files"),
|
||||
|
@ -256,13 +287,16 @@ QT_TRANSLATE_NOOP("bitcoin-core", "Send trace/debug info to console instead of d
|
|||
QT_TRANSLATE_NOOP("bitcoin-core", "Send transactions as zero-fee transactions if possible (default: %u)"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Server certificate file (default: %s)"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Server private key (default: %s)"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Set SSL root certificates for payment request (default: -system-)"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Set database cache size in megabytes (%d to %d, default: %d)"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Set key pool size to <n> (default: %u)"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Set language, for example \"de_DE\" (default: system locale)"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Set maximum block size in bytes (default: %d)"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Set minimum block size in bytes (default: %u)"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Set the number of threads to service RPC calls (default: %d)"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Sets the DB_PRIVATE flag in the wallet db environment (default: %u)"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Show all debugging options (usage: --help -help-debug)"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Show splash screen on startup (default: 1)"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Shrink debug.log file on client startup (default: 1 when no -debug)"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Signing transaction failed"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Specify configuration file (default: %s)"),
|
||||
|
@ -272,15 +306,18 @@ QT_TRANSLATE_NOOP("bitcoin-core", "Specify pid file (default: %s)"),
|
|||
QT_TRANSLATE_NOOP("bitcoin-core", "Specify wallet file (within data directory)"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Specify your own public address"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Spend unconfirmed change when sending transactions (default: %u)"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Start minimized"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Stop running after importing blocks from disk (default: %u)"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "The transaction amount is too small to pay the fee"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "This help message"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "This is experimental software."),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "This is intended for regression testing tools and app development."),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Threshold for disconnecting misbehaving peers (default: %u)"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "To use the %s option"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Transaction amount too small"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Transaction amounts must be positive"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Transaction too large for fee policy"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Transaction too large"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "UI Options:"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Unable to bind to %s on this computer (bind returned error %s)"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Unknown network specified in -onlynet: '%s'"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Upgrade wallet to latest format"),
|
||||
|
|
|
@ -8,12 +8,12 @@
|
|||
#include "addresstablemodel.h"
|
||||
#include "bitcoinunits.h"
|
||||
#include "guiutil.h"
|
||||
#include "init.h"
|
||||
#include "optionsmodel.h"
|
||||
#include "scicon.h"
|
||||
#include "walletmodel.h"
|
||||
|
||||
#include "coincontrol.h"
|
||||
#include "init.h"
|
||||
#include "main.h"
|
||||
#include "wallet/wallet.h"
|
||||
|
||||
|
|
|
@ -195,7 +195,7 @@
|
|||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QFrame" name="SendCoins_InsecurePaymentRequest">
|
||||
<widget class="QFrame" name="SendCoins_UnauthenticatedPaymentRequest">
|
||||
<property name="palette">
|
||||
<palette>
|
||||
<active>
|
||||
|
@ -612,7 +612,7 @@
|
|||
</palette>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>This is an unverified payment request.</string>
|
||||
<string>This is an unauthenticated payment request.</string>
|
||||
</property>
|
||||
<property name="autoFillBackground">
|
||||
<bool>true</bool>
|
||||
|
@ -700,7 +700,7 @@
|
|||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QFrame" name="SendCoins_SecurePaymentRequest">
|
||||
<widget class="QFrame" name="SendCoins_AuthenticatedPaymentRequest">
|
||||
<property name="palette">
|
||||
<palette>
|
||||
<active>
|
||||
|
@ -1144,7 +1144,7 @@
|
|||
</palette>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>This is a verified payment request.</string>
|
||||
<string>This is an authenticated payment request.</string>
|
||||
</property>
|
||||
<property name="autoFillBackground">
|
||||
<bool>true</bool>
|
||||
|
|
|
@ -741,14 +741,14 @@ LSSharedFileListItemRef findStartupItemInList(LSSharedFileListRef list, CFURLRef
|
|||
CFURLRef currentItemURL = NULL;
|
||||
|
||||
#if defined(MAC_OS_X_VERSION_MAX_ALLOWED) && MAC_OS_X_VERSION_MAX_ALLOWED >= 10100
|
||||
if(&LSSharedFileListItemCopyResolvedURL)
|
||||
currentItemURL = LSSharedFileListItemCopyResolvedURL(item, resolutionFlags, NULL);
|
||||
if(&LSSharedFileListItemCopyResolvedURL)
|
||||
currentItemURL = LSSharedFileListItemCopyResolvedURL(item, resolutionFlags, NULL);
|
||||
#if defined(MAC_OS_X_VERSION_MIN_REQUIRED) && MAC_OS_X_VERSION_MIN_REQUIRED < 10100
|
||||
else
|
||||
LSSharedFileListItemResolve(item, resolutionFlags, ¤tItemURL, NULL);
|
||||
else
|
||||
LSSharedFileListItemResolve(item, resolutionFlags, ¤tItemURL, NULL);
|
||||
#endif
|
||||
#else
|
||||
LSSharedFileListItemResolve(item, resolutionFlags, ¤tItemURL, NULL);
|
||||
LSSharedFileListItemResolve(item, resolutionFlags, ¤tItemURL, NULL);
|
||||
#endif
|
||||
|
||||
if(currentItemURL && CFEqual(currentItemURL, findUrl)) {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
<TS language="ach" version="2.0">
|
||||
<TS language="ach" version="2.1">
|
||||
<context>
|
||||
<name>AddressBookPage</name>
|
||||
</context>
|
||||
|
|
|
@ -1,10 +1,6 @@
|
|||
<TS language="af_ZA" version="2.0">
|
||||
<TS language="af_ZA" version="2.1">
|
||||
<context>
|
||||
<name>AddressBookPage</name>
|
||||
<message>
|
||||
<source>Double-click to edit address or label</source>
|
||||
<translation>Dubbel-klik om die adres of etiket te wysig</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Create a new address</source>
|
||||
<translation>Skep 'n nuwe adres</translation>
|
||||
|
@ -658,10 +654,6 @@
|
|||
<source>Loading addresses...</source>
|
||||
<translation>Laai adresse...</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Invalid amount</source>
|
||||
<translation>Ongeldige bedrag</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Insufficient funds</source>
|
||||
<translation>Onvoldoende fondse</translation>
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
<TS language="ar" version="2.0">
|
||||
<TS language="ar" version="2.1">
|
||||
<context>
|
||||
<name>AddressBookPage</name>
|
||||
<message>
|
||||
<source>Double-click to edit address or label</source>
|
||||
<translation>أنقر بالماوس مرتين لتعديل العنوان او الوصف</translation>
|
||||
<source>Right-click to edit address or label</source>
|
||||
<translation>انقر بالزر الايمن لتعديل العنوان</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Create a new address</source>
|
||||
|
@ -294,6 +294,14 @@
|
|||
<source>Bitcoin Core client</source>
|
||||
<translation>عميل bitcion core</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Importing blocks from disk...</source>
|
||||
<translation>استيراد كتل من القرص ...</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Reindexing blocks on disk...</source>
|
||||
<translation>إعادة فهرسة الكتل على القرص</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Send coins to a Bitcoin address</source>
|
||||
<translation>ارسل عملات الى عنوان بيتكوين</translation>
|
||||
|
@ -1674,10 +1682,6 @@
|
|||
<source>Error: Disk space is low!</source>
|
||||
<translation>تحذير: مساحة القرص منخفضة</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Error: Wallet locked, unable to create transaction!</source>
|
||||
<translation>تحذير: المحفظة مغلقة , لا تستطيع تنفيذ المعاملة</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Failed to listen on any port. Use -listen=0 if you want this.</source>
|
||||
<translation>فشل في الاستماع على أي منفذ. استخدام الاستماع = 0 إذا كنت تريد هذا.</translation>
|
||||
|
@ -1746,10 +1750,6 @@
|
|||
<source>Invalid -proxy address: '%s'</source>
|
||||
<translation>عنوان البروكسي غير صحيح : '%s'</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Invalid amount</source>
|
||||
<translation>قيمة غير صحيحة</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Insufficient funds</source>
|
||||
<translation>اموال غير كافية</translation>
|
||||
|
@ -1770,10 +1770,6 @@
|
|||
<source>Done loading</source>
|
||||
<translation>انتهاء التحميل</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>To use the %s option</source>
|
||||
<translation>لاستخدام %s الخيار</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Error</source>
|
||||
<translation>خطأ</translation>
|
||||
|
|
|
@ -1,10 +1,6 @@
|
|||
<TS language="be_BY" version="2.0">
|
||||
<TS language="be_BY" version="2.1">
|
||||
<context>
|
||||
<name>AddressBookPage</name>
|
||||
<message>
|
||||
<source>Double-click to edit address or label</source>
|
||||
<translation>Двайны клік для рэдагавання адрасу ці пазнакі</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Create a new address</source>
|
||||
<translation>Стварыць новы адрас</translation>
|
||||
|
@ -954,10 +950,6 @@ Address: %4
|
|||
<source>Error loading wallet.dat</source>
|
||||
<translation>Памылка загрузкі wallet.dat</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Invalid amount</source>
|
||||
<translation>Памылковая колькасць</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Insufficient funds</source>
|
||||
<translation>Недастаткова сродкаў</translation>
|
||||
|
|
|
@ -1,18 +1,26 @@
|
|||
<TS language="bg" version="2.0">
|
||||
<TS language="bg" version="2.1">
|
||||
<context>
|
||||
<name>AddressBookPage</name>
|
||||
<message>
|
||||
<source>Double-click to edit address or label</source>
|
||||
<translation>Двоен клик за редакция на адрес или име</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Create a new address</source>
|
||||
<translation>Създаване на нов адрес</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>&New</source>
|
||||
<translation>Нов</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Copy the currently selected address to the system clipboard</source>
|
||||
<translation>Копиране на избрания адрес</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>&Copy</source>
|
||||
<translation>Копирай</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>C&lose</source>
|
||||
<translation>Затвори</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>&Copy Address</source>
|
||||
<translation>&Копирай</translation>
|
||||
|
@ -25,10 +33,26 @@
|
|||
<source>Export the data in the current tab to a file</source>
|
||||
<translation>Запишете данните от текущия раздел във файл</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>&Export</source>
|
||||
<translation>Изнеси</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>&Delete</source>
|
||||
<translation>&Изтриване</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Choose the address to send coins to</source>
|
||||
<translation>Изберете адрес, на който да се изпращат монети</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Choose the address to receive coins with</source>
|
||||
<translation>Изберете адрес за получаване на монети</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>C&hoose</source>
|
||||
<translation>Избери</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Sending addresses</source>
|
||||
<translation>Адреси за изпращане</translation>
|
||||
|
@ -37,6 +61,10 @@
|
|||
<source>Receiving addresses</source>
|
||||
<translation>Адреси за получаване</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>These are your Bitcoin addresses for sending payments. Always check the amount and the receiving address before sending coins.</source>
|
||||
<translation>Това са адресите на получателите на плащания. Винаги проверявайте размера на сумата и адреса на получателя, преди да изпратите монети.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Copy &Label</source>
|
||||
<translation>Копирай &име</translation>
|
||||
|
@ -230,10 +258,22 @@
|
|||
<source>&Change Passphrase...</source>
|
||||
<translation>&Смяна на паролата...</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Open &URI...</source>
|
||||
<translation>Отвори &URI...</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Bitcoin Core client</source>
|
||||
<translation>Bitcoin Core клиент</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Send coins to a Bitcoin address</source>
|
||||
<translation>Изпращане към Биткоин адрес</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Backup wallet to another location</source>
|
||||
<translation>Запазване на портфейла на друго място</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Change the passphrase used for wallet encryption</source>
|
||||
<translation>Променя паролата за портфейла</translation>
|
||||
|
@ -254,6 +294,10 @@
|
|||
<source>&Send</source>
|
||||
<translation>&Изпращане</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>&Receive</source>
|
||||
<translation>&Получаване</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>&Show / Hide</source>
|
||||
<translation>&Покажи / Скрий</translation>
|
||||
|
@ -278,6 +322,10 @@
|
|||
<source>Tabs toolbar</source>
|
||||
<translation>Раздели</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>&About Bitcoin Core</source>
|
||||
<translation>&Относно Bitcoin Core</translation>
|
||||
</message>
|
||||
<message numerus="yes">
|
||||
<source>%n active connection(s) to Bitcoin network</source>
|
||||
<translation><numerusform>%n връзка към Биткоин мрежата</numerusform><numerusform>%n връзки към Биткоин мрежата</numerusform></translation>
|
||||
|
@ -330,6 +378,18 @@
|
|||
<source>Incoming transaction</source>
|
||||
<translation>Входяща трансакция</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Date: %1
|
||||
Amount: %2
|
||||
Type: %3
|
||||
Address: %4
|
||||
</source>
|
||||
<translation>Дата: %1
|
||||
Сума: %2
|
||||
Вид: %3
|
||||
Адрес: %4
|
||||
</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Wallet is <b>encrypted</b> and currently <b>unlocked</b></source>
|
||||
<translation>Портфейлът е <b>криптиран</b> и <b>отключен</b></translation>
|
||||
|
@ -392,6 +452,14 @@
|
|||
<source>Copy amount</source>
|
||||
<translation>Копирай сума</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Copy transaction ID</source>
|
||||
<translation>Копирай транзакция с ID</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>none</source>
|
||||
<translation>нищо</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>yes</source>
|
||||
<translation>да</translation>
|
||||
|
@ -400,11 +468,19 @@
|
|||
<source>no</source>
|
||||
<translation>не</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>This label turns red, if any recipient receives an amount smaller than %1.</source>
|
||||
<translation>Това наименование се оцветява в червено, ако произволен получател получи сума по-малка от %1.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>(no label)</source>
|
||||
<translation>(без име)</translation>
|
||||
</message>
|
||||
</context>
|
||||
<message>
|
||||
<source>(change)</source>
|
||||
<translation>(промени)</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>EditAddressDialog</name>
|
||||
<message>
|
||||
|
@ -473,6 +549,14 @@
|
|||
<source>version</source>
|
||||
<translation>версия</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>(%1-bit)</source>
|
||||
<translation>(%1-битов)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>About Bitcoin Core</source>
|
||||
<translation>За Bitcoin Core</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Usage:</source>
|
||||
<translation>Използване:</translation>
|
||||
|
@ -510,10 +594,26 @@
|
|||
<source>&Start Bitcoin on system login</source>
|
||||
<translation>&Пускане на Биткоин при вход в системата</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>IP address of the proxy (e.g. IPv4: 127.0.0.1 / IPv6: ::1)</source>
|
||||
<translation>IP адрес на прокси (напр. за IPv4: 127.0.0.1 / за IPv6: ::1)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>&Reset Options</source>
|
||||
<translation>&Нулирай настройките</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>&Network</source>
|
||||
<translation>&Мрежа</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>W&allet</source>
|
||||
<translation>По&ртфейл</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Expert</source>
|
||||
<translation>Експерт</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Automatically open the Bitcoin client port on the router. This only works when your router supports UPnP and it is enabled.</source>
|
||||
<translation>Автоматично отваряне на входящия Bitcoin порт. Работи само с рутери поддържащи UPnP.</translation>
|
||||
|
@ -586,6 +686,10 @@
|
|||
<source>default</source>
|
||||
<translation>подразбиране</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>none</source>
|
||||
<translation>нищо</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>The supplied proxy address is invalid.</source>
|
||||
<translation>Прокси адресът е невалиден.</translation>
|
||||
|
@ -597,6 +701,10 @@
|
|||
<source>Form</source>
|
||||
<translation>Форма</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>The displayed information may be out of date. Your wallet automatically synchronizes with the Bitcoin network after a connection is established, but this process has not completed yet.</source>
|
||||
<translation>Текущата информация на екрана може да не е актуална. Вашият портфейл ще се синхронизира автоматично с мрежата на Биткоин, щом поне една връзката с нея се установи; този процес все още не е приключил.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Available:</source>
|
||||
<translation>Налично:</translation>
|
||||
|
@ -605,6 +713,10 @@
|
|||
<source>Pending:</source>
|
||||
<translation>Изчакващо:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Balances</source>
|
||||
<translation>Баланс</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Total:</source>
|
||||
<translation>Общо:</translation>
|
||||
|
@ -620,6 +732,10 @@
|
|||
</context>
|
||||
<context>
|
||||
<name>PaymentServer</name>
|
||||
<message>
|
||||
<source>Requested payment amount of %1 is too small (considered dust).</source>
|
||||
<translation>Заявената сума за плащане: %1 е твърде малка (счита се за отпадък)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Payment acknowledged</source>
|
||||
<translation>Плащането е приета</translation>
|
||||
|
@ -641,7 +757,23 @@
|
|||
</context>
|
||||
<context>
|
||||
<name>QRImageWidget</name>
|
||||
</context>
|
||||
<message>
|
||||
<source>&Save Image...</source>
|
||||
<translation>&Запиши изображение...</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>&Copy Image</source>
|
||||
<translation>&Копирай изображение</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Save QR Code</source>
|
||||
<translation>Запази QR Код</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>PNG Image (*.png)</source>
|
||||
<translation>PNG Изображение (*.png)</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>RPCConsole</name>
|
||||
<message>
|
||||
|
@ -660,6 +792,10 @@
|
|||
<source>&Information</source>
|
||||
<translation>Данни</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>General</source>
|
||||
<translation>Основни</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Using OpenSSL version</source>
|
||||
<translation>Използване на OpenSSL версия</translation>
|
||||
|
@ -680,10 +816,46 @@
|
|||
<source>Current number of blocks</source>
|
||||
<translation>Текущ брой блокове</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Received</source>
|
||||
<translation>Получени</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Sent</source>
|
||||
<translation>Изпратени</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>&Peers</source>
|
||||
<translation>&Пиъри</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Select a peer to view detailed information.</source>
|
||||
<translation>Избери пиър за детайлна информация.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Version</source>
|
||||
<translation>Версия</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Last block time</source>
|
||||
<translation>Време на последния блок</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>&Open</source>
|
||||
<translation>&Отвори</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>&Console</source>
|
||||
<translation>&Конзола</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>&Network Traffic</source>
|
||||
<translation>&Мрежов Трафик</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>&Clear</source>
|
||||
<translation>&Изчисти</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Totals</source>
|
||||
<translation>Общо:</translation>
|
||||
|
@ -703,10 +875,26 @@
|
|||
</context>
|
||||
<context>
|
||||
<name>ReceiveCoinsDialog</name>
|
||||
<message>
|
||||
<source>&Amount:</source>
|
||||
<translation>&Сума</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>&Label:</source>
|
||||
<translation>&Име:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Use this form to request payments. All fields are <b>optional</b>.</source>
|
||||
<translation>Използвате този формуляр за заявяване на плащания. Всички полета са <b>незадължителни</b>.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>An optional amount to request. Leave this empty or zero to not request a specific amount.</source>
|
||||
<translation>Незадължително заявяване на сума. Оставете полето празно или нулево, за да не заявите конкретна сума.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Clear all fields of the form.</source>
|
||||
<translation>Изчисти всички полета от формуляра.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Clear</source>
|
||||
<translation>Изчистване</translation>
|
||||
|
@ -734,6 +922,14 @@
|
|||
</context>
|
||||
<context>
|
||||
<name>ReceiveRequestDialog</name>
|
||||
<message>
|
||||
<source>Copy &Address</source>
|
||||
<translation>&Копирай адрес</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>&Save Image...</source>
|
||||
<translation>&Запиши изображение...</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Payment information</source>
|
||||
<translation>Данни за плащането</translation>
|
||||
|
@ -781,7 +977,11 @@
|
|||
<source>(no label)</source>
|
||||
<translation>(без име)</translation>
|
||||
</message>
|
||||
</context>
|
||||
<message>
|
||||
<source>(no amount)</source>
|
||||
<translation>(липсва сума)</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>SendCoinsDialog</name>
|
||||
<message>
|
||||
|
@ -812,6 +1012,10 @@
|
|||
<source>Add &Recipient</source>
|
||||
<translation>Добави &получател</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Clear all fields of the form.</source>
|
||||
<translation>Изчисти всички полета от формуляра.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Clear &All</source>
|
||||
<translation>&Изчисти</translation>
|
||||
|
@ -836,6 +1040,10 @@
|
|||
<source>Copy amount</source>
|
||||
<translation>Копирай сума</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Total Amount %1 (= %2)</source>
|
||||
<translation>Пълна сума %1 (= %2)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>or</source>
|
||||
<translation>или</translation>
|
||||
|
@ -887,6 +1095,10 @@
|
|||
<source>&Label:</source>
|
||||
<translation>&Име:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Choose previously used address</source>
|
||||
<translation>Изберете използван преди адрес</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>This is a normal payment.</source>
|
||||
<translation>Това е нормално плащане.</translation>
|
||||
|
@ -933,6 +1145,10 @@
|
|||
<source>You can sign messages with your addresses to prove you own them. Be careful not to sign anything vague, as phishing attacks may try to trick you into signing your identity over to them. Only sign fully-detailed statements you agree to.</source>
|
||||
<translation>Можете да подпишете съобщение като доказателство, че притежавате определен адрес. Бъдете внимателни и не подписвайте съобщения, които биха разкрили лична информация без вашето съгласие.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Choose previously used address</source>
|
||||
<translation>Изберете използван преди адрес</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Alt+A</source>
|
||||
<translation>Alt+A</translation>
|
||||
|
@ -989,6 +1205,10 @@
|
|||
<source>Please check the address and try again.</source>
|
||||
<translation>Моля проверете адреса и опитайте отново.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>The entered address does not refer to a key.</source>
|
||||
<translation>Въведеният адрес не може да се съпостави с валиден ключ.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Wallet unlock was cancelled.</source>
|
||||
<translation>Отключването на портфейла беше отменено.</translation>
|
||||
|
@ -1028,6 +1248,10 @@
|
|||
</context>
|
||||
<context>
|
||||
<name>SplashScreen</name>
|
||||
<message>
|
||||
<source>The Bitcoin Core developers</source>
|
||||
<translation>Разработчици на Bitcoin Core</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>[testnet]</source>
|
||||
<translation>[testnet]</translation>
|
||||
|
@ -1315,6 +1539,10 @@
|
|||
<source>Copy amount</source>
|
||||
<translation>Копирай сума</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Copy transaction ID</source>
|
||||
<translation>Копирай транзакция с ID</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Edit label</source>
|
||||
<translation>Редактирай име</translation>
|
||||
|
@ -1391,6 +1619,10 @@
|
|||
</context>
|
||||
<context>
|
||||
<name>WalletView</name>
|
||||
<message>
|
||||
<source>&Export</source>
|
||||
<translation>Изнеси</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Export the data in the current tab to a file</source>
|
||||
<translation>Запишете данните от текущия раздел във файл</translation>
|
||||
|
@ -1399,7 +1631,15 @@
|
|||
<source>Backup Wallet</source>
|
||||
<translation>Запазване на портфейла</translation>
|
||||
</message>
|
||||
</context>
|
||||
<message>
|
||||
<source>Backup Failed</source>
|
||||
<translation>Неуспешно запазване на портфейла</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Backup Successful</source>
|
||||
<translation>Успешно запазване на портфейла</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>bitcoin-core</name>
|
||||
<message>
|
||||
|
@ -1410,6 +1650,10 @@
|
|||
<source>Specify data directory</source>
|
||||
<translation>Определете директория за данните</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Specify your own public address</source>
|
||||
<translation>Въведете Ваш публичен адрес</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Use the test network</source>
|
||||
<translation>Използвайте тестовата мрежа</translation>
|
||||
|
@ -1454,6 +1698,14 @@
|
|||
<source>Information</source>
|
||||
<translation>Данни</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Invalid amount for -minrelaytxfee=<amount>: '%s'</source>
|
||||
<translation>Невалидна сума за -minrelaytxfee=<amount>: '%s'</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Invalid amount for -mintxfee=<amount>: '%s'</source>
|
||||
<translation>Невалидна сума за -mintxfee=<amount>: '%s'</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Send trace/debug info to console instead of debug.log file</source>
|
||||
<translation>Изпрати локализиращата или дебъг информацията към конзолата, вместо файлът debug.log</translation>
|
||||
|
@ -1518,6 +1770,10 @@
|
|||
<source>Invalid -proxy address: '%s'</source>
|
||||
<translation>Невалиден -proxy address: '%s'</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Invalid amount for -paytxfee=<amount>: '%s'</source>
|
||||
<translation>Невалидна сума за -paytxfee=<amount>: '%s'</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Insufficient funds</source>
|
||||
<translation>Недостатъчно средства</translation>
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
<TS language="bs" version="2.0">
|
||||
<TS language="bs" version="2.1">
|
||||
<context>
|
||||
<name>AddressBookPage</name>
|
||||
</context>
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
<TS language="ca" version="2.0">
|
||||
<TS language="ca" version="2.1">
|
||||
<context>
|
||||
<name>AddressBookPage</name>
|
||||
<message>
|
||||
<source>Double-click to edit address or label</source>
|
||||
<translation>Feu doble clic per editar l'adreça o l'etiqueta</translation>
|
||||
<source>Right-click to edit address or label</source>
|
||||
<translation>Feu clic dret per a editar l'adreça o l'etiqueta</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Create a new address</source>
|
||||
|
@ -478,6 +478,10 @@
|
|||
<source>Up to date</source>
|
||||
<translation>Al dia</translation>
|
||||
</message>
|
||||
<message numerus="yes">
|
||||
<source>Processed %n blocks of transaction history.</source>
|
||||
<translation><numerusform>S'ha processat %n bloc de l'historial de transacció.</numerusform><numerusform>S'han processat %n blocs de l'historial de transacció.</numerusform></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Catching up...</source>
|
||||
<translation>S'està posant al dia ...</translation>
|
||||
|
@ -516,6 +520,10 @@ Address: %4
|
|||
</context>
|
||||
<context>
|
||||
<name>CoinControlDialog</name>
|
||||
<message>
|
||||
<source>Coin Selection</source>
|
||||
<translation>Selecció de moneda</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Quantity:</source>
|
||||
<translation>Quantitat:</translation>
|
||||
|
@ -534,7 +542,7 @@ Address: %4
|
|||
</message>
|
||||
<message>
|
||||
<source>Fee:</source>
|
||||
<translation>Quota:</translation>
|
||||
<translation>Comissió</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Dust:</source>
|
||||
|
@ -542,7 +550,7 @@ Address: %4
|
|||
</message>
|
||||
<message>
|
||||
<source>After Fee:</source>
|
||||
<translation>Quota posterior:</translation>
|
||||
<translation>Comissió posterior:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Change:</source>
|
||||
|
@ -562,7 +570,15 @@ Address: %4
|
|||
</message>
|
||||
<message>
|
||||
<source>Amount</source>
|
||||
<translation>Quantitat</translation>
|
||||
<translation>Import</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Received with label</source>
|
||||
<translation>Rebut amb l'etiqueta</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Received with address</source>
|
||||
<translation>Rebut amb l'adreça</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Date</source>
|
||||
|
@ -694,7 +710,7 @@ Address: %4
|
|||
</message>
|
||||
<message>
|
||||
<source>This means a fee of at least %1 per kB is required.</source>
|
||||
<translation>Això comporta una comissi d'almenys %1 per kB.</translation>
|
||||
<translation>Això comporta una comissió d'almenys %1 per kB.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Can vary +/- 1 byte per input.</source>
|
||||
|
@ -729,7 +745,7 @@ Address: %4
|
|||
<name>EditAddressDialog</name>
|
||||
<message>
|
||||
<source>Edit Address</source>
|
||||
<translation>Editar Adreça</translation>
|
||||
<translation>Edita l'adreça</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>&Label</source>
|
||||
|
@ -839,7 +855,7 @@ Address: %4
|
|||
</message>
|
||||
<message>
|
||||
<source>Set language, for example "de_DE" (default: system locale)</source>
|
||||
<translation>Defineix un idioma, per exemple "de_DE" (per defecte: preferències locals de sistema)</translation>
|
||||
<translation>Defineix un idioma, per exemple «de_DE» (per defecte: preferències locals de sistema)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Start minimized</source>
|
||||
|
@ -896,7 +912,15 @@ Address: %4
|
|||
<source>Error</source>
|
||||
<translation>Error</translation>
|
||||
</message>
|
||||
</context>
|
||||
<message numerus="yes">
|
||||
<source>%n GB of free space available</source>
|
||||
<translation><numerusform>%n GB d'espai lliure disponible</numerusform><numerusform>%n GB d'espai lliure disponible</numerusform></translation>
|
||||
</message>
|
||||
<message numerus="yes">
|
||||
<source>(of %n GB needed)</source>
|
||||
<translation><numerusform>(de %n GB necessari)</numerusform><numerusform>(de %n GB necessaris)</numerusform></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>OpenURIDialog</name>
|
||||
<message>
|
||||
|
@ -1018,6 +1042,14 @@ Address: %4
|
|||
<source>Map port using &UPnP</source>
|
||||
<translation>Port obert amb &UPnP</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Connect to the Bitcoin network through a SOCKS5 proxy.</source>
|
||||
<translation>Connecta a la xarxa Bitcoin a través d'un proxy SOCKS5.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>&Connect through SOCKS5 proxy (default proxy):</source>
|
||||
<translation>&Connecta a través d'un proxy SOCKS5 (proxy per defecte):</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Proxy &IP:</source>
|
||||
<translation>&IP del proxy:</translation>
|
||||
|
@ -1149,6 +1181,10 @@ Address: %4
|
|||
<source>Mined balance that has not yet matured</source>
|
||||
<translation>Balanç minat que encara no ha madurat</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Balances</source>
|
||||
<translation>Balances</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Total:</source>
|
||||
<translation>Total:</translation>
|
||||
|
@ -1161,6 +1197,14 @@ Address: %4
|
|||
<source>Your current balance in watch-only addresses</source>
|
||||
<translation>El vostre balanç actual en adreces de només lectura</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Spendable:</source>
|
||||
<translation>Que es pot gastar:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Recent transactions</source>
|
||||
<translation>Transaccions recents</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Unconfirmed transactions to watch-only addresses</source>
|
||||
<translation>Transaccions sense confirmar a adreces de només lectura</translation>
|
||||
|
@ -1240,6 +1284,14 @@ Address: %4
|
|||
<source>Refund from %1</source>
|
||||
<translation>Reemborsament de %1</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Payment request %1 is too large (%2 bytes, allowed %3 bytes).</source>
|
||||
<translation>La sol·licitud de pagament %1 és massa gran (%2 bytes, permès %3 bytes).</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Payment request DoS protection</source>
|
||||
<translation>Protecció de DoS per a la sol·licitud de pagament</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Error communicating with %1: %2</source>
|
||||
<translation>Error en comunicar amb %1: %2</translation>
|
||||
|
@ -1280,7 +1332,7 @@ Address: %4
|
|||
<name>QObject</name>
|
||||
<message>
|
||||
<source>Amount</source>
|
||||
<translation>Quantitat</translation>
|
||||
<translation>Import</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Enter a Bitcoin address (e.g. %1)</source>
|
||||
|
@ -1782,7 +1834,7 @@ Address: %4
|
|||
</message>
|
||||
<message>
|
||||
<source>After Fee:</source>
|
||||
<translation>Quota posterior:</translation>
|
||||
<translation>Comissió posterior:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Change:</source>
|
||||
|
@ -1796,6 +1848,78 @@ Address: %4
|
|||
<source>Custom change address</source>
|
||||
<translation>Personalitza l'adreça de canvi</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Transaction Fee:</source>
|
||||
<translation>Comissió de transacció</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Choose...</source>
|
||||
<translation>Tria...</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>collapse fee-settings</source>
|
||||
<translation>redueix els paràmetres de comissió</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Minimize</source>
|
||||
<translation>Minimitza</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>If the custom fee is set to 1000 satoshis and the transaction is only 250 bytes, then "per kilobyte" only pays 250 satoshis in fee, while "at least" pays 1000 satoshis. For transactions bigger than a kilobyte both pay by kilobyte.</source>
|
||||
<translation>Si la comissió personalitzada es defineix a 1000 satoshis i la transacció és de només 250 bytes, llavors «per kilobyte» només es paguen 250 satoshis en una comissió, mentre que amb la de «com a mínim» es pagarien 1000 satoshis. Per a transaccions superiors al kilobyte, en tots dos casos es paga per kilobyte.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>per kilobyte</source>
|
||||
<translation>per kilobyte</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>If the custom fee is set to 1000 satoshis and the transaction is only 250 bytes, then "per kilobyte" only pays 250 satoshis in fee, while "total at least" pays 1000 satoshis. For transactions bigger than a kilobyte both pay by kilobyte.</source>
|
||||
<translation>Si la comissió personalitzada es defineix a 1000 satoshis i la transacció és de només 250 bytes, llavors «per kilobyte» només es paguen 250 satoshis en una comissió, mentre que amb la de «total com a mínim» es pagarien 1000 satoshis. Per a transaccions superiors al kilobyte, en tots dos casos es paga per kilobyte.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>total at least</source>
|
||||
<translation>total com a mínim</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Paying only the minimum fee is just fine as long as there is less transaction volume than space in the blocks. But be aware that this can end up in a never confirming transaction once there is more demand for bitcoin transactions than the network can process.</source>
|
||||
<translation>No hi ha cap problema en pagar només la comissió mínima sempre que hi hagi menys volum de transacció que espai en els blocs. Però tingueu present que això pot acabar en una transacció que mai es confirmi una vegada hi hagi més demanda de transaccions de bitcoins que la xarxa pugui processar.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>(read the tooltip)</source>
|
||||
<translation>(llegiu l'indicador de funció)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Recommended:</source>
|
||||
<translation>Recomanada:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Custom:</source>
|
||||
<translation>Personalitzada:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>(Smart fee not initialized yet. This usually takes a few blocks...)</source>
|
||||
<translation>(No s'ha inicialitzat encara la comissió intel·ligent. Normalment pren uns pocs blocs...)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Confirmation time:</source>
|
||||
<translation>Temps de confirmació:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>normal</source>
|
||||
<translation>normal</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>fast</source>
|
||||
<translation>ràpid</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Send as zero-fee transaction if possible</source>
|
||||
<translation>Envia com a transacció de comissió zero si és possible</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>(confirmation may take longer)</source>
|
||||
<translation>(la confirmació pot trigar més temps)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Send to multiple recipients at once</source>
|
||||
<translation>Envia a múltiples destinataris al mateix temps</translation>
|
||||
|
@ -1846,7 +1970,7 @@ Address: %4
|
|||
</message>
|
||||
<message>
|
||||
<source>Copy fee</source>
|
||||
<translation>Copia la comissi</translation>
|
||||
<translation>Copia la comissió</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Copy after fee</source>
|
||||
|
@ -1886,7 +2010,7 @@ Address: %4
|
|||
</message>
|
||||
<message>
|
||||
<source>The total exceeds your balance when the %1 transaction fee is included.</source>
|
||||
<translation>El total excedeix el teu balanç quan s'afegeix la comisió a la transacció %1.</translation>
|
||||
<translation>El total excedeix el teu balanç quan s'afegeix la comissió a la transacció %1.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Duplicate address found, can only send to each address once per send operation.</source>
|
||||
|
@ -1900,6 +2024,18 @@ Address: %4
|
|||
<source>The transaction was rejected! This might happen if some of the coins in your wallet were already spent, such as if you used a copy of wallet.dat and coins were spent in the copy but not marked as spent here.</source>
|
||||
<translation>S'ha rebutjat la transacció! Això pot passar si alguna de les monedes del vostre moneder ja s'han gastat; per exemple, si heu fet servir una còpia de seguretat del fitxer wallet.dat i s'haguessin gastat monedes de la còpia però sense marcar-les-hi com a gastades.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>A fee higher than %1 is considered an insanely high fee.</source>
|
||||
<translation>Una comissió superior a %1 es considera una comissió excessiva.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Pay only the minimum fee of %1</source>
|
||||
<translation>Paga només la comissió mínima de %1</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Estimated to begin confirmation within %1 block(s).</source>
|
||||
<translation>Estimat per a començar la confirmació en %1 bloc(s).</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Warning: Invalid Bitcoin address</source>
|
||||
<translation>Avís: adreça Bitcoin no vàlida</translation>
|
||||
|
@ -2300,7 +2436,7 @@ Address: %4
|
|||
</message>
|
||||
<message>
|
||||
<source>Amount</source>
|
||||
<translation>Quantitat</translation>
|
||||
<translation>Import</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>true</source>
|
||||
|
@ -2428,6 +2564,10 @@ Address: %4
|
|||
<source>Type of transaction.</source>
|
||||
<translation>Tipus de transacció.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Whether or not a watch-only address is involved in this transaction.</source>
|
||||
<translation>Si està implicada o no una adreça només de lectura en la transacció.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Destination address of transaction.</source>
|
||||
<translation>Adreça del destinatari de la transacció.</translation>
|
||||
|
@ -2523,6 +2663,10 @@ Address: %4
|
|||
<source>Export Transaction History</source>
|
||||
<translation>Exporta l'historial de transacció</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Watch-only</source>
|
||||
<translation>Només de lectura</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Exporting Failed</source>
|
||||
<translation>L'exportació ha fallat</translation>
|
||||
|
@ -2666,29 +2810,6 @@ Address: %4
|
|||
<source>Accept connections from outside (default: 1 if no -proxy or -connect)</source>
|
||||
<translation>Accepta connexions de fora (per defecte: 1 si no -proxy o -connect)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>%s, you must set a rpcpassword in the configuration file:
|
||||
%s
|
||||
It is recommended you use the following random password:
|
||||
rpcuser=bitcoinrpc
|
||||
rpcpassword=%s
|
||||
(you do not need to remember this password)
|
||||
The username and password MUST NOT be the same.
|
||||
If the file does not exist, create it with owner-readable-only file permissions.
|
||||
It is also recommended to set alertnotify so you are notified of problems;
|
||||
for example: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com
|
||||
</source>
|
||||
<translation>%s, heu de establir una contrasenya RPC al fitxer de configuració: %s
|
||||
Es recomana que useu la següent contrasenya aleatòria:
|
||||
rpcuser=bitcoinrpc
|
||||
rpcpassword=%s
|
||||
(no necesiteu recordar aquesta contrasenya)
|
||||
El nom d'usuari i la contrasenya NO HAN de ser els mateixos.
|
||||
Si el fitxer no existeix, crea'l amb els permisos de fitxer de només lectura per al propietari.
|
||||
També es recomana establir la notificació d'alertes i així sereu notificat de les incidències;
|
||||
per exemple: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com
|
||||
</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Bind to given address and always listen on it. Use [host]:port notation for IPv6</source>
|
||||
<translation>Vincula a una adreça específica i sempre escolta-hi. Utilitza la notació [host]:port per IPv6</translation>
|
||||
|
@ -2697,18 +2818,14 @@ per exemple: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com
|
|||
<source>Delete all wallet transactions and only recover those parts of the blockchain through -rescan on startup</source>
|
||||
<translation>Elimina totes les transaccions del moneder i només recupera aquelles de la cadena de blocs a través de -rescan a l'inici</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Distributed under the MIT software license, see the accompanying file COPYING or <http://www.opensource.org/licenses/mit-license.php>.</source>
|
||||
<translation>Distribuït sota llicència de programari MIT. Vegeu el fitxer acompanyant COPYING o <http://www.opensource.org/licenses/mit-license.php>.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Enter regression test mode, which uses a special chain in which blocks can be solved instantly.</source>
|
||||
<translation>Entra en el mode de proves de regressió, que utilitza una cadena especial en què els blocs poden resoldre's al moment.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Error: The transaction was rejected! This might happen if some of the coins in your wallet were already spent, such as if you used a copy of wallet.dat and coins were spent in the copy but not marked as spent here.</source>
|
||||
<translation>Error: La transacció ha estat rebutjada. Això pot passar si alguna de les monedes del teu moneder ja s'han gastat, com si haguesis usat una copia de l'arxiu wallet.dat i s'haguessin gastat monedes de la copia però sense marcar com gastades en aquest.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Error: This transaction requires a transaction fee of at least %s because of its amount, complexity, or use of recently received funds!</source>
|
||||
<translation>Error: Aquesta transacció requereix una comissió d'almenys %s degut al seu import, complexitat o per l'ús de fons recentment rebuts!</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Execute command when a wallet transaction changes (%s in cmd is replaced by TxID)</source>
|
||||
<translation>Executa una ordre quan una transacció del moneder canviï (%s en cmd es canvia per TxID)</translation>
|
||||
|
@ -2749,6 +2866,10 @@ per exemple: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com
|
|||
<source>Warning: wallet.dat corrupt, data salvaged! Original wallet.dat saved as wallet.{timestamp}.bak in %s; if your balance or transactions are incorrect you should restore from a backup.</source>
|
||||
<translation>Avís: el fitxer wallet.dat és corrupte, dades rescatades! L'arxiu wallet.dat original ha estat desat com wallet.{estampa_temporal}.bak al directori %s; si el teu balanç o transaccions son incorrectes hauries de restaurar-lo de un backup.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Whitelist peers connecting from the given netmask or IP address. Can be specified multiple times.</source>
|
||||
<translation>Afegeix a la llista blanca els iguals que es connecten de la màscara de xarxa o adreça IP donada. Es pot especificar moltes vegades.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>(default: 1)</source>
|
||||
<translation>(per defecte: 1)</translation>
|
||||
|
@ -2810,12 +2931,12 @@ per exemple: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com
|
|||
<translation>Error en obrir la base de dades de blocs</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Error: Disk space is low!</source>
|
||||
<translation>Error: Espai al disc baix!</translation>
|
||||
<source>Error: A fatal internal error occured, see debug.log for details</source>
|
||||
<translation>Error: s'ha produït un error intern fatal. Consulteu debug.log per a més detalls</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Error: Wallet locked, unable to create transaction!</source>
|
||||
<translation>Error: El moneder està bloquejat, no és possible crear la transacció!</translation>
|
||||
<source>Error: Disk space is low!</source>
|
||||
<translation>Error: Espai al disc baix!</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Failed to listen on any port. Use -listen=0 if you want this.</source>
|
||||
|
@ -2841,6 +2962,10 @@ per exemple: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com
|
|||
<source>Not enough file descriptors available.</source>
|
||||
<translation>No hi ha suficient descriptors de fitxers disponibles.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Only connect to nodes in network <net> (ipv4, ipv6 or onion)</source>
|
||||
<translation>Només connecta als nodes de la xarxa <net> (ipv4, ipv6 o onion)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Rebuild block chain index from current blk000??.dat files</source>
|
||||
<translation>Reconstrueix l'índex de la cadena de blocs dels fitxers actuals blk000??.dat</translation>
|
||||
|
@ -2861,6 +2986,10 @@ per exemple: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com
|
|||
<source>This is intended for regression testing tools and app development.</source>
|
||||
<translation>Això es així per a eines de proves de regressió per al desenvolupament d'aplicacions.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Use UPnP to map the listening port (default: %u)</source>
|
||||
<translation>Utilitza UPnP per a mapejar el port d'escolta (per defecte: %u)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Verifying blocks...</source>
|
||||
<translation>S'estan verificant els blocs...</translation>
|
||||
|
@ -2901,6 +3030,10 @@ per exemple: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com
|
|||
<source>Cannot obtain a lock on data directory %s. Bitcoin Core is probably already running.</source>
|
||||
<translation>No es pot obtenir un bloqueig del directori de dades %s. El Bitcoin Core probablement ja s'estigui executant.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Continuously rate-limit free transactions to <n>*1000 bytes per minute (default:%u)</source>
|
||||
<translation>Limita contínuament la freqüència de les transaccions gratuïtes a <n>*1000 bytes per minut (per defecte: %u)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Create new files with system default permissions, instead of umask 077 (only effective with disabled wallet functionality)</source>
|
||||
<translation>Crea fitxers nous amb els permisos per defecte del sistema, en comptes de l'umask 077 (només efectiu amb la funcionalitat de moneder inhabilitada)</translation>
|
||||
|
@ -2925,18 +3058,69 @@ per exemple: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com
|
|||
<source>Fees (in BTC/Kb) smaller than this are considered zero fee for transaction creation (default: %s)</source>
|
||||
<translation>Comissions (en BTC/Kb) inferiors a això es consideren de comissió zero per a la creació de la transacció (per defecte: %s)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>If paytxfee is not set, include enough fee so transactions begin confirmation on average within n blocks (default: %u)</source>
|
||||
<translation>Si no s'especifica una paytxfee (comissió de transacció de pagament), inclogueu suficient comissió per tal que les transaccions comencin a confirmar-se en una mitja de n blocs (per defecte: %u)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Invalid amount for -maxtxfee=<amount>: '%s' (must be at least the minrelay fee of %s to prevent stuck transactions)</source>
|
||||
<translation>Import no vàlid per a -maxtxfee=<amount>: '%s' (cal que sigui com a mínim la comissió de minrelay de %s per evitar que les comissions s'encallin)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Maximum size of data in data carrier transactions we relay and mine (default: %u)</source>
|
||||
<translation>Mida màxima de les dades en les transaccions de l'operador en què confiem i en les meves (per defecte: %u)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Maximum total fees to use in a single wallet transaction, setting too low may abort large transactions (default: %s)</source>
|
||||
<translation>Comissions totals màximes que s'utilitzaran en una transacció d'un únic moneder. Si es defineix un valor massa baix les transaccions més grans poden interrompre's (per defecte: %s)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Query for peer addresses via DNS lookup, if low on addresses (default: 1 unless -connect)</source>
|
||||
<translation>Consulta a adreces d'iguals a través de DNS, si es troba baix en adreces (per defecte: 1 a menys que -connect)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Require high priority for relaying free or low-fee transactions (default:%u)</source>
|
||||
<translation>Es requereix una prioritat alta per retransmetre transaccions gratuïtes o de baixa comissió (per defecte:%u)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Set maximum size of high-priority/low-fee transactions in bytes (default: %d)</source>
|
||||
<translation>Defineix la mida màxima de transaccions d'alta prioritat / baixa comissió en bytes (per defecte: %d)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Set the number of threads for coin generation if enabled (-1 = all cores, default: %d)</source>
|
||||
<translation>Defineix el nombre de fils per a la generació de moneda si està habilitat (-1 = tots els nuclis, per defecte: %d)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>This product includes software developed by the OpenSSL Project for use in the OpenSSL Toolkit <https://www.openssl.org/> and cryptographic software written by Eric Young and UPnP software written by Thomas Bernard.</source>
|
||||
<translation>Aquest producte inclou programari desenvolupat pel projecte OpenSSL per a ús a l'OpenSSL Toolkit <https://www.openssl.org/> i programari criptogràfic escrit per Eric Young i programari UPnP escrit per Thomas Bernard.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>To use bitcoind, or the -server option to bitcoin-qt, you must set an rpcpassword in the configuration file:
|
||||
%s
|
||||
It is recommended you use the following random password:
|
||||
rpcuser=bitcoinrpc
|
||||
rpcpassword=%s
|
||||
(you do not need to remember this password)
|
||||
The username and password MUST NOT be the same.
|
||||
If the file does not exist, create it with owner-readable-only file permissions.
|
||||
It is also recommended to set alertnotify so you are notified of problems;
|
||||
for example: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com
|
||||
</source>
|
||||
<translation>Per utilitzar bitcoind, o l'opció de serviddor de bitcoin-qt, heu de definir una rpcpassword en el fitxer de configuració:
|
||||
%s
|
||||
Es recomana que utilitzeu la contrasenya aleatòria següent:
|
||||
rpcuser=bitcoinrpc
|
||||
rpcpassword=%s
|
||||
(no cal que recordeu la contrasenya)
|
||||
El nom d'usuari i la contrasenya NO han de ser els mateixos.
|
||||
Si el fitxer no existeix, creeu-ne un amb permisos de lectura només per al seu propietari.
|
||||
Es recomana definir alertnotify per tal de ser notificat de qualsevol problema;
|
||||
per exemple: alertnotify=echo %%s | mail -s "Avís de Bitcoin" admin@foo.com</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Warning: -maxtxfee is set very high! Fees this large could be paid on a single transaction.</source>
|
||||
<translation>Avís: s'ha especificat un -maxtxfee molt alt! Comissions tan grans podrien pagar-se en una única transacció.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Warning: Please check that your computer's date and time are correct! If your clock is wrong Bitcoin Core will not work properly.</source>
|
||||
<translation>Avís: comproveu que la data i hora del vostre ordinador siguin correctes! Si el vostre rellotge no és correcte, el Bitcoin Core no funcionarà correctament.</translation>
|
||||
|
@ -2945,6 +3129,10 @@ per exemple: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com
|
|||
<source>Whitelisted peers cannot be DoS banned and their transactions are always relayed, even if they are already in the mempool, useful e.g. for a gateway</source>
|
||||
<translation>Els iguals en la llista blanca no poden ser bandejats per DoS i es transmetran sempre llurs transaccions, fins i tot si ja són a la mempool. Això és útil, p. ex., per a una passarel·la</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Accept public REST requests (default: %u)</source>
|
||||
<translation>Accepta sol·licituds REST públiques (per defecte: %u)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Cannot resolve -whitebind address: '%s'</source>
|
||||
<translation>No es pot resoldre l'adreça -whitebind: «%s»</translation>
|
||||
|
@ -2965,6 +3153,10 @@ per exemple: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com
|
|||
<source>Error loading wallet.dat: Wallet requires newer version of Bitcoin Core</source>
|
||||
<translation>Error en carregar wallet.dat: el moneder requereix una versió més nova del Bitcoin core</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Error reading from database, shutting down.</source>
|
||||
<translation>Error en llegir la base de dades, tancant.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Error: Unsupported argument -tor found, use -onion.</source>
|
||||
<translation>Error: s'ha trobat un argument -tor no acceptat. Feu servir -onion.</translation>
|
||||
|
@ -2981,6 +3173,10 @@ per exemple: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com
|
|||
<source>Initialization sanity check failed. Bitcoin Core is shutting down.</source>
|
||||
<translation>Ha fallat la inicialització de la comprovació de validesa. El Bitcoin Core s'està aturant.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Invalid amount for -maxtxfee=<amount>: '%s'</source>
|
||||
<translation>Import no vàlid per a -maxtxfee=<amount>: '%s'</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Invalid amount for -minrelaytxfee=<amount>: '%s'</source>
|
||||
<translation>Import no vàlid per a -minrelaytxfee=<amount>: «%s»</translation>
|
||||
|
@ -2998,8 +3194,8 @@ per exemple: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com
|
|||
<translation>S'ha especificat una màscara de xarxa no vàlida a -whitelist: «%s»</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Keep at most <n> unconnectable blocks in memory (default: %u)</source>
|
||||
<translation>Manté com a màxim <n> blocs no connectables en memòria (per defecte: %u)</translation>
|
||||
<source>Keep at most <n> unconnectable transactions in memory (default: %u)</source>
|
||||
<translation>Manté com a màxim <n> transaccions no connectables en memòria (per defecte: %u)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Need to specify a port with -whitebind: '%s'</source>
|
||||
|
@ -3009,10 +3205,6 @@ per exemple: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com
|
|||
<source>Node relay options:</source>
|
||||
<translation>Opcions de transmissió del node:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Print block on startup, if found in block index</source>
|
||||
<translation>Imprimeix el block a l'inici, si es troba l'índex de blocs</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>RPC SSL options: (see the Bitcoin Wiki for SSL setup instructions)</source>
|
||||
<translation>Opcions RPC SSL: (veieu el wiki del Bitcoin per a instruccions de configuració de l'SSL)</translation>
|
||||
|
@ -3021,6 +3213,10 @@ per exemple: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com
|
|||
<source>RPC server options:</source>
|
||||
<translation>Opcions del servidor RPC:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>RPC support for HTTP persistent connections (default: %d)</source>
|
||||
<translation>Suport RPC per a connexions HTTP persistents (per defecte: %d)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Randomly drop 1 of every <n> network messages</source>
|
||||
<translation>Descarta a l'atzar 1 de cada <n> missatges de la xarxa</translation>
|
||||
|
@ -3033,6 +3229,10 @@ per exemple: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com
|
|||
<source>Send trace/debug info to console instead of debug.log file</source>
|
||||
<translation>Envia informació de traça/depuració a la consola en comptes del fitxer debug.log</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Send transactions as zero-fee transactions if possible (default: %u)</source>
|
||||
<translation>Envia les transaccions com a transaccions de comissió zero sempre que sigui possible (per defecte: %u) </translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Show all debugging options (usage: --help -help-debug)</source>
|
||||
<translation>Mostra totes les opcions de depuració (ús: --help --help-debug)</translation>
|
||||
|
@ -3057,6 +3257,10 @@ per exemple: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com
|
|||
<source>Transaction amounts must be positive</source>
|
||||
<translation>Els imports de les transaccions han de ser positius</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Transaction too large for fee policy</source>
|
||||
<translation>Transacció massa gran per a la política de comissions</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Transaction too large</source>
|
||||
<translation>La transacció és massa gran</translation>
|
||||
|
@ -3141,14 +3345,170 @@ per exemple: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com
|
|||
<source>Error loading wallet.dat: Wallet corrupted</source>
|
||||
<translation>Error en carregar wallet.dat: Moneder corrupte</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>(1 = keep tx meta data e.g. account owner and payment request information, 2 = drop tx meta data)</source>
|
||||
<translation>(1 = manté les metadades de les tx, p. ex., propietari del compte i informació de sol·licitud del pagament, 2 = prescindeix de les metadades de les tx)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Flush database activity from memory pool to disk log every <n> megabytes (default: %u)</source>
|
||||
<translation>Buida l'activitat de la base de dades de la memòria disponible al registre del disc cada <n> megabytes (per defecte: %u)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>How thorough the block verification of -checkblocks is (0-4, default: %u)</source>
|
||||
<translation>Com d'exhaustiva és la verificació de blocs del -checkblocks (0-4, per defecte: %u)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Log transaction priority and fee per kB when mining blocks (default: %u)</source>
|
||||
<translation>Enregistreu la prioritat de la transacció i la comissió per kB en minar blocs (per defecte: %u)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Maintain a full transaction index, used by the getrawtransaction rpc call (default: %u)</source>
|
||||
<translation>Manté un índex complet de transaccions, utilitzat per la crida rpc getrawtransaction (per defecte: %u)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Number of seconds to keep misbehaving peers from reconnecting (default: %u)</source>
|
||||
<translation>Nombre de segons necessaris perquè els iguals de comportament qüestionable puguin tornar a connectar-se (per defecte: %u)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Output debugging information (default: %u, supplying <category> is optional)</source>
|
||||
<translation>Informació de sortida de la depuració (per defecte: %u, proporcionar <category> és opcional)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Use separate SOCKS5 proxy to reach peers via Tor hidden services (default: %s)</source>
|
||||
<translation>Utilitza un proxy SOCKS4 apart per a arribar als iguals a través de serveis ocults de Tor (per defecte: %s)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>(default: %s)</source>
|
||||
<translation>(per defecte: %s)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Acceptable ciphers (default: %s)</source>
|
||||
<translation>Xifrats acceptables (per defecte: %s)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Always query for peer addresses via DNS lookup (default: %u)</source>
|
||||
<translation>Demana sempre les adreces dels iguals a través de consultes DNS (per defecte: %u)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Disable safemode, override a real safe mode event (default: %u)</source>
|
||||
<translation>Inhabilita el mode segur, sobreescriu un esdeveniment de mode segur real (per defecte: %u) </translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Error loading wallet.dat</source>
|
||||
<translation>Error en carregar wallet.dat</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Force safe mode (default: %u)</source>
|
||||
<translation>Força el mode segur (per defecte: %u)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Generate coins (default: %u)</source>
|
||||
<translation>Genera monedes (per defecte: %u)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>How many blocks to check at startup (default: %u, 0 = all)</source>
|
||||
<translation>Quants blocs per comprovar a l'inici (per defecte: %u, 0 = tots)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Include IP addresses in debug output (default: %u)</source>
|
||||
<translation>Inclou l'adreça IP a la sortida de depuració (per defecte: %u)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Invalid -proxy address: '%s'</source>
|
||||
<translation>Adreça -proxy invalida: '%s'</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Limit size of signature cache to <n> entries (default: %u)</source>
|
||||
<translation>Limita la mida de la cau de signatura a <n> entrades (per defecte: %u)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Listen for JSON-RPC connections on <port> (default: %u or testnet: %u)</source>
|
||||
<translation>Escolta les connexions JSON-RPC en <port> (per defecte: %u o testnet: %u)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Listen for connections on <port> (default: %u or testnet: %u)</source>
|
||||
<translation>Escolta les connexions en <port> (per defecte: %u o testnet: %u)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Maintain at most <n> connections to peers (default: %u)</source>
|
||||
<translation>Manté com a màxim <n> connexions a iguals (per defecte: %u)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Maximum per-connection receive buffer, <n>*1000 bytes (default: %u)</source>
|
||||
<translation>Memòria intermèdia màxima de recepció per connexió, <n>*1000 bytes (per defecte: %u)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Maximum per-connection send buffer, <n>*1000 bytes (default: %u)</source>
|
||||
<translation>Memòria intermèdia màxima d'enviament per connexió, <n>*1000 bytes (per defecte: %u)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Only accept block chain matching built-in checkpoints (default: %u)</source>
|
||||
<translation>Només accepta els punts de control integrats que coincideixen amb la cadena de blocs (per defecte: %u)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Prepend debug output with timestamp (default: %u)</source>
|
||||
<translation>Posa davant de la sortida de depuració una marca horària (per defecte: %u)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Relay and mine data carrier transactions (default: %u)</source>
|
||||
<translation>Retransmet i mina les transaccions de l'operador (per defecte: %u)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Relay non-P2SH multisig (default: %u)</source>
|
||||
<translation>Retransmet multisig no P2SH (per defecte: %u)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Run a thread to flush wallet periodically (default: %u)</source>
|
||||
<translation>Executa un fil per buidar el moneder periòdicament (per defecte: %u)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Server certificate file (default: %s)</source>
|
||||
<translation>Fitxer de certificat del servidor (per defecte: %s)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Server private key (default: %s)</source>
|
||||
<translation>Clau privada del servidor (per defecte: %s)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Set key pool size to <n> (default: %u)</source>
|
||||
<translation>Defineix la mida clau disponible a <n> (per defecte: %u)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Set minimum block size in bytes (default: %u)</source>
|
||||
<translation>Defineix la mida de bloc mínima en bytes (per defecte: %u)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Set the number of threads to service RPC calls (default: %d)</source>
|
||||
<translation>Defineix el nombre de fils a crides de servei RPC (per defecte: %d)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Sets the DB_PRIVATE flag in the wallet db environment (default: %u)</source>
|
||||
<translation>Defineix el senyalador DB_PRIVATE en l'entorn db del moneder (per defecte: %u)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Specify configuration file (default: %s)</source>
|
||||
<translation>Especifica el fitxer de configuració (per defecte: %s)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Specify connection timeout in milliseconds (minimum: 1, default: %d)</source>
|
||||
<translation>Especifica el temps d'espera de la connexió en milisegons (mínim: 1, per defecte: %d)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Specify pid file (default: %s)</source>
|
||||
<translation>Especifica el fitxer pid (per defecte: %s)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Spend unconfirmed change when sending transactions (default: %u)</source>
|
||||
<translation>Gasta el canvi no confirmat en enviar les transaccions (per defecte: %u)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Stop running after importing blocks from disk (default: %u)</source>
|
||||
<translation>Atura l'execució després d'importar blocs del disc (per defecte: %u)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Threshold for disconnecting misbehaving peers (default: %u)</source>
|
||||
<translation>Llindar per a desconnectar els iguals de comportament qüestionable (per defecte: %u)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Unknown network specified in -onlynet: '%s'</source>
|
||||
<translation>Xarxa desconeguda especificada a -onlynet: '%s'</translation>
|
||||
|
@ -3165,10 +3525,6 @@ per exemple: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com
|
|||
<source>Invalid amount for -paytxfee=<amount>: '%s'</source>
|
||||
<translation>Import no vàlid per a -paytxfee=<amount>: «%s»</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Invalid amount</source>
|
||||
<translation>Import no vàlid</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Insufficient funds</source>
|
||||
<translation>Balanç insuficient</translation>
|
||||
|
@ -3201,10 +3557,6 @@ per exemple: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com
|
|||
<source>Done loading</source>
|
||||
<translation>Ha acabat la càrrega</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>To use the %s option</source>
|
||||
<translation>Utilitza l'opció %s</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Error</source>
|
||||
<translation>Error</translation>
|
||||
|
|
|
@ -1,10 +1,6 @@
|
|||
<TS language="ca@valencia" version="2.0">
|
||||
<TS language="ca@valencia" version="2.1">
|
||||
<context>
|
||||
<name>AddressBookPage</name>
|
||||
<message>
|
||||
<source>Double-click to edit address or label</source>
|
||||
<translation>Feu doble clic per editar l'adreça o l'etiqueta</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Create a new address</source>
|
||||
<translation>Crea una nova adreça</translation>
|
||||
|
@ -2630,29 +2626,6 @@ Address: %4
|
|||
<source>Accept connections from outside (default: 1 if no -proxy or -connect)</source>
|
||||
<translation>Accepta connexions de fora (per defecte: 1 si no -proxy o -connect)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>%s, you must set a rpcpassword in the configuration file:
|
||||
%s
|
||||
It is recommended you use the following random password:
|
||||
rpcuser=bitcoinrpc
|
||||
rpcpassword=%s
|
||||
(you do not need to remember this password)
|
||||
The username and password MUST NOT be the same.
|
||||
If the file does not exist, create it with owner-readable-only file permissions.
|
||||
It is also recommended to set alertnotify so you are notified of problems;
|
||||
for example: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com
|
||||
</source>
|
||||
<translation>%s, heu d'establir una contrasenya RPC al fitxer de configuració: %s
|
||||
Es recomana que useu la següent contrasenya aleatòria:
|
||||
rpcuser=bitcoinrpc
|
||||
rpcpassword=%s
|
||||
(no necesiteu recordar esta contrasenya)
|
||||
El nom d'usuari i la contrasenya NO HAN de ser els mateixos.
|
||||
Si el fitxer no existeix, crea'l amb els permisos de fitxer de només lectura per al propietari.
|
||||
També es recomana establir la notificació d'alertes i així sereu notificat de les incidències;
|
||||
per exemple: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com
|
||||
</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Bind to given address and always listen on it. Use [host]:port notation for IPv6</source>
|
||||
<translation>Vincula a una adreça específica i sempre escolta-hi. Utilitza la notació [host]:port per IPv6</translation>
|
||||
|
@ -2665,14 +2638,6 @@ per exemple: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com
|
|||
<source>Enter regression test mode, which uses a special chain in which blocks can be solved instantly.</source>
|
||||
<translation>Entra en el mode de proves de regressió, que utilitza una cadena especial en què els blocs poden resoldre's al moment.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Error: The transaction was rejected! This might happen if some of the coins in your wallet were already spent, such as if you used a copy of wallet.dat and coins were spent in the copy but not marked as spent here.</source>
|
||||
<translation>Error: La transacció ha estat rebutjada. Això pot passar si alguna de les monedes del teu moneder ja s'han gastat, com si haguesis usat una copia de l'arxiu wallet.dat i s'hagueren gastat monedes de la copia però sense marcar com gastades en este.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Error: This transaction requires a transaction fee of at least %s because of its amount, complexity, or use of recently received funds!</source>
|
||||
<translation>Error: Esta transacció requereix una comissió d'almenys %s degut al seu import, complexitat o per l'ús de fons recentment rebuts!</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Execute command when a wallet transaction changes (%s in cmd is replaced by TxID)</source>
|
||||
<translation>Executa una orde quan una transacció del moneder canvie (%s en cmd es canvia per TxID)</translation>
|
||||
|
@ -2777,10 +2742,6 @@ per exemple: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com
|
|||
<source>Error: Disk space is low!</source>
|
||||
<translation>Error: Espai al disc baix!</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Error: Wallet locked, unable to create transaction!</source>
|
||||
<translation>Error: El moneder està bloquejat, no és possible crear la transacció!</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Failed to listen on any port. Use -listen=0 if you want this.</source>
|
||||
<translation>Ha fallat escoltar a qualsevol port. Feu servir -listen=0 si voleu fer això.</translation>
|
||||
|
@ -2961,10 +2922,6 @@ per exemple: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com
|
|||
<source>Invalid netmask specified in -whitelist: '%s'</source>
|
||||
<translation>S'ha especificat una màscara de xarxa no vàlida a -whitelist: «%s»</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Keep at most <n> unconnectable blocks in memory (default: %u)</source>
|
||||
<translation>Manté com a màxim <n> blocs no connectables en memòria (per defecte: %u)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Need to specify a port with -whitebind: '%s'</source>
|
||||
<translation>Cal especificar un port amb -whitebind: «%s»</translation>
|
||||
|
@ -2973,10 +2930,6 @@ per exemple: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com
|
|||
<source>Node relay options:</source>
|
||||
<translation>Opcions de transmissió del node:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Print block on startup, if found in block index</source>
|
||||
<translation>Imprimeix el block a l'inici, si es troba l'índex de blocs</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>RPC SSL options: (see the Bitcoin Wiki for SSL setup instructions)</source>
|
||||
<translation>Opcions RPC SSL: (veieu el wiki del Bitcoin per a instruccions de configuració de l'SSL)</translation>
|
||||
|
@ -3129,10 +3082,6 @@ per exemple: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com
|
|||
<source>Invalid amount for -paytxfee=<amount>: '%s'</source>
|
||||
<translation>Import no vàlid per a -paytxfee=<amount>: «%s»</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Invalid amount</source>
|
||||
<translation>Import no vàlid</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Insufficient funds</source>
|
||||
<translation>Balanç insuficient</translation>
|
||||
|
@ -3165,10 +3114,6 @@ per exemple: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com
|
|||
<source>Done loading</source>
|
||||
<translation>Ha acabat la càrrega</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>To use the %s option</source>
|
||||
<translation>Utilitza l'opció %s</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Error</source>
|
||||
<translation>Error</translation>
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
<TS language="ca_ES" version="2.0">
|
||||
<TS language="ca_ES" version="2.1">
|
||||
<context>
|
||||
<name>AddressBookPage</name>
|
||||
<message>
|
||||
<source>Double-click to edit address or label</source>
|
||||
<translation>Feu doble clic per editar l'adreça o l'etiqueta</translation>
|
||||
<source>Right-click to edit address or label</source>
|
||||
<translation>Feu clic dret per a editar l'adreça o l'etiqueta</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Create a new address</source>
|
||||
|
@ -478,6 +478,10 @@
|
|||
<source>Up to date</source>
|
||||
<translation>Al dia</translation>
|
||||
</message>
|
||||
<message numerus="yes">
|
||||
<source>Processed %n blocks of transaction history.</source>
|
||||
<translation><numerusform>S'ha processat %n bloc de l'historial de transacció.</numerusform><numerusform>S'han processat %n blocs de l'historial de transacció.</numerusform></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Catching up...</source>
|
||||
<translation>S'està posant al dia ...</translation>
|
||||
|
@ -516,6 +520,10 @@ Address: %4
|
|||
</context>
|
||||
<context>
|
||||
<name>CoinControlDialog</name>
|
||||
<message>
|
||||
<source>Coin Selection</source>
|
||||
<translation>Selecció de moneda</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Quantity:</source>
|
||||
<translation>Quantitat:</translation>
|
||||
|
@ -534,7 +542,7 @@ Address: %4
|
|||
</message>
|
||||
<message>
|
||||
<source>Fee:</source>
|
||||
<translation>Quota:</translation>
|
||||
<translation>Comissió</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Dust:</source>
|
||||
|
@ -542,7 +550,7 @@ Address: %4
|
|||
</message>
|
||||
<message>
|
||||
<source>After Fee:</source>
|
||||
<translation>Quota posterior:</translation>
|
||||
<translation>Comissió posterior:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Change:</source>
|
||||
|
@ -562,7 +570,15 @@ Address: %4
|
|||
</message>
|
||||
<message>
|
||||
<source>Amount</source>
|
||||
<translation>Quantitat</translation>
|
||||
<translation>Import</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Received with label</source>
|
||||
<translation>Rebut amb l'etiqueta</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Received with address</source>
|
||||
<translation>Rebut amb l'adreça</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Date</source>
|
||||
|
@ -694,7 +710,7 @@ Address: %4
|
|||
</message>
|
||||
<message>
|
||||
<source>This means a fee of at least %1 per kB is required.</source>
|
||||
<translation>Això comporta una comissi d'almenys %1 per kB.</translation>
|
||||
<translation>Això comporta una comissió d'almenys %1 per kB.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Can vary +/- 1 byte per input.</source>
|
||||
|
@ -729,7 +745,7 @@ Address: %4
|
|||
<name>EditAddressDialog</name>
|
||||
<message>
|
||||
<source>Edit Address</source>
|
||||
<translation>Editar Adreça</translation>
|
||||
<translation>Edita l'adreça</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>&Label</source>
|
||||
|
@ -839,7 +855,7 @@ Address: %4
|
|||
</message>
|
||||
<message>
|
||||
<source>Set language, for example "de_DE" (default: system locale)</source>
|
||||
<translation>Defineix un idioma, per exemple "de_DE" (per defecte: preferències locals de sistema)</translation>
|
||||
<translation>Defineix un idioma, per exemple «de_DE» (per defecte: preferències locals de sistema)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Start minimized</source>
|
||||
|
@ -896,7 +912,15 @@ Address: %4
|
|||
<source>Error</source>
|
||||
<translation>Error</translation>
|
||||
</message>
|
||||
</context>
|
||||
<message numerus="yes">
|
||||
<source>%n GB of free space available</source>
|
||||
<translation><numerusform>%n GB d'espai lliure disponible</numerusform><numerusform>%n GB d'espai lliure disponible</numerusform></translation>
|
||||
</message>
|
||||
<message numerus="yes">
|
||||
<source>(of %n GB needed)</source>
|
||||
<translation><numerusform>(de %n GB necessari)</numerusform><numerusform>(de %n GB necessaris)</numerusform></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>OpenURIDialog</name>
|
||||
<message>
|
||||
|
@ -1018,6 +1042,14 @@ Address: %4
|
|||
<source>Map port using &UPnP</source>
|
||||
<translation>Port obert amb &UPnP</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Connect to the Bitcoin network through a SOCKS5 proxy.</source>
|
||||
<translation>Connecta a la xarxa Bitcoin a través d'un proxy SOCKS5.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>&Connect through SOCKS5 proxy (default proxy):</source>
|
||||
<translation>&Connecta a través d'un proxy SOCKS5 (proxy per defecte):</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Proxy &IP:</source>
|
||||
<translation>&IP del proxy:</translation>
|
||||
|
@ -1149,6 +1181,10 @@ Address: %4
|
|||
<source>Mined balance that has not yet matured</source>
|
||||
<translation>Balanç minat que encara no ha madurat</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Balances</source>
|
||||
<translation>Balances</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Total:</source>
|
||||
<translation>Total:</translation>
|
||||
|
@ -1161,6 +1197,14 @@ Address: %4
|
|||
<source>Your current balance in watch-only addresses</source>
|
||||
<translation>El vostre balanç actual en adreces de només lectura</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Spendable:</source>
|
||||
<translation>Que es pot gastar:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Recent transactions</source>
|
||||
<translation>Transaccions recents</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Unconfirmed transactions to watch-only addresses</source>
|
||||
<translation>Transaccions sense confirmar a adreces de només lectura</translation>
|
||||
|
@ -1240,6 +1284,14 @@ Address: %4
|
|||
<source>Refund from %1</source>
|
||||
<translation>Reemborsament de %1</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Payment request %1 is too large (%2 bytes, allowed %3 bytes).</source>
|
||||
<translation>La sol·licitud de pagament %1 és massa gran (%2 bytes, permès %3 bytes).</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Payment request DoS protection</source>
|
||||
<translation>Protecció de DoS per a la sol·licitud de pagament</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Error communicating with %1: %2</source>
|
||||
<translation>Error en comunicar amb %1: %2</translation>
|
||||
|
@ -1280,7 +1332,7 @@ Address: %4
|
|||
<name>QObject</name>
|
||||
<message>
|
||||
<source>Amount</source>
|
||||
<translation>Quantitat</translation>
|
||||
<translation>Import</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Enter a Bitcoin address (e.g. %1)</source>
|
||||
|
@ -1782,7 +1834,7 @@ Address: %4
|
|||
</message>
|
||||
<message>
|
||||
<source>After Fee:</source>
|
||||
<translation>Quota posterior:</translation>
|
||||
<translation>Comissió posterior:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Change:</source>
|
||||
|
@ -1796,6 +1848,78 @@ Address: %4
|
|||
<source>Custom change address</source>
|
||||
<translation>Personalitza l'adreça de canvi</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Transaction Fee:</source>
|
||||
<translation>Comissió de transacció</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Choose...</source>
|
||||
<translation>Tria...</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>collapse fee-settings</source>
|
||||
<translation>redueix els paràmetres de comissió</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Minimize</source>
|
||||
<translation>Minimitza</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>If the custom fee is set to 1000 satoshis and the transaction is only 250 bytes, then "per kilobyte" only pays 250 satoshis in fee, while "at least" pays 1000 satoshis. For transactions bigger than a kilobyte both pay by kilobyte.</source>
|
||||
<translation>Si la comissió personalitzada es defineix a 1000 satoshis i la transacció és de només 250 bytes, llavors «per kilobyte» només es paguen 250 satoshis en una comissió, mentre que amb la de «com a mínim» es pagarien 1000 satoshis. Per a transaccions superiors al kilobyte, en tots dos casos es paga per kilobyte.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>per kilobyte</source>
|
||||
<translation>per kilobyte</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>If the custom fee is set to 1000 satoshis and the transaction is only 250 bytes, then "per kilobyte" only pays 250 satoshis in fee, while "total at least" pays 1000 satoshis. For transactions bigger than a kilobyte both pay by kilobyte.</source>
|
||||
<translation>Si la comissió personalitzada es defineix a 1000 satoshis i la transacció és de només 250 bytes, llavors «per kilobyte» només es paguen 250 satoshis en una comissió, mentre que amb la de «total com a mínim» es pagarien 1000 satoshis. Per a transaccions superiors al kilobyte, en tots dos casos es paga per kilobyte.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>total at least</source>
|
||||
<translation>total com a mínim</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Paying only the minimum fee is just fine as long as there is less transaction volume than space in the blocks. But be aware that this can end up in a never confirming transaction once there is more demand for bitcoin transactions than the network can process.</source>
|
||||
<translation>No hi ha cap problema en pagar només la comissió mínima sempre que hi hagi menys volum de transacció que espai en els blocs. Però tingueu present que això pot acabar en una transacció que mai es confirmi una vegada hi hagi més demanda de transaccions de bitcoins que la xarxa pugui processar.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>(read the tooltip)</source>
|
||||
<translation>(llegiu l'indicador de funció)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Recommended:</source>
|
||||
<translation>Recomanada:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Custom:</source>
|
||||
<translation>Personalitzada:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>(Smart fee not initialized yet. This usually takes a few blocks...)</source>
|
||||
<translation>(No s'ha inicialitzat encara la comissió intel·ligent. Normalment pren uns pocs blocs...)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Confirmation time:</source>
|
||||
<translation>Temps de confirmació:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>normal</source>
|
||||
<translation>normal</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>fast</source>
|
||||
<translation>ràpid</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Send as zero-fee transaction if possible</source>
|
||||
<translation>Envia com a transacció de comissió zero si és possible</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>(confirmation may take longer)</source>
|
||||
<translation>(la confirmació pot trigar més temps)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Send to multiple recipients at once</source>
|
||||
<translation>Envia a múltiples destinataris al mateix temps</translation>
|
||||
|
@ -1846,7 +1970,7 @@ Address: %4
|
|||
</message>
|
||||
<message>
|
||||
<source>Copy fee</source>
|
||||
<translation>Copia la comissi</translation>
|
||||
<translation>Copia la comissió</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Copy after fee</source>
|
||||
|
@ -1886,7 +2010,7 @@ Address: %4
|
|||
</message>
|
||||
<message>
|
||||
<source>The total exceeds your balance when the %1 transaction fee is included.</source>
|
||||
<translation>El total excedeix el teu balanç quan s'afegeix la comisió a la transacció %1.</translation>
|
||||
<translation>El total excedeix el teu balanç quan s'afegeix la comissió a la transacció %1.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Duplicate address found, can only send to each address once per send operation.</source>
|
||||
|
@ -1900,6 +2024,18 @@ Address: %4
|
|||
<source>The transaction was rejected! This might happen if some of the coins in your wallet were already spent, such as if you used a copy of wallet.dat and coins were spent in the copy but not marked as spent here.</source>
|
||||
<translation>S'ha rebutjat la transacció! Això pot passar si alguna de les monedes del vostre moneder ja s'han gastat; per exemple, si heu fet servir una còpia de seguretat del fitxer wallet.dat i s'haguessin gastat monedes de la còpia però sense marcar-les-hi com a gastades.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>A fee higher than %1 is considered an insanely high fee.</source>
|
||||
<translation>Una comissió superior a %1 es considera una comissió excessiva.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Pay only the minimum fee of %1</source>
|
||||
<translation>Paga només la comissió mínima de %1</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Estimated to begin confirmation within %1 block(s).</source>
|
||||
<translation>Estimat per a començar la confirmació en %1 bloc(s).</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Warning: Invalid Bitcoin address</source>
|
||||
<translation>Avís: adreça Bitcoin no vàlida</translation>
|
||||
|
@ -2300,7 +2436,7 @@ Address: %4
|
|||
</message>
|
||||
<message>
|
||||
<source>Amount</source>
|
||||
<translation>Quantitat</translation>
|
||||
<translation>Import</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>true</source>
|
||||
|
@ -2428,6 +2564,10 @@ Address: %4
|
|||
<source>Type of transaction.</source>
|
||||
<translation>Tipus de transacció.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Whether or not a watch-only address is involved in this transaction.</source>
|
||||
<translation>Si està implicada o no una adreça només de lectura en la transacció.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Destination address of transaction.</source>
|
||||
<translation>Adreça del destinatari de la transacció.</translation>
|
||||
|
@ -2523,6 +2663,10 @@ Address: %4
|
|||
<source>Export Transaction History</source>
|
||||
<translation>Exporta l'historial de transacció</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Watch-only</source>
|
||||
<translation>Només de lectura</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Exporting Failed</source>
|
||||
<translation>L'exportació ha fallat</translation>
|
||||
|
@ -2666,29 +2810,6 @@ Address: %4
|
|||
<source>Accept connections from outside (default: 1 if no -proxy or -connect)</source>
|
||||
<translation>Accepta connexions de fora (per defecte: 1 si no -proxy o -connect)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>%s, you must set a rpcpassword in the configuration file:
|
||||
%s
|
||||
It is recommended you use the following random password:
|
||||
rpcuser=bitcoinrpc
|
||||
rpcpassword=%s
|
||||
(you do not need to remember this password)
|
||||
The username and password MUST NOT be the same.
|
||||
If the file does not exist, create it with owner-readable-only file permissions.
|
||||
It is also recommended to set alertnotify so you are notified of problems;
|
||||
for example: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com
|
||||
</source>
|
||||
<translation>%s, heu de establir una contrasenya RPC al fitxer de configuració: %s
|
||||
Es recomana que useu la següent contrasenya aleatòria:
|
||||
rpcuser=bitcoinrpc
|
||||
rpcpassword=%s
|
||||
(no necesiteu recordar aquesta contrasenya)
|
||||
El nom d'usuari i la contrasenya NO HAN de ser els mateixos.
|
||||
Si el fitxer no existeix, crea'l amb els permisos de fitxer de només lectura per al propietari.
|
||||
També es recomana establir la notificació d'alertes i així sereu notificat de les incidències;
|
||||
per exemple: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com
|
||||
</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Bind to given address and always listen on it. Use [host]:port notation for IPv6</source>
|
||||
<translation>Vincula a una adreça específica i sempre escolta-hi. Utilitza la notació [host]:port per IPv6</translation>
|
||||
|
@ -2697,18 +2818,14 @@ per exemple: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com
|
|||
<source>Delete all wallet transactions and only recover those parts of the blockchain through -rescan on startup</source>
|
||||
<translation>Elimina totes les transaccions del moneder i només recupera aquelles de la cadena de blocs a través de -rescan a l'inici</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Distributed under the MIT software license, see the accompanying file COPYING or <http://www.opensource.org/licenses/mit-license.php>.</source>
|
||||
<translation>Distribuït sota llicència de programari MIT. Vegeu el fitxer acompanyant COPYING o <http://www.opensource.org/licenses/mit-license.php>.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Enter regression test mode, which uses a special chain in which blocks can be solved instantly.</source>
|
||||
<translation>Entra en el mode de proves de regressió, que utilitza una cadena especial en què els blocs poden resoldre's al moment.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Error: The transaction was rejected! This might happen if some of the coins in your wallet were already spent, such as if you used a copy of wallet.dat and coins were spent in the copy but not marked as spent here.</source>
|
||||
<translation>Error: La transacció ha estat rebutjada. Això pot passar si alguna de les monedes del teu moneder ja s'han gastat, com si haguesis usat una copia de l'arxiu wallet.dat i s'haguessin gastat monedes de la copia però sense marcar com gastades en aquest.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Error: This transaction requires a transaction fee of at least %s because of its amount, complexity, or use of recently received funds!</source>
|
||||
<translation>Error: Aquesta transacció requereix una comissió d'almenys %s degut al seu import, complexitat o per l'ús de fons recentment rebuts!</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Execute command when a wallet transaction changes (%s in cmd is replaced by TxID)</source>
|
||||
<translation>Executa una ordre quan una transacció del moneder canviï (%s en cmd es canvia per TxID)</translation>
|
||||
|
@ -2749,6 +2866,10 @@ per exemple: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com
|
|||
<source>Warning: wallet.dat corrupt, data salvaged! Original wallet.dat saved as wallet.{timestamp}.bak in %s; if your balance or transactions are incorrect you should restore from a backup.</source>
|
||||
<translation>Avís: el fitxer wallet.dat és corrupte, dades rescatades! L'arxiu wallet.dat original ha estat desat com wallet.{estampa_temporal}.bak al directori %s; si el teu balanç o transaccions son incorrectes hauries de restaurar-lo de un backup.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Whitelist peers connecting from the given netmask or IP address. Can be specified multiple times.</source>
|
||||
<translation>Afegeix a la llista blanca els iguals que es connecten de la màscara de xarxa o adreça IP donada. Es pot especificar moltes vegades.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>(default: 1)</source>
|
||||
<translation>(per defecte: 1)</translation>
|
||||
|
@ -2810,12 +2931,12 @@ per exemple: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com
|
|||
<translation>Error en obrir la base de dades de blocs</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Error: Disk space is low!</source>
|
||||
<translation>Error: Espai al disc baix!</translation>
|
||||
<source>Error: A fatal internal error occured, see debug.log for details</source>
|
||||
<translation>Error: s'ha produït un error intern fatal. Consulteu debug.log per a més detalls</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Error: Wallet locked, unable to create transaction!</source>
|
||||
<translation>Error: El moneder està bloquejat, no és possible crear la transacció!</translation>
|
||||
<source>Error: Disk space is low!</source>
|
||||
<translation>Error: Espai al disc baix!</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Failed to listen on any port. Use -listen=0 if you want this.</source>
|
||||
|
@ -2841,6 +2962,10 @@ per exemple: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com
|
|||
<source>Not enough file descriptors available.</source>
|
||||
<translation>No hi ha suficient descriptors de fitxers disponibles.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Only connect to nodes in network <net> (ipv4, ipv6 or onion)</source>
|
||||
<translation>Només connecta als nodes de la xarxa <net> (ipv4, ipv6 o onion)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Rebuild block chain index from current blk000??.dat files</source>
|
||||
<translation>Reconstrueix l'índex de la cadena de blocs dels fitxers actuals blk000??.dat</translation>
|
||||
|
@ -2861,6 +2986,10 @@ per exemple: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com
|
|||
<source>This is intended for regression testing tools and app development.</source>
|
||||
<translation>Això es així per a eines de proves de regressió per al desenvolupament d'aplicacions.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Use UPnP to map the listening port (default: %u)</source>
|
||||
<translation>Utilitza UPnP per a mapejar el port d'escolta (per defecte: %u)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Verifying blocks...</source>
|
||||
<translation>S'estan verificant els blocs...</translation>
|
||||
|
@ -2901,6 +3030,10 @@ per exemple: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com
|
|||
<source>Cannot obtain a lock on data directory %s. Bitcoin Core is probably already running.</source>
|
||||
<translation>No es pot obtenir un bloqueig del directori de dades %s. El Bitcoin Core probablement ja s'estigui executant.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Continuously rate-limit free transactions to <n>*1000 bytes per minute (default:%u)</source>
|
||||
<translation>Limita contínuament la freqüència de les transaccions gratuïtes a <n>*1000 bytes per minut (per defecte: %u)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Create new files with system default permissions, instead of umask 077 (only effective with disabled wallet functionality)</source>
|
||||
<translation>Crea fitxers nous amb els permisos per defecte del sistema, en comptes de l'umask 077 (només efectiu amb la funcionalitat de moneder inhabilitada)</translation>
|
||||
|
@ -2925,18 +3058,69 @@ per exemple: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com
|
|||
<source>Fees (in BTC/Kb) smaller than this are considered zero fee for transaction creation (default: %s)</source>
|
||||
<translation>Comissions (en BTC/Kb) inferiors a això es consideren de comissió zero per a la creació de la transacció (per defecte: %s)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>If paytxfee is not set, include enough fee so transactions begin confirmation on average within n blocks (default: %u)</source>
|
||||
<translation>Si no s'especifica una paytxfee (comissió de transacció de pagament), inclogueu suficient comissió per tal que les transaccions comencin a confirmar-se en una mitja de n blocs (per defecte: %u)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Invalid amount for -maxtxfee=<amount>: '%s' (must be at least the minrelay fee of %s to prevent stuck transactions)</source>
|
||||
<translation>Import no vàlid per a -maxtxfee=<amount>: '%s' (cal que sigui com a mínim la comissió de minrelay de %s per evitar que les comissions s'encallin)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Maximum size of data in data carrier transactions we relay and mine (default: %u)</source>
|
||||
<translation>Mida màxima de les dades en les transaccions de l'operador en què confiem i en les meves (per defecte: %u)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Maximum total fees to use in a single wallet transaction, setting too low may abort large transactions (default: %s)</source>
|
||||
<translation>Comissions totals màximes que s'utilitzaran en una transacció d'un únic moneder. Si es defineix un valor massa baix les transaccions més grans poden interrompre's (per defecte: %s)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Query for peer addresses via DNS lookup, if low on addresses (default: 1 unless -connect)</source>
|
||||
<translation>Consulta a adreces d'iguals a través de DNS, si es troba baix en adreces (per defecte: 1 a menys que -connect)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Require high priority for relaying free or low-fee transactions (default:%u)</source>
|
||||
<translation>Es requereix una prioritat alta per retransmetre transaccions gratuïtes o de baixa comissió (per defecte:%u)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Set maximum size of high-priority/low-fee transactions in bytes (default: %d)</source>
|
||||
<translation>Defineix la mida màxima de transaccions d'alta prioritat / baixa comissió en bytes (per defecte: %d)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Set the number of threads for coin generation if enabled (-1 = all cores, default: %d)</source>
|
||||
<translation>Defineix el nombre de fils per a la generació de moneda si està habilitat (-1 = tots els nuclis, per defecte: %d)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>This product includes software developed by the OpenSSL Project for use in the OpenSSL Toolkit <https://www.openssl.org/> and cryptographic software written by Eric Young and UPnP software written by Thomas Bernard.</source>
|
||||
<translation>Aquest producte inclou programari desenvolupat pel projecte OpenSSL per a ús a l'OpenSSL Toolkit <https://www.openssl.org/> i programari criptogràfic escrit per Eric Young i programari UPnP escrit per Thomas Bernard.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>To use bitcoind, or the -server option to bitcoin-qt, you must set an rpcpassword in the configuration file:
|
||||
%s
|
||||
It is recommended you use the following random password:
|
||||
rpcuser=bitcoinrpc
|
||||
rpcpassword=%s
|
||||
(you do not need to remember this password)
|
||||
The username and password MUST NOT be the same.
|
||||
If the file does not exist, create it with owner-readable-only file permissions.
|
||||
It is also recommended to set alertnotify so you are notified of problems;
|
||||
for example: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com
|
||||
</source>
|
||||
<translation>Per utilitzar bitcoind, o l'opció de serviddor de bitcoin-qt, heu de definir una rpcpassword en el fitxer de configuració:
|
||||
%s
|
||||
Es recomana que utilitzeu la contrasenya aleatòria següent:
|
||||
rpcuser=bitcoinrpc
|
||||
rpcpassword=%s
|
||||
(no cal que recordeu la contrasenya)
|
||||
El nom d'usuari i la contrasenya NO han de ser els mateixos.
|
||||
Si el fitxer no existeix, creeu-ne un amb permisos de lectura només per al seu propietari.
|
||||
Es recomana definir alertnotify per tal de ser notificat de qualsevol problema;
|
||||
per exemple: alertnotify=echo %%s | mail -s "Avís de Bitcoin" admin@foo.com</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Warning: -maxtxfee is set very high! Fees this large could be paid on a single transaction.</source>
|
||||
<translation>Avís: s'ha especificat un -maxtxfee molt alt! Comissions tan grans podrien pagar-se en una única transacció.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Warning: Please check that your computer's date and time are correct! If your clock is wrong Bitcoin Core will not work properly.</source>
|
||||
<translation>Avís: comproveu que la data i hora del vostre ordinador siguin correctes! Si el vostre rellotge no és correcte, el Bitcoin Core no funcionarà correctament.</translation>
|
||||
|
@ -2945,6 +3129,10 @@ per exemple: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com
|
|||
<source>Whitelisted peers cannot be DoS banned and their transactions are always relayed, even if they are already in the mempool, useful e.g. for a gateway</source>
|
||||
<translation>Els iguals en la llista blanca no poden ser bandejats per DoS i es transmetran sempre llurs transaccions, fins i tot si ja són a la mempool. Això és útil, p. ex., per a una passarel·la</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Accept public REST requests (default: %u)</source>
|
||||
<translation>Accepta sol·licituds REST públiques (per defecte: %u)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Cannot resolve -whitebind address: '%s'</source>
|
||||
<translation>No es pot resoldre l'adreça -whitebind: «%s»</translation>
|
||||
|
@ -2965,6 +3153,10 @@ per exemple: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com
|
|||
<source>Error loading wallet.dat: Wallet requires newer version of Bitcoin Core</source>
|
||||
<translation>Error en carregar wallet.dat: el moneder requereix una versió més nova del Bitcoin core</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Error reading from database, shutting down.</source>
|
||||
<translation>Error en llegir la base de dades, tancant.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Error: Unsupported argument -tor found, use -onion.</source>
|
||||
<translation>Error: s'ha trobat un argument -tor no acceptat. Feu servir -onion.</translation>
|
||||
|
@ -2981,6 +3173,10 @@ per exemple: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com
|
|||
<source>Initialization sanity check failed. Bitcoin Core is shutting down.</source>
|
||||
<translation>Ha fallat la inicialització de la comprovació de validesa. El Bitcoin Core s'està aturant.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Invalid amount for -maxtxfee=<amount>: '%s'</source>
|
||||
<translation>Import no vàlid per a -maxtxfee=<amount>: '%s'</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Invalid amount for -minrelaytxfee=<amount>: '%s'</source>
|
||||
<translation>Import no vàlid per a -minrelaytxfee=<amount>: «%s»</translation>
|
||||
|
@ -2998,8 +3194,8 @@ per exemple: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com
|
|||
<translation>S'ha especificat una màscara de xarxa no vàlida a -whitelist: «%s»</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Keep at most <n> unconnectable blocks in memory (default: %u)</source>
|
||||
<translation>Manté com a màxim <n> blocs no connectables en memòria (per defecte: %u)</translation>
|
||||
<source>Keep at most <n> unconnectable transactions in memory (default: %u)</source>
|
||||
<translation>Manté com a màxim <n> transaccions no connectables en memòria (per defecte: %u)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Need to specify a port with -whitebind: '%s'</source>
|
||||
|
@ -3009,10 +3205,6 @@ per exemple: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com
|
|||
<source>Node relay options:</source>
|
||||
<translation>Opcions de transmissió del node:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Print block on startup, if found in block index</source>
|
||||
<translation>Imprimeix el block a l'inici, si es troba l'índex de blocs</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>RPC SSL options: (see the Bitcoin Wiki for SSL setup instructions)</source>
|
||||
<translation>Opcions RPC SSL: (veieu el wiki del Bitcoin per a instruccions de configuració de l'SSL)</translation>
|
||||
|
@ -3021,6 +3213,10 @@ per exemple: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com
|
|||
<source>RPC server options:</source>
|
||||
<translation>Opcions del servidor RPC:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>RPC support for HTTP persistent connections (default: %d)</source>
|
||||
<translation>Suport RPC per a connexions HTTP persistents (per defecte: %d)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Randomly drop 1 of every <n> network messages</source>
|
||||
<translation>Descarta a l'atzar 1 de cada <n> missatges de la xarxa</translation>
|
||||
|
@ -3033,6 +3229,10 @@ per exemple: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com
|
|||
<source>Send trace/debug info to console instead of debug.log file</source>
|
||||
<translation>Envia informació de traça/depuració a la consola en comptes del fitxer debug.log</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Send transactions as zero-fee transactions if possible (default: %u)</source>
|
||||
<translation>Envia les transaccions com a transaccions de comissió zero sempre que sigui possible (per defecte: %u) </translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Show all debugging options (usage: --help -help-debug)</source>
|
||||
<translation>Mostra totes les opcions de depuració (ús: --help --help-debug)</translation>
|
||||
|
@ -3057,6 +3257,10 @@ per exemple: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com
|
|||
<source>Transaction amounts must be positive</source>
|
||||
<translation>Els imports de les transaccions han de ser positius</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Transaction too large for fee policy</source>
|
||||
<translation>Transacció massa gran per a la política de comissions</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Transaction too large</source>
|
||||
<translation>La transacció és massa gran</translation>
|
||||
|
@ -3141,14 +3345,170 @@ per exemple: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com
|
|||
<source>Error loading wallet.dat: Wallet corrupted</source>
|
||||
<translation>Error en carregar wallet.dat: Moneder corrupte</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>(1 = keep tx meta data e.g. account owner and payment request information, 2 = drop tx meta data)</source>
|
||||
<translation>(1 = manté les metadades de les tx, p. ex., propietari del compte i informació de sol·licitud del pagament, 2 = prescindeix de les metadades de les tx)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Flush database activity from memory pool to disk log every <n> megabytes (default: %u)</source>
|
||||
<translation>Buida l'activitat de la base de dades de la memòria disponible al registre del disc cada <n> megabytes (per defecte: %u)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>How thorough the block verification of -checkblocks is (0-4, default: %u)</source>
|
||||
<translation>Com d'exhaustiva és la verificació de blocs del -checkblocks (0-4, per defecte: %u)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Log transaction priority and fee per kB when mining blocks (default: %u)</source>
|
||||
<translation>Enregistreu la prioritat de la transacció i la comissió per kB en minar blocs (per defecte: %u)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Maintain a full transaction index, used by the getrawtransaction rpc call (default: %u)</source>
|
||||
<translation>Manté un índex complet de transaccions, utilitzat per la crida rpc getrawtransaction (per defecte: %u)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Number of seconds to keep misbehaving peers from reconnecting (default: %u)</source>
|
||||
<translation>Nombre de segons necessaris perquè els iguals de comportament qüestionable puguin tornar a connectar-se (per defecte: %u)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Output debugging information (default: %u, supplying <category> is optional)</source>
|
||||
<translation>Informació de sortida de la depuració (per defecte: %u, proporcionar <category> és opcional)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Use separate SOCKS5 proxy to reach peers via Tor hidden services (default: %s)</source>
|
||||
<translation>Utilitza un proxy SOCKS4 apart per a arribar als iguals a través de serveis ocults de Tor (per defecte: %s)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>(default: %s)</source>
|
||||
<translation>(per defecte: %s)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Acceptable ciphers (default: %s)</source>
|
||||
<translation>Xifrats acceptables (per defecte: %s)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Always query for peer addresses via DNS lookup (default: %u)</source>
|
||||
<translation>Demana sempre les adreces dels iguals a través de consultes DNS (per defecte: %u)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Disable safemode, override a real safe mode event (default: %u)</source>
|
||||
<translation>Inhabilita el mode segur, sobreescriu un esdeveniment de mode segur real (per defecte: %u) </translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Error loading wallet.dat</source>
|
||||
<translation>Error en carregar wallet.dat</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Force safe mode (default: %u)</source>
|
||||
<translation>Força el mode segur (per defecte: %u)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Generate coins (default: %u)</source>
|
||||
<translation>Genera monedes (per defecte: %u)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>How many blocks to check at startup (default: %u, 0 = all)</source>
|
||||
<translation>Quants blocs per comprovar a l'inici (per defecte: %u, 0 = tots)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Include IP addresses in debug output (default: %u)</source>
|
||||
<translation>Inclou l'adreça IP a la sortida de depuració (per defecte: %u)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Invalid -proxy address: '%s'</source>
|
||||
<translation>Adreça -proxy invalida: '%s'</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Limit size of signature cache to <n> entries (default: %u)</source>
|
||||
<translation>Limita la mida de la cau de signatura a <n> entrades (per defecte: %u)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Listen for JSON-RPC connections on <port> (default: %u or testnet: %u)</source>
|
||||
<translation>Escolta les connexions JSON-RPC en <port> (per defecte: %u o testnet: %u)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Listen for connections on <port> (default: %u or testnet: %u)</source>
|
||||
<translation>Escolta les connexions en <port> (per defecte: %u o testnet: %u)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Maintain at most <n> connections to peers (default: %u)</source>
|
||||
<translation>Manté com a màxim <n> connexions a iguals (per defecte: %u)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Maximum per-connection receive buffer, <n>*1000 bytes (default: %u)</source>
|
||||
<translation>Memòria intermèdia màxima de recepció per connexió, <n>*1000 bytes (per defecte: %u)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Maximum per-connection send buffer, <n>*1000 bytes (default: %u)</source>
|
||||
<translation>Memòria intermèdia màxima d'enviament per connexió, <n>*1000 bytes (per defecte: %u)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Only accept block chain matching built-in checkpoints (default: %u)</source>
|
||||
<translation>Només accepta els punts de control integrats que coincideixen amb la cadena de blocs (per defecte: %u)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Prepend debug output with timestamp (default: %u)</source>
|
||||
<translation>Posa davant de la sortida de depuració una marca horària (per defecte: %u)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Relay and mine data carrier transactions (default: %u)</source>
|
||||
<translation>Retransmet i mina les transaccions de l'operador (per defecte: %u)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Relay non-P2SH multisig (default: %u)</source>
|
||||
<translation>Retransmet multisig no P2SH (per defecte: %u)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Run a thread to flush wallet periodically (default: %u)</source>
|
||||
<translation>Executa un fil per buidar el moneder periòdicament (per defecte: %u)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Server certificate file (default: %s)</source>
|
||||
<translation>Fitxer de certificat del servidor (per defecte: %s)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Server private key (default: %s)</source>
|
||||
<translation>Clau privada del servidor (per defecte: %s)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Set key pool size to <n> (default: %u)</source>
|
||||
<translation>Defineix la mida clau disponible a <n> (per defecte: %u)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Set minimum block size in bytes (default: %u)</source>
|
||||
<translation>Defineix la mida de bloc mínima en bytes (per defecte: %u)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Set the number of threads to service RPC calls (default: %d)</source>
|
||||
<translation>Defineix el nombre de fils a crides de servei RPC (per defecte: %d)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Sets the DB_PRIVATE flag in the wallet db environment (default: %u)</source>
|
||||
<translation>Defineix el senyalador DB_PRIVATE en l'entorn db del moneder (per defecte: %u)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Specify configuration file (default: %s)</source>
|
||||
<translation>Especifica el fitxer de configuració (per defecte: %s)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Specify connection timeout in milliseconds (minimum: 1, default: %d)</source>
|
||||
<translation>Especifica el temps d'espera de la connexió en milisegons (mínim: 1, per defecte: %d)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Specify pid file (default: %s)</source>
|
||||
<translation>Especifica el fitxer pid (per defecte: %s)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Spend unconfirmed change when sending transactions (default: %u)</source>
|
||||
<translation>Gasta el canvi no confirmat en enviar les transaccions (per defecte: %u)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Stop running after importing blocks from disk (default: %u)</source>
|
||||
<translation>Atura l'execució després d'importar blocs del disc (per defecte: %u)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Threshold for disconnecting misbehaving peers (default: %u)</source>
|
||||
<translation>Llindar per a desconnectar els iguals de comportament qüestionable (per defecte: %u)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Unknown network specified in -onlynet: '%s'</source>
|
||||
<translation>Xarxa desconeguda especificada a -onlynet: '%s'</translation>
|
||||
|
@ -3165,10 +3525,6 @@ per exemple: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com
|
|||
<source>Invalid amount for -paytxfee=<amount>: '%s'</source>
|
||||
<translation>Import no vàlid per a -paytxfee=<amount>: «%s»</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Invalid amount</source>
|
||||
<translation>Import no vàlid</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Insufficient funds</source>
|
||||
<translation>Balanç insuficient</translation>
|
||||
|
@ -3201,10 +3557,6 @@ per exemple: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com
|
|||
<source>Done loading</source>
|
||||
<translation>Ha acabat la càrrega</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>To use the %s option</source>
|
||||
<translation>Utilitza l'opció %s</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Error</source>
|
||||
<translation>Error</translation>
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
<TS language="cmn" version="2.0">
|
||||
<TS language="cmn" version="2.1">
|
||||
<context>
|
||||
<name>AddressBookPage</name>
|
||||
</context>
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
<TS language="cs" version="2.0">
|
||||
<TS language="cs" version="2.1">
|
||||
<context>
|
||||
<name>AddressBookPage</name>
|
||||
<message>
|
||||
<source>Double-click to edit address or label</source>
|
||||
<translation>Dvojklikem myši začneš upravovat označení adresy</translation>
|
||||
<source>Right-click to edit address or label</source>
|
||||
<translation>Pravým tlačítkem myši začneš upravovat označení adresy</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Create a new address</source>
|
||||
|
@ -430,10 +430,26 @@
|
|||
<source>No block source available...</source>
|
||||
<translation>Není dostupný žádný zdroj bloků...</translation>
|
||||
</message>
|
||||
<message numerus="yes">
|
||||
<source>%n hour(s)</source>
|
||||
<translation><numerusform>%n hodinu</numerusform><numerusform>%n hodiny</numerusform><numerusform>%n hodin</numerusform></translation>
|
||||
</message>
|
||||
<message numerus="yes">
|
||||
<source>%n day(s)</source>
|
||||
<translation><numerusform>%n den</numerusform><numerusform>%n dny</numerusform><numerusform>%n dnů</numerusform></translation>
|
||||
</message>
|
||||
<message numerus="yes">
|
||||
<source>%n week(s)</source>
|
||||
<translation><numerusform>%n týden</numerusform><numerusform>%n týdny</numerusform><numerusform>%n týdnů</numerusform></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>%1 and %2</source>
|
||||
<translation>%1 a %2</translation>
|
||||
</message>
|
||||
<message numerus="yes">
|
||||
<source>%n year(s)</source>
|
||||
<translation><numerusform>%n rok</numerusform><numerusform>%n roky</numerusform><numerusform>%n roků</numerusform></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>%1 behind</source>
|
||||
<translation>Stahuji ještě bloky transakcí za poslední %1</translation>
|
||||
|
@ -462,6 +478,10 @@
|
|||
<source>Up to date</source>
|
||||
<translation>Aktuální</translation>
|
||||
</message>
|
||||
<message numerus="yes">
|
||||
<source>Processed %n blocks of transaction history.</source>
|
||||
<translation><numerusform>Zpracován %n blok transakční historie.</numerusform><numerusform>Zpracovány %n bloky transakční historie.</numerusform><numerusform>Zpracováno %n bloků transakční historie.</numerusform></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Catching up...</source>
|
||||
<translation>Stahuji...</translation>
|
||||
|
@ -504,6 +524,10 @@ Adresa: %4
|
|||
</context>
|
||||
<context>
|
||||
<name>CoinControlDialog</name>
|
||||
<message>
|
||||
<source>Coin Selection</source>
|
||||
<translation>Výběr mincí</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Quantity:</source>
|
||||
<translation>Počet:</translation>
|
||||
|
@ -552,6 +576,14 @@ Adresa: %4
|
|||
<source>Amount</source>
|
||||
<translation>Částka</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Received with label</source>
|
||||
<translation>Příjem na označení</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Received with address</source>
|
||||
<translation>Příjem na adrese</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Date</source>
|
||||
<translation>Datum</translation>
|
||||
|
@ -884,7 +916,15 @@ Adresa: %4
|
|||
<source>Error</source>
|
||||
<translation>Chyba</translation>
|
||||
</message>
|
||||
</context>
|
||||
<message numerus="yes">
|
||||
<source>%n GB of free space available</source>
|
||||
<translation><numerusform>%n GB volného místa</numerusform><numerusform>%n GB volného místa</numerusform><numerusform>%n GB volného místa</numerusform></translation>
|
||||
</message>
|
||||
<message numerus="yes">
|
||||
<source>(of %n GB needed)</source>
|
||||
<translation><numerusform>(z potřebného %n GB)</numerusform><numerusform>(z potřebných %n GB)</numerusform><numerusform>(z potřebných %n GB)</numerusform></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>OpenURIDialog</name>
|
||||
<message>
|
||||
|
@ -1006,6 +1046,14 @@ Adresa: %4
|
|||
<source>Map port using &UPnP</source>
|
||||
<translation>Namapovat port přes &UPnP</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Connect to the Bitcoin network through a SOCKS5 proxy.</source>
|
||||
<translation>Připojí se do Bitcoinové sítě přes SOCKS5 proxy.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>&Connect through SOCKS5 proxy (default proxy):</source>
|
||||
<translation>&Připojit přes SOCKS5 proxy (výchozí proxy):</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Proxy &IP:</source>
|
||||
<translation>&IP adresa proxy:</translation>
|
||||
|
@ -1137,6 +1185,10 @@ Adresa: %4
|
|||
<source>Mined balance that has not yet matured</source>
|
||||
<translation>Vytěžené mince, které ještě nejsou zralé</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Balances</source>
|
||||
<translation>Stavy účtů</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Total:</source>
|
||||
<translation>Celkem:</translation>
|
||||
|
@ -1149,6 +1201,14 @@ Adresa: %4
|
|||
<source>Your current balance in watch-only addresses</source>
|
||||
<translation>Aktuální stav účtu sledovaných adres</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Spendable:</source>
|
||||
<translation>Běžné:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Recent transactions</source>
|
||||
<translation>Poslední transakce</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Unconfirmed transactions to watch-only addresses</source>
|
||||
<translation>Nepotvrzené transakce sledovaných adres</translation>
|
||||
|
@ -1228,6 +1288,14 @@ Adresa: %4
|
|||
<source>Refund from %1</source>
|
||||
<translation>Vrácení peněz od %1</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Payment request %1 is too large (%2 bytes, allowed %3 bytes).</source>
|
||||
<translation>Platební požadavek %1 je moc velký (%2 bajtů, povoleno %3 bajtů).</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Payment request DoS protection</source>
|
||||
<translation>DoS ochrana platebního požadavku</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Error communicating with %1: %2</source>
|
||||
<translation>Chyba při komunikaci s %1: %2</translation>
|
||||
|
@ -1784,6 +1852,78 @@ Adresa: %4
|
|||
<source>Custom change address</source>
|
||||
<translation>Vlastní adresa pro drobné</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Transaction Fee:</source>
|
||||
<translation>Transakční poplatek:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Choose...</source>
|
||||
<translation>Zvol...</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>collapse fee-settings</source>
|
||||
<translation>sbal nastavení poplatků</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Minimize</source>
|
||||
<translation>Skryj</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>If the custom fee is set to 1000 satoshis and the transaction is only 250 bytes, then "per kilobyte" only pays 250 satoshis in fee, while "at least" pays 1000 satoshis. For transactions bigger than a kilobyte both pay by kilobyte.</source>
|
||||
<translation>Pokud je vlastní poplatek nastavený na 1000 satoshi a transakce má pouze 250 bajtů, tak „za kilobajt“ zaplatí poplatek jen 250 satoshi, zatímco „přinejmenším“ zaplatí 1000 satoshi. Pro transakce větší než kilobajt obě možnosti platí za kilobajt.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>per kilobyte</source>
|
||||
<translation>za kilobajt</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>If the custom fee is set to 1000 satoshis and the transaction is only 250 bytes, then "per kilobyte" only pays 250 satoshis in fee, while "total at least" pays 1000 satoshis. For transactions bigger than a kilobyte both pay by kilobyte.</source>
|
||||
<translation>Pokud je vlastní poplatek nastavený na 1000 satoshi a transakce má pouze 250 bajtů, tak „za kilobajt“ zaplatí poplatek jen 250 satoshi, zatímco „přinejmenším“ zaplatí 1000 satoshi. Pro transakce větší než kilobajt obě možnosti platí za kilobajt.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>total at least</source>
|
||||
<translation>přinejmenším</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Paying only the minimum fee is just fine as long as there is less transaction volume than space in the blocks. But be aware that this can end up in a never confirming transaction once there is more demand for bitcoin transactions than the network can process.</source>
|
||||
<translation>Platit jen minimální poplatek je v pořádku, pokud je zrovna méně transakcí než místa v blocích. Ale počítej s tím, že to také může skončit transakcí, která nikdy nebude potvrzena, pokud je větší poptávka po bitcoinových transakcích, než síť zvládne zpracovat.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>(read the tooltip)</source>
|
||||
<translation>(viz bublina)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Recommended:</source>
|
||||
<translation>Doporučený:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Custom:</source>
|
||||
<translation>Vlastní:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>(Smart fee not initialized yet. This usually takes a few blocks...)</source>
|
||||
<translation>(Inteligentní poplatek ještě není inicializovaný. Obvykle mu to tak pár bloků trvá...)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Confirmation time:</source>
|
||||
<translation>Rychlost potvrzení:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>normal</source>
|
||||
<translation>normální</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>fast</source>
|
||||
<translation>rychlá</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Send as zero-fee transaction if possible</source>
|
||||
<translation>Pošli transakci pokud možno bez poplatku</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>(confirmation may take longer)</source>
|
||||
<translation>(potvrzení může trvat déle)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Send to multiple recipients at once</source>
|
||||
<translation>Pošli více příjemcům naráz</translation>
|
||||
|
@ -1888,6 +2028,18 @@ Adresa: %4
|
|||
<source>The transaction was rejected! This might happen if some of the coins in your wallet were already spent, such as if you used a copy of wallet.dat and coins were spent in the copy but not marked as spent here.</source>
|
||||
<translation>Transakce byla odmítnuta! Tohle může nastat, pokud nějaké mince z tvé peněženky už jednou byly utraceny, například pokud používáš kopii souboru wallet.dat a mince byly utraceny v druhé kopii, ale nebyly označeny jako utracené v této.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>A fee higher than %1 is considered an insanely high fee.</source>
|
||||
<translation>Poplatek vyšší než %1 je považován za absurdně vysoký.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Pay only the minimum fee of %1</source>
|
||||
<translation>Zaplatit pouze minimální poplatek %1</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Estimated to begin confirmation within %1 block(s).</source>
|
||||
<translation>Potvrzování by podle odhadu mělo začít během %1 bloků.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Warning: Invalid Bitcoin address</source>
|
||||
<translation>Upozornění: Neplatná Bitcoinová adresa</translation>
|
||||
|
@ -2216,7 +2368,7 @@ Adresa: %4
|
|||
</message>
|
||||
<message>
|
||||
<source>watch-only</source>
|
||||
<translation>sledovací</translation>
|
||||
<translation>sledovaná</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>label</source>
|
||||
|
@ -2226,6 +2378,10 @@ Adresa: %4
|
|||
<source>Credit</source>
|
||||
<translation>Příjem</translation>
|
||||
</message>
|
||||
<message numerus="yes">
|
||||
<source>matures in %n more block(s)</source>
|
||||
<translation><numerusform>dozraje po %n bloku</numerusform><numerusform>dozraje po %n blocích</numerusform><numerusform>dozraje po %n blocích</numerusform></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>not accepted</source>
|
||||
<translation>neakceptováno</translation>
|
||||
|
@ -2412,6 +2568,10 @@ Adresa: %4
|
|||
<source>Type of transaction.</source>
|
||||
<translation>Druh transakce.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Whether or not a watch-only address is involved in this transaction.</source>
|
||||
<translation>Zda tato transakce zahrnuje i některou sledovanou adresu.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Destination address of transaction.</source>
|
||||
<translation>Cílová adresa transakce.</translation>
|
||||
|
@ -2507,6 +2667,10 @@ Adresa: %4
|
|||
<source>Export Transaction History</source>
|
||||
<translation>Exportuj transakční historii</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Watch-only</source>
|
||||
<translation>Sledovaná</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Exporting Failed</source>
|
||||
<translation>Exportování selhalo</translation>
|
||||
|
@ -2650,30 +2814,6 @@ Adresa: %4
|
|||
<source>Accept connections from outside (default: 1 if no -proxy or -connect)</source>
|
||||
<translation>Přijímat spojení zvenčí (výchozí: 1, pokud není zadáno -proxy nebo -connect)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>%s, you must set a rpcpassword in the configuration file:
|
||||
%s
|
||||
It is recommended you use the following random password:
|
||||
rpcuser=bitcoinrpc
|
||||
rpcpassword=%s
|
||||
(you do not need to remember this password)
|
||||
The username and password MUST NOT be the same.
|
||||
If the file does not exist, create it with owner-readable-only file permissions.
|
||||
It is also recommended to set alertnotify so you are notified of problems;
|
||||
for example: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com
|
||||
</source>
|
||||
<translation>%s, musíš nastavit rpcpassword v konfiguračním souboru:
|
||||
%s
|
||||
Je vhodné použít následující náhodné heslo:
|
||||
rpcuser=bitcoinrpc
|
||||
rpcpassword=%s
|
||||
(není potřeba si ho pamatovat)
|
||||
rpcuser a rpcpassword NESMÍ být stejné.
|
||||
Pokud konfigurační soubor ještě neexistuje, vytvoř ho tak, aby ho mohl číst pouze vlastník.
|
||||
Je také doporučeno si nastavit alertnotify, abys byl upozorněn na případné problémy;
|
||||
například: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com
|
||||
</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Bind to given address and always listen on it. Use [host]:port notation for IPv6</source>
|
||||
<translation>Poslouchat na zadané adrese. Pro zápis IPv6 adresy použij notaci [adresa]:port</translation>
|
||||
|
@ -2682,18 +2822,14 @@ například: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com
|
|||
<source>Delete all wallet transactions and only recover those parts of the blockchain through -rescan on startup</source>
|
||||
<translation>Smazat všechny transakce peněženky a při startu obnovit pouze relevantní části řetězce bloků pomocí -rescan</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Distributed under the MIT software license, see the accompanying file COPYING or <http://www.opensource.org/licenses/mit-license.php>.</source>
|
||||
<translation>Šířen pod softwarovou licencí MIT, viz přiložený soubor COPYING nebo <http://www.opensource.org/licenses/mit-license.php>.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Enter regression test mode, which uses a special chain in which blocks can be solved instantly.</source>
|
||||
<translation>Přepnout do módu testování regresí, který používá speciální řetězec, ve kterém mohou být bloky okamžitě vyřešeny.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Error: The transaction was rejected! This might happen if some of the coins in your wallet were already spent, such as if you used a copy of wallet.dat and coins were spent in the copy but not marked as spent here.</source>
|
||||
<translation>Chyba: Transakce byla odmítnuta! Tohle může nastat, pokud nějaké mince z tvé peněženky už jednou byly utraceny, například pokud používáš kopii souboru wallet.dat a mince byly utraceny v druhé kopii, ale nebyly označeny jako utracené v této.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Error: This transaction requires a transaction fee of at least %s because of its amount, complexity, or use of recently received funds!</source>
|
||||
<translation>Chyba: Tahle transakce vyžaduje transakční poplatek nejméně %s kvůli velikosti zasílané částky, komplexnosti nebo použití nedávno přijatých mincí!</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Execute command when a wallet transaction changes (%s in cmd is replaced by TxID)</source>
|
||||
<translation>Spustit příkaz, když se objeví transakce týkající se peněženky (%s se v příkazu nahradí za TxID)</translation>
|
||||
|
@ -2734,6 +2870,10 @@ například: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com
|
|||
<source>Warning: wallet.dat corrupt, data salvaged! Original wallet.dat saved as wallet.{timestamp}.bak in %s; if your balance or transactions are incorrect you should restore from a backup.</source>
|
||||
<translation>Upozornění: soubor wallet.dat je poškozený, data jsou však zachráněna! Původní soubor wallet.dat je uložený jako wallet.{timestamp}.bak v %s. Pokud je stav tvého účtu nebo transakce nesprávné, zřejmě bys měl obnovit zálohu.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Whitelist peers connecting from the given netmask or IP address. Can be specified multiple times.</source>
|
||||
<translation>Umístit na bílou listinu protějšky připojující se z dané podsítě či IP adresy. Lze zadat i vícekrát.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>(default: 1)</source>
|
||||
<translation>(výchozí: 1)</translation>
|
||||
|
@ -2795,12 +2935,12 @@ například: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com
|
|||
<translation>Chyba při otevírání databáze bloků</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Error: Disk space is low!</source>
|
||||
<translation>Problém: Na disku je málo místa!</translation>
|
||||
<source>Error: A fatal internal error occured, see debug.log for details</source>
|
||||
<translation>Chyba: Stala se fatální vnitřní chyba. detaily viz v debug.log</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Error: Wallet locked, unable to create transaction!</source>
|
||||
<translation>Chyba: Peněženka je zamčená, nemohu vytvořit transakci!</translation>
|
||||
<source>Error: Disk space is low!</source>
|
||||
<translation>Problém: Na disku je málo místa!</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Failed to listen on any port. Use -listen=0 if you want this.</source>
|
||||
|
@ -2826,6 +2966,10 @@ například: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com
|
|||
<source>Not enough file descriptors available.</source>
|
||||
<translation>Je nedostatek deskriptorů souborů.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Only connect to nodes in network <net> (ipv4, ipv6 or onion)</source>
|
||||
<translation>Připojovat se pouze k uzlům v <net> síti (ipv4, ipv6 nebo onion)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Rebuild block chain index from current blk000??.dat files</source>
|
||||
<translation>Znovu vytvořit index řetězce bloků z aktuálních blk000??.dat souborů</translation>
|
||||
|
@ -2846,6 +2990,10 @@ například: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com
|
|||
<source>This is intended for regression testing tools and app development.</source>
|
||||
<translation>Tohle je určeno pro nástroje na regresní testování a vyvíjení aplikací.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Use UPnP to map the listening port (default: %u)</source>
|
||||
<translation>Použít UPnP k namapování naslouchacího portu (výchozí: %u)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Verifying blocks...</source>
|
||||
<translation>Ověřuji bloky... </translation>
|
||||
|
@ -2890,6 +3038,10 @@ například: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com
|
|||
<source>Cannot obtain a lock on data directory %s. Bitcoin Core is probably already running.</source>
|
||||
<translation>Nedaří se mi získat zámek na datový adresář %s. Bitcoin Core pravděpodobně už jednou běží.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Continuously rate-limit free transactions to <n>*1000 bytes per minute (default:%u)</source>
|
||||
<translation>Kontinuálně omezovat bezpoplatkové transakce na <n>*1000 bajtů za minutu (výchozí: %u)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Create new files with system default permissions, instead of umask 077 (only effective with disabled wallet functionality)</source>
|
||||
<translation>Vytvářet nové soubory s výchozími systémovými právy namísto umask 077 (uplatní se, pouze pokud je vypnutá funkce peněženky)</translation>
|
||||
|
@ -2914,6 +3066,14 @@ například: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com
|
|||
<source>Fees (in BTC/Kb) smaller than this are considered zero fee for transaction creation (default: %s)</source>
|
||||
<translation>Poplatky (v BTC/Kb) menší než tato hodnota jsou považovány za nulové pro účely vytváření transakcí (výchozí: %s)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>If paytxfee is not set, include enough fee so transactions begin confirmation on average within n blocks (default: %u)</source>
|
||||
<translation>Pokud paytxfee není nastaveno, platit dostatečný poplatek na to, aby byly transakce potvrzeny v průměru během n bloků (výchozí: %u)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Maximum size of data in data carrier transactions we relay and mine (default: %u)</source>
|
||||
<translation>Maximální velikost dat v transakcích nesoucích data, se kterou jsme ochotni je ještě přeposílat a těžit (výchozí: %u)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Query for peer addresses via DNS lookup, if low on addresses (default: 1 unless -connect)</source>
|
||||
<translation>Při nedostatku adres získat další protějšky z DNS (výchozí: 1, pokud není použito -connect)</translation>
|
||||
|
@ -2922,6 +3082,10 @@ například: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com
|
|||
<source>Set maximum size of high-priority/low-fee transactions in bytes (default: %d)</source>
|
||||
<translation>Nastavit maximální velikost prioritních/nízkopoplatkových transakcí v bajtech (výchozí: %d)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Set the number of threads for coin generation if enabled (-1 = all cores, default: %d)</source>
|
||||
<translation>Nastavení počtu vláken pro těžení, je-li zapnuté (-1 = všechna jádra, výchozí: %d)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>This product includes software developed by the OpenSSL Project for use in the OpenSSL Toolkit <https://www.openssl.org/> and cryptographic software written by Eric Young and UPnP software written by Thomas Bernard.</source>
|
||||
<translation>Tento produkt zahrnuje programy vyvinuté OpenSSL Projektem pro použití v OpenSSL Toolkitu <https://www.openssl.org/> a kryptografický program od Erika Younga a program UPnP od Thomase Bernarda.</translation>
|
||||
|
@ -2954,6 +3118,10 @@ například: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com
|
|||
<source>Error loading wallet.dat: Wallet requires newer version of Bitcoin Core</source>
|
||||
<translation>Chyba při načítání wallet.dat: peněženka vyžaduje novější verzi Bitcoin Core</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Error reading from database, shutting down.</source>
|
||||
<translation>Chyba při čtení z databáze, ukončuji se.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Error: Unsupported argument -tor found, use -onion.</source>
|
||||
<translation>Chyba: Argument -tor již není podporovaný, použij -onion.</translation>
|
||||
|
@ -2987,8 +3155,8 @@ například: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com
|
|||
<translation>Ve -whitelist byla zadána neplatná podsíť: '%s'</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Keep at most <n> unconnectable blocks in memory (default: %u)</source>
|
||||
<translation>Držet v paměti nejvýše <n> nespojitelných bloků (výchozí: %u)</translation>
|
||||
<source>Keep at most <n> unconnectable transactions in memory (default: %u)</source>
|
||||
<translation>Držet v paměti nejvýše <n> nespojitelných transakcí (výchozí: %u)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Need to specify a port with -whitebind: '%s'</source>
|
||||
|
@ -2998,10 +3166,6 @@ například: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com
|
|||
<source>Node relay options:</source>
|
||||
<translation>Možnosti přeposílání:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Print block on startup, if found in block index</source>
|
||||
<translation>Vypsat při startu blok,pokud se nachází v indexu bloků</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>RPC SSL options: (see the Bitcoin Wiki for SSL setup instructions)</source>
|
||||
<translation>Možnosti SSL pro RPC: (viz instrukce nastavení SSL na Bitcoin Wiki)</translation>
|
||||
|
@ -3022,6 +3186,10 @@ například: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com
|
|||
<source>Send trace/debug info to console instead of debug.log file</source>
|
||||
<translation>Posílat stopovací/ladicí informace do konzole místo do souboru debug.log</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Send transactions as zero-fee transactions if possible (default: %u)</source>
|
||||
<translation>Posílat transakce pokud možno bez poplatků (výchozí: %u)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Show all debugging options (usage: --help -help-debug)</source>
|
||||
<translation>Zobrazit všechny možnosti ladění (užití: --help -help-debug)</translation>
|
||||
|
@ -3046,9 +3214,13 @@ například: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com
|
|||
<source>Transaction amounts must be positive</source>
|
||||
<translation>Částky v transakci musí být kladné</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Transaction too large for fee policy</source>
|
||||
<translation>Transakce je na poplatkovou politiku příliš velká</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Transaction too large</source>
|
||||
<translation>Transace je příliš velká</translation>
|
||||
<translation>Transakce je příliš velká</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Unable to bind to %s on this computer (bind returned error %s)</source>
|
||||
|
@ -3130,14 +3302,166 @@ například: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com
|
|||
<source>Error loading wallet.dat: Wallet corrupted</source>
|
||||
<translation>Chyba při načítání wallet.dat: peněženka je poškozená</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>(1 = keep tx meta data e.g. account owner and payment request information, 2 = drop tx meta data)</source>
|
||||
<translation>(1 = ukládat transakční metadata, např. majitele účtu a informace o platebním požadavku, 2 = mazat transakční metadata)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Flush database activity from memory pool to disk log every <n> megabytes (default: %u)</source>
|
||||
<translation>Promítnout databázovou aktivitu z paměťového prostoru do záznamu na disku každých <n> megabajtů (výchozí: %u)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>How thorough the block verification of -checkblocks is (0-4, default: %u)</source>
|
||||
<translation>Jak moc důkladná má být verifikace bloků -checkblocks (0-4, výchozí: %u)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Log transaction priority and fee per kB when mining blocks (default: %u)</source>
|
||||
<translation>Zaznamenávat během těžení bloků prioritu transakce a poplatek za kB (výchozí: %u)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Maintain a full transaction index, used by the getrawtransaction rpc call (default: %u)</source>
|
||||
<translation>Spravovat úplný index transakcí, který je využíván rpc voláním getrawtransaction (výchozí: %u)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Number of seconds to keep misbehaving peers from reconnecting (default: %u)</source>
|
||||
<translation>Doba ve vteřinách, po kterou se nebudou moci zlobivé protějšky znovu připojit (výchozí: %u)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Output debugging information (default: %u, supplying <category> is optional)</source>
|
||||
<translation>Tisknout ladicí informace (výchozí: %u, zadání <category> je volitelné)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Use separate SOCKS5 proxy to reach peers via Tor hidden services (default: %s)</source>
|
||||
<translation>Použít samostatnou SOCKS5 proxy ke spojení s protějšky přes skryté služby v Toru (výchozí: %s)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>(default: %s)</source>
|
||||
<translation>(výchozí: %s)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Acceptable ciphers (default: %s)</source>
|
||||
<translation>Akceptovatelné šifry (výchozí: %s)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Always query for peer addresses via DNS lookup (default: %u)</source>
|
||||
<translation>Vždy získávat adresy dalších protějšků přes DNS (výchozí: %u)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Disable safemode, override a real safe mode event (default: %u)</source>
|
||||
<translation>Vypnout bezpečný režim (safemode), překrýt skutečnou událost bezpečného režimu (výchozí: %u)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Error loading wallet.dat</source>
|
||||
<translation>Chyba při načítání wallet.dat</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Force safe mode (default: %u)</source>
|
||||
<translation>Vynutit bezpečný mód (výchozí: %u)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Generate coins (default: %u)</source>
|
||||
<translation>Těžit (výchozí: %u)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>How many blocks to check at startup (default: %u, 0 = all)</source>
|
||||
<translation>Kolik bloků při startu zkontrolovat (výchozí: %u, 0 = všechny)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Include IP addresses in debug output (default: %u)</source>
|
||||
<translation>Zaznamenávat do ladicích výstupů i IP adresy (výchozí: %u)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Invalid -proxy address: '%s'</source>
|
||||
<translation>Neplatná -proxy adresa: '%s'</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Limit size of signature cache to <n> entries (default: %u)</source>
|
||||
<translation>Omezit velikost vyrovnávací paměti pro podpisy na <n> položek (výchozí: %u)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Listen for JSON-RPC connections on <port> (default: %u or testnet: %u)</source>
|
||||
<translation>Čekat na JSON-RPC spojení na <portu> (výchozí: %u nebo testnet: %u)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Listen for connections on <port> (default: %u or testnet: %u)</source>
|
||||
<translation>Čekat na spojení na <portu> (výchozí: %u nebo testnet: %u)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Maintain at most <n> connections to peers (default: %u)</source>
|
||||
<translation>Povolit nejvýše <n> protějšků (výchozí: %u)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Maximum per-connection receive buffer, <n>*1000 bytes (default: %u)</source>
|
||||
<translation>Maximální velikost přijímacího bufferu pro každé spojení, <n>*1000 bajtů (výchozí: %u)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Maximum per-connection send buffer, <n>*1000 bytes (default: %u)</source>
|
||||
<translation>Maximální velikost odesílacího bufferu pro každé spojení, <n>*1000 bajtů (výchozí: %u)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Only accept block chain matching built-in checkpoints (default: %u)</source>
|
||||
<translation>Uznávat pouze řetězec bloků, který odpovídá vnitřním kontrolním bodům (výchozí: %u)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Prepend debug output with timestamp (default: %u)</source>
|
||||
<translation>Připojit před ladicí výstup časové razítko (výchozí: %u)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Relay and mine data carrier transactions (default: %u)</source>
|
||||
<translation>Přeposílat a těžit transakce nesoucí data (výchozí: %u)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Relay non-P2SH multisig (default: %u)</source>
|
||||
<translation>Přeposílat ne-P2SH multisig (výchozí: %u)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Run a thread to flush wallet periodically (default: %u)</source>
|
||||
<translation>Spustit vlákno pročišťující periodicky peněženku (výchozí: %u)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Server certificate file (default: %s)</source>
|
||||
<translation>Soubor se serverovým certifikátem (výchozí: %s)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Server private key (default: %s)</source>
|
||||
<translation>Soubor se serverovým soukromým klíčem (výchozí: %s)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Set key pool size to <n> (default: %u)</source>
|
||||
<translation>Nastavit zásobník klíčů na velikost <n> (výchozí: %u)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Set minimum block size in bytes (default: %u)</source>
|
||||
<translation>Nastavit minimální velikost bloku v bajtech (výchozí: %u)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Set the number of threads to service RPC calls (default: %d)</source>
|
||||
<translation>Nastavení počtu vláken pro servisní RPC volání (výchozí: %d)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Sets the DB_PRIVATE flag in the wallet db environment (default: %u)</source>
|
||||
<translation>Nastavit příznak DB_PRIVATE v databázovém prostředí peněženky (výchozí: %u)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Specify configuration file (default: %s)</source>
|
||||
<translation>Konfigurační soubor (výchozí: %s)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Specify connection timeout in milliseconds (minimum: 1, default: %d)</source>
|
||||
<translation>Zadej časový limit spojení v milivteřinách (minimum: 1, výchozí: %d)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Spend unconfirmed change when sending transactions (default: %u)</source>
|
||||
<translation>Utrácet i ještě nepotvrzené drobné při posílání transakcí (výchozí: %u)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Stop running after importing blocks from disk (default: %u)</source>
|
||||
<translation>Ukončit se po importu bloků z disku (výchozí: %u)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Threshold for disconnecting misbehaving peers (default: %u)</source>
|
||||
<translation>Práh pro odpojování zlobivých protějšků (výchozí: %u)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Unknown network specified in -onlynet: '%s'</source>
|
||||
<translation>V -onlynet byla uvedena neznámá síť: '%s'</translation>
|
||||
|
@ -3154,10 +3478,6 @@ například: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com
|
|||
<source>Invalid amount for -paytxfee=<amount>: '%s'</source>
|
||||
<translation>Neplatná částka pro -paytxfee=<částka>: '%s'</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Invalid amount</source>
|
||||
<translation>Neplatná částka</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Insufficient funds</source>
|
||||
<translation>Nedostatek prostředků</translation>
|
||||
|
@ -3190,10 +3510,6 @@ například: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com
|
|||
<source>Done loading</source>
|
||||
<translation>Načítání dokončeno</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>To use the %s option</source>
|
||||
<translation>K použití volby %s</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Error</source>
|
||||
<translation>Chyba</translation>
|
||||
|
|
|
@ -1,10 +1,6 @@
|
|||
<TS language="cy" version="2.0">
|
||||
<TS language="cy" version="2.1">
|
||||
<context>
|
||||
<name>AddressBookPage</name>
|
||||
<message>
|
||||
<source>Double-click to edit address or label</source>
|
||||
<translation>Clicio dwywaith i olygu cyfeiriad neu label</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Create a new address</source>
|
||||
<translation>Creu cyfeiriad newydd</translation>
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
<TS language="da" version="2.0">
|
||||
<TS language="da" version="2.1">
|
||||
<context>
|
||||
<name>AddressBookPage</name>
|
||||
<message>
|
||||
<source>Double-click to edit address or label</source>
|
||||
<translation>Dobbeltklik for at redigere adresse eller mærkat</translation>
|
||||
<source>Right-click to edit address or label</source>
|
||||
<translation>Højreklik for at redigere adresse eller mærke</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Create a new address</source>
|
||||
|
@ -1284,6 +1284,14 @@ Adresse: %4
|
|||
<source>Refund from %1</source>
|
||||
<translation>Tilbagebetaling fra %1</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Payment request %1 is too large (%2 bytes, allowed %3 bytes).</source>
|
||||
<translation>Betalingsanmodning %1 er for stor (%2 byte, %3 byte tilladt).</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Payment request DoS protection</source>
|
||||
<translation>Beskyttelse mod DoS-angreb via betalingsanmodninger</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Error communicating with %1: %2</source>
|
||||
<translation>Fejl under kommunikation med %1: %2</translation>
|
||||
|
@ -2802,30 +2810,6 @@ Adresse: %4
|
|||
<source>Accept connections from outside (default: 1 if no -proxy or -connect)</source>
|
||||
<translation>Acceptér forbindelser udefra (standard: 1 hvis hverken -proxy eller -connect)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>%s, you must set a rpcpassword in the configuration file:
|
||||
%s
|
||||
It is recommended you use the following random password:
|
||||
rpcuser=bitcoinrpc
|
||||
rpcpassword=%s
|
||||
(you do not need to remember this password)
|
||||
The username and password MUST NOT be the same.
|
||||
If the file does not exist, create it with owner-readable-only file permissions.
|
||||
It is also recommended to set alertnotify so you are notified of problems;
|
||||
for example: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com
|
||||
</source>
|
||||
<translation>%s, du skal angive en RPC-adgangskode i konfigurationsfilen:
|
||||
%s
|
||||
Det anbefales, at du bruger nedenstående, tilfældige adgangskode:
|
||||
rpcuser=bitcoinrpc
|
||||
rpcpassword=%s
|
||||
(du behøver ikke huske denne adgangskode)
|
||||
Brugernavnet og adgangskode MÅ IKKE være det samme.
|
||||
Hvis filen ikke eksisterer, opret den og giv ingen andre end ejeren læserettighed.
|
||||
Det anbefales også at angive alertnotify, så du påmindes om problemer;
|
||||
fx: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com
|
||||
</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Bind to given address and always listen on it. Use [host]:port notation for IPv6</source>
|
||||
<translation>Tildel til den givne adresse og lyt altid på den. Brug [vært]:port-notation for IPv6</translation>
|
||||
|
@ -2842,14 +2826,6 @@ fx: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com
|
|||
<source>Enter regression test mode, which uses a special chain in which blocks can be solved instantly.</source>
|
||||
<translation>Start regressionstesttilstand, som bruger en speciel kæde, hvor blokke kan løses med det samme.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Error: The transaction was rejected! This might happen if some of the coins in your wallet were already spent, such as if you used a copy of wallet.dat and coins were spent in the copy but not marked as spent here.</source>
|
||||
<translation>Fejl: Transaktionen blev afvist. Dette kan ske, hvis nogle af dine bitcoins i din tegnebog allerede er brugt, som hvis du brugte en kopi af wallet.dat og dine bitcoins er blevet brugt i kopien, men ikke er markeret som brugt her.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Error: This transaction requires a transaction fee of at least %s because of its amount, complexity, or use of recently received funds!</source>
|
||||
<translation>Fejl: Denne transaktion kræver et transaktionsgebyr på minimum %s pga. dens beløb, kompleksitet eller anvendelse af nyligt modtagne bitcoins!</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Execute command when a wallet transaction changes (%s in cmd is replaced by TxID)</source>
|
||||
<translation>Udfør kommando, når en transaktion i tegnebogen ændres (%s i kommandoen erstattes med TxID)</translation>
|
||||
|
@ -2962,10 +2938,6 @@ fx: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com
|
|||
<source>Error: Disk space is low!</source>
|
||||
<translation>Fejl: Mangel på ledig diskplads!</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Error: Wallet locked, unable to create transaction!</source>
|
||||
<translation>Fejl: Tegnebog låst, kan ikke oprette transaktion!</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Failed to listen on any port. Use -listen=0 if you want this.</source>
|
||||
<translation>Lytning på enhver port mislykkedes. Brug -listen=0, hvis du ønsker dette.</translation>
|
||||
|
@ -3090,14 +3062,30 @@ fx: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com
|
|||
<source>Fees (in BTC/Kb) smaller than this are considered zero fee for transaction creation (default: %s)</source>
|
||||
<translation>Gebyrer (i BTC/Kb) mindre end dette opfattes som nulgebyr for oprettelse af transaktion (standard: %s)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>If paytxfee is not set, include enough fee so transactions begin confirmation on average within n blocks (default: %u)</source>
|
||||
<translation>Hvis paytxfee ikke er sat, inkluderes nok gebyr til at transaktioner begynder at blive bekræftet ingen for gennemsnitligt n blokke (standard: %u)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Invalid amount for -maxtxfee=<amount>: '%s' (must be at least the minrelay fee of %s to prevent stuck transactions)</source>
|
||||
<translation>Ugyldigt beløb for -maxtxfee=<beløb>: "%s" (skal være på mindst minrelay-gebyret på %s for at undgå hængende transaktioner)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Maximum size of data in data carrier transactions we relay and mine (default: %u)</source>
|
||||
<translation>Maksimal størrelse på data i transaktioner til dataoverførsel, som vi videresender og miner (standard: %u)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Maximum total fees to use in a single wallet transaction, setting too low may abort large transactions (default: %s)</source>
|
||||
<translation>Maksimalt totalgebyr der bruges på en enkelt tegnebogstransaktion. Sættes det for lavt kan store transaktioner afbrydes (standard: %s)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Query for peer addresses via DNS lookup, if low on addresses (default: 1 unless -connect)</source>
|
||||
<translation>Forespørgsel</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Require high priority for relaying free or low-fee transactions (default:%u)</source>
|
||||
<translation>Kræv høj prioritet for at videresende transaktioner med intet eller lavt gebyr (standard: %u)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Set maximum size of high-priority/low-fee transactions in bytes (default: %d)</source>
|
||||
<translation>Sæt maksimumstørrelse for højprioritet/lavgebyr-transaktioner i byte (standard: %d)</translation>
|
||||
|
@ -3110,6 +3098,34 @@ fx: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com
|
|||
<source>This product includes software developed by the OpenSSL Project for use in the OpenSSL Toolkit <https://www.openssl.org/> and cryptographic software written by Eric Young and UPnP software written by Thomas Bernard.</source>
|
||||
<translation>Dette produkt indeholder software, der er udviklet af OpenSSL-projektet for brug i OpenSSL-værktøjskassen <https://www.openssl.org/>, samt kryptografisk software, der er skrevet af Eric Young, samt UPnP-software, der er skrevet af Thomas Bernard.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>To use bitcoind, or the -server option to bitcoin-qt, you must set an rpcpassword in the configuration file:
|
||||
%s
|
||||
It is recommended you use the following random password:
|
||||
rpcuser=bitcoinrpc
|
||||
rpcpassword=%s
|
||||
(you do not need to remember this password)
|
||||
The username and password MUST NOT be the same.
|
||||
If the file does not exist, create it with owner-readable-only file permissions.
|
||||
It is also recommended to set alertnotify so you are notified of problems;
|
||||
for example: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com
|
||||
</source>
|
||||
<translation>For at bruge bitcoind eller valgmuligheden -server i bitcoin-qt skal du oprette et rpcpassword i konfigurationsfilen:
|
||||
%s
|
||||
Det anbefales, at du bruger følgende tilfældige adgangskode:
|
||||
rpcuser=bitcoinrpc
|
||||
rpcpassword=%s
|
||||
(du behøver ikke at huske adgangskoden)
|
||||
Brugernavnet og adgangskoden MÅ IKKE være det samme.
|
||||
Hvis filen ikke eksisterer, opret den da så kun ejeren har læserettigheder.
|
||||
Det anbefales også at sætte alertnotify, så du får besked omkring problemer;
|
||||
for eksempel: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com
|
||||
</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Warning: -maxtxfee is set very high! Fees this large could be paid on a single transaction.</source>
|
||||
<translation>Advarsel: -maxtxfee er sat meget højt! Så store gebyrer kan betales på en enkelt transaktion.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Warning: Please check that your computer's date and time are correct! If your clock is wrong Bitcoin Core will not work properly.</source>
|
||||
<translation>Advarsel: Undersøg venligst at din computers dato og klokkeslet er korrekt indstillet! Hvis der er fejl i disse vil Bitcoin Core ikke fungere korrekt.</translation>
|
||||
|
@ -3118,6 +3134,10 @@ fx: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com
|
|||
<source>Whitelisted peers cannot be DoS banned and their transactions are always relayed, even if they are already in the mempool, useful e.g. for a gateway</source>
|
||||
<translation>Andre knuder på hvidliste kan ikke DoS-bandlyses, og deres transaktioner videresendes altid, selv hvis de allerede er i mempool'en. Brugbart til fx et adgangspunkt</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Accept public REST requests (default: %u)</source>
|
||||
<translation>Acceptér offentlige REST-anmodninger (standard: %u)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Cannot resolve -whitebind address: '%s'</source>
|
||||
<translation>Kan ikke løse -whitebind adresse: "%s"</translation>
|
||||
|
@ -3138,6 +3158,10 @@ fx: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com
|
|||
<source>Error loading wallet.dat: Wallet requires newer version of Bitcoin Core</source>
|
||||
<translation>Fejl ved indlæsning af wallet.dat: Tegnebog kræver en nyere version af Bitcoin Core</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Error reading from database, shutting down.</source>
|
||||
<translation>Fejl under læsning fra database; lukker ned.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Error: Unsupported argument -tor found, use -onion.</source>
|
||||
<translation>Fejl: Ikke understøttet argument -tor fundet, brug -onion.</translation>
|
||||
|
@ -3154,6 +3178,10 @@ fx: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com
|
|||
<source>Initialization sanity check failed. Bitcoin Core is shutting down.</source>
|
||||
<translation>Sundhedstjek under klargøring mislykkedes. Bitcoin Core lukker ned.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Invalid amount for -maxtxfee=<amount>: '%s'</source>
|
||||
<translation>Ugyldigt beløb for -maxtxfee=<beløb>: "%s"</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Invalid amount for -minrelaytxfee=<amount>: '%s'</source>
|
||||
<translation>Ugyldigt beløb til -minrelaytxfee=<beløb>: "%s"</translation>
|
||||
|
@ -3170,10 +3198,6 @@ fx: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com
|
|||
<source>Invalid netmask specified in -whitelist: '%s'</source>
|
||||
<translation>Ugyldig netmaske angivet i -whitelist: "%s"</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Keep at most <n> unconnectable blocks in memory (default: %u)</source>
|
||||
<translation>Behold højest <n> uforbindelige blokke i hukommelsen (standard: %u)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Keep at most <n> unconnectable transactions in memory (default: %u)</source>
|
||||
<translation>Behold højest <n> uforbindelige transaktioner i hukommelsen (standard: %u)</translation>
|
||||
|
@ -3186,10 +3210,6 @@ fx: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com
|
|||
<source>Node relay options:</source>
|
||||
<translation>Videresendelsesvalgmuligheder for knude:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Print block on startup, if found in block index</source>
|
||||
<translation>Udskriv blok under opstart, hvis den findes i blokindeks</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>RPC SSL options: (see the Bitcoin Wiki for SSL setup instructions)</source>
|
||||
<translation>Tilvalg for RPC SSL: (se Bitcoin Wiki for instruktioner i SSL-opstart)</translation>
|
||||
|
@ -3198,6 +3218,10 @@ fx: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com
|
|||
<source>RPC server options:</source>
|
||||
<translation>Tilvalg for RPC-server:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>RPC support for HTTP persistent connections (default: %d)</source>
|
||||
<translation>RPC-understøttelse for HTTP-persistente forbindelser (standard: %d)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Randomly drop 1 of every <n> network messages</source>
|
||||
<translation>Drop tilfældigt 1 ud af hver <n> netværksbeskeder</translation>
|
||||
|
@ -3238,6 +3262,10 @@ fx: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com
|
|||
<source>Transaction amounts must be positive</source>
|
||||
<translation>Transaktionsbeløb skal være positive</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Transaction too large for fee policy</source>
|
||||
<translation>Transaktion for stor til gebyrretningslinjer</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Transaction too large</source>
|
||||
<translation>Transaktionen er for stor</translation>
|
||||
|
@ -3334,10 +3362,6 @@ fx: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com
|
|||
<source>How thorough the block verification of -checkblocks is (0-4, default: %u)</source>
|
||||
<translation>Hvor gennemarbejdet blokverificeringen for -checkblocks er (0-4; standard: %u)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>If paytxfee is not set, include enough fee so transactions are confirmed on average within n blocks (default: %u)</source>
|
||||
<translation>Hvis paytxfee ikke er angivet, inkludér da nok gebyr til at transaktioner gennemsnitligt bekræftes inden for n blokke (standard: %u)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Log transaction priority and fee per kB when mining blocks (default: %u)</source>
|
||||
<translation>Prioritet for transaktionslog og gebyr pr. kB under udvinding af blokke (standard: %u)</translation>
|
||||
|
@ -3430,10 +3454,6 @@ fx: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com
|
|||
<source>Prepend debug output with timestamp (default: %u)</source>
|
||||
<translation>Føj tidsstempel foran fejlsøgningsoutput (standard: %u)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Print block tree on startup (default: %u)</source>
|
||||
<translation>Udskriv bloktræ under opstart (standard: %u)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Relay and mine data carrier transactions (default: %u)</source>
|
||||
<translation>Videresend og udvind databærer-transaktioner (standard: %u)</translation>
|
||||
|
@ -3512,10 +3532,6 @@ fx: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com
|
|||
<source>Invalid amount for -paytxfee=<amount>: '%s'</source>
|
||||
<translation>Ugyldigt beløb for -paytxfee=<beløb>: "%s"</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Invalid amount</source>
|
||||
<translation>Ugyldigt beløb</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Insufficient funds</source>
|
||||
<translation>Manglende dækning</translation>
|
||||
|
@ -3548,10 +3564,6 @@ fx: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com
|
|||
<source>Done loading</source>
|
||||
<translation>Indlæsning gennemført</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>To use the %s option</source>
|
||||
<translation>For at bruge %s mulighed</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Error</source>
|
||||
<translation>Fejl</translation>
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
<TS language="de" version="2.0">
|
||||
<TS language="de" version="2.1">
|
||||
<context>
|
||||
<name>AddressBookPage</name>
|
||||
<message>
|
||||
<source>Double-click to edit address or label</source>
|
||||
<translation>Doppelklick zum Bearbeiten der Adresse oder der Bezeichnung</translation>
|
||||
<source>Right-click to edit address or label</source>
|
||||
<translation>Rechtsklick zum Bearbeiten der Adresse oder der Bezeichnung</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Create a new address</source>
|
||||
|
@ -478,6 +478,10 @@
|
|||
<source>Up to date</source>
|
||||
<translation>Auf aktuellem Stand</translation>
|
||||
</message>
|
||||
<message numerus="yes">
|
||||
<source>Processed %n blocks of transaction history.</source>
|
||||
<translation><numerusform>%n Block des Transaktionsverlaufs verarbeitet.</numerusform><numerusform>%n Blöcke des Transaktionsverlaufs verarbeitet.</numerusform></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Catching up...</source>
|
||||
<translation>Hole auf...</translation>
|
||||
|
@ -862,7 +866,7 @@ Adresse: %4</translation>
|
|||
</message>
|
||||
<message>
|
||||
<source>Set SSL root certificates for payment request (default: -system-)</source>
|
||||
<translation>SSL-Wurzelzertifikate für Zahlungsanforderungen festlegen (Standard: Systemstandard)</translation>
|
||||
<translation>SSL-Wurzelzertifikate für Zahlungsanforderungen festlegen (Standard: -system-)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Show splash screen on startup (default: 1)</source>
|
||||
|
@ -1283,6 +1287,14 @@ Adresse: %4</translation>
|
|||
<source>Refund from %1</source>
|
||||
<translation>Rücküberweisung von %1</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Payment request %1 is too large (%2 bytes, allowed %3 bytes).</source>
|
||||
<translation>Zahlungsanforderung %1 ist zu groß (%2 Byte, erlaubt sind %3 Byte).</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Payment request DoS protection</source>
|
||||
<translation>Zahlungsanforderungs-DoS-Schutz</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Error communicating with %1: %2</source>
|
||||
<translation>Kommunikationsfehler mit %1: %2</translation>
|
||||
|
@ -2801,30 +2813,6 @@ Adresse: %4</translation>
|
|||
<source>Accept connections from outside (default: 1 if no -proxy or -connect)</source>
|
||||
<translation>Eingehende Verbindungen annehmen (Standard: 1, wenn nicht -proxy oder -connect)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>%s, you must set a rpcpassword in the configuration file:
|
||||
%s
|
||||
It is recommended you use the following random password:
|
||||
rpcuser=bitcoinrpc
|
||||
rpcpassword=%s
|
||||
(you do not need to remember this password)
|
||||
The username and password MUST NOT be the same.
|
||||
If the file does not exist, create it with owner-readable-only file permissions.
|
||||
It is also recommended to set alertnotify so you are notified of problems;
|
||||
for example: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com
|
||||
</source>
|
||||
<translation>%s, Sie müssen den Wert rpcpasswort in dieser Konfigurationsdatei angeben:
|
||||
%s
|
||||
Es wird empfohlen das folgende Zufallspasswort zu verwenden:
|
||||
rpcuser=bitcoinrpc
|
||||
rpcpassword=%s
|
||||
(Sie müssen sich dieses Passwort nicht merken!)
|
||||
Der Benutzername und das Passwort dürfen NICHT identisch sein.
|
||||
Falls die Konfigurationsdatei nicht existiert, erzeugen Sie diese bitte mit Leserechten nur für den Dateibesitzer.
|
||||
Es wird ebenfalls empfohlen alertnotify anzugeben, um im Problemfall benachrichtig zu werden;
|
||||
zum Beispiel: alertnotify=echo %%s | mail -s \"Bitcoin Alert\" admin@foo.com
|
||||
</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Bind to given address and always listen on it. Use [host]:port notation for IPv6</source>
|
||||
<translation>An die angegebene Adresse binden und immer abhören. Für IPv6 "[Host]:Port"-Notation verwenden</translation>
|
||||
|
@ -2841,14 +2829,6 @@ zum Beispiel: alertnotify=echo %%s | mail -s \"Bitcoin Alert\" admin@foo.com
|
|||
<source>Enter regression test mode, which uses a special chain in which blocks can be solved instantly.</source>
|
||||
<translation>Regressionstest-Modus aktivieren, der eine spezielle Blockkette nutzt, in der Blöcke sofort gelöst werden können.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Error: The transaction was rejected! This might happen if some of the coins in your wallet were already spent, such as if you used a copy of wallet.dat and coins were spent in the copy but not marked as spent here.</source>
|
||||
<translation>Fehler: Die Transaktion wurde abgelehnt! Dies kann passieren, wenn einige Bitcoins aus Ihrer Wallet bereits ausgegeben wurden. Beispielsweise weil Sie eine Kopie Ihrer wallet.dat genutzt, die Bitcoins dort ausgegeben haben und dies daher in der derzeit aktiven Wallet nicht vermerkt ist.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Error: This transaction requires a transaction fee of at least %s because of its amount, complexity, or use of recently received funds!</source>
|
||||
<translation>Fehler: Diese Transaktion benötigt aufgrund Ihres Betrags, Ihrer Komplexität oder der Nutzung erst kürzlich erhaltener Zahlungen eine Transaktionsgebühr in Höhe von mindestens %s!</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Execute command when a wallet transaction changes (%s in cmd is replaced by TxID)</source>
|
||||
<translation>Befehl ausführen wenn sich eine Wallet-Transaktion verändert (%s im Befehl wird durch die Transaktions-ID ersetzt)</translation>
|
||||
|
@ -2961,10 +2941,6 @@ zum Beispiel: alertnotify=echo %%s | mail -s \"Bitcoin Alert\" admin@foo.com
|
|||
<source>Error: Disk space is low!</source>
|
||||
<translation>Fehler: Zu wenig freier Speicherplatz auf dem Datenträger!</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Error: Wallet locked, unable to create transaction!</source>
|
||||
<translation>Fehler: Wallet gesperrt, Transaktion kann nicht erstellt werden!</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Failed to listen on any port. Use -listen=0 if you want this.</source>
|
||||
<translation>Fehler, es konnte kein Port abgehört werden. Wenn dies so gewünscht wird -listen=0 verwenden.</translation>
|
||||
|
@ -3089,14 +3065,30 @@ zum Beispiel: alertnotify=echo %%s | mail -s \"Bitcoin Alert\" admin@foo.com
|
|||
<source>Fees (in BTC/Kb) smaller than this are considered zero fee for transaction creation (default: %s)</source>
|
||||
<translation>Niedrigere Gebühren (in BTC/Kb) als diese werden bei der Transaktionserstellung als gebührenfrei angesehen (Standard: %s)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>If paytxfee is not set, include enough fee so transactions begin confirmation on average within n blocks (default: %u)</source>
|
||||
<translation>Wenn -paytxfee nicht festgelegt wurde Gebühren einschließen, so dass mit der Bestätigung von Transaktionen im Schnitt innerhalb von n Blöcken begonnen wird (Standard: %u)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Invalid amount for -maxtxfee=<amount>: '%s' (must be at least the minrelay fee of %s to prevent stuck transactions)</source>
|
||||
<translation>Ungültiger Betrag für -maxtxfee=<amount>: '%s' (muss mindestens die minimale Weiterleitungsgebühr in Höhe von %s sein, um zu verhindern dass Transaktionen nicht bearbeitet werden)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Maximum size of data in data carrier transactions we relay and mine (default: %u)</source>
|
||||
<translation>Maximale Datengröße in "Data Carrier"-Transaktionen die weitergeleitet und erarbeitet werden (Standard: %u)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Maximum total fees to use in a single wallet transaction, setting too low may abort large transactions (default: %s)</source>
|
||||
<translation>Maximale Gesamtgebühren je Wallet-Transaktion, ein zu niedriger Wert kann große Transaktionen abbrechen (Standard: %s)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Query for peer addresses via DNS lookup, if low on addresses (default: 1 unless -connect)</source>
|
||||
<translation>Adressen von Gegenstellen via DNS-Namensauflösung finden, falls zu wenige Adressen verfügbar sind (Standard: 1, außer bei -connect)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Require high priority for relaying free or low-fee transactions (default:%u)</source>
|
||||
<translation>Zum Weiterleiten von freien Transaktionen oder Transaktionen mit niedrigen Gebühren eine hohe Priorität voraussetzen (Standard: %u)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Set maximum size of high-priority/low-fee transactions in bytes (default: %d)</source>
|
||||
<translation>Maximale Größe in Byte von "high-priority/low-fee"-Transaktionen festlegen (Standard: %d)</translation>
|
||||
|
@ -3109,6 +3101,34 @@ zum Beispiel: alertnotify=echo %%s | mail -s \"Bitcoin Alert\" admin@foo.com
|
|||
<source>This product includes software developed by the OpenSSL Project for use in the OpenSSL Toolkit <https://www.openssl.org/> and cryptographic software written by Eric Young and UPnP software written by Thomas Bernard.</source>
|
||||
<translation>Dieses Produkt enthält Software, die vom OpenSSL-Projekt zur Verwendung im OpenSSL-Toolkit <https://www.openssl.org/> entwickelt wird, sowie von Eric Young geschriebene kryptographische Software und von Thomas Bernard geschriebene UPnP-Software.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>To use bitcoind, or the -server option to bitcoin-qt, you must set an rpcpassword in the configuration file:
|
||||
%s
|
||||
It is recommended you use the following random password:
|
||||
rpcuser=bitcoinrpc
|
||||
rpcpassword=%s
|
||||
(you do not need to remember this password)
|
||||
The username and password MUST NOT be the same.
|
||||
If the file does not exist, create it with owner-readable-only file permissions.
|
||||
It is also recommended to set alertnotify so you are notified of problems;
|
||||
for example: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com
|
||||
</source>
|
||||
<translation>Um bitcoind oder die Option -server mit bitcoin-qt verwenden zu können, müssen Sie rpcpassword in der Konfigurationsdatei angeben:
|
||||
%s
|
||||
Es wird empfohlen das folgende Zufallspasswort zu verwenden.
|
||||
rpcuser=bitcoinrpc
|
||||
rpcpassword=%s
|
||||
(Sie müssen sich dieses Passwort nicht merken!)
|
||||
Der Benutzername und das Passwort dürfen NICHT identisch sein.
|
||||
Falls die Konfigurationsdatei nicht existiert, erzeugen Sie diese bitte mit Leserechten nur für den Dateibesitzer.
|
||||
Es wird ebenfalls empfohlen alertnotify anzugeben, um im Problemfall benachrichtigt zu werden.
|
||||
Beispiel: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com
|
||||
</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Warning: -maxtxfee is set very high! Fees this large could be paid on a single transaction.</source>
|
||||
<translation>Warnung: -maxtxfee ist auf einen sehr hohen Wert festgelegt! Gebühren dieser Höhe könnten für eine einzelne Transaktion bezahlt werden.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Warning: Please check that your computer's date and time are correct! If your clock is wrong Bitcoin Core will not work properly.</source>
|
||||
<translation>Warnung: Bitte korrigieren Sie die Datums- und Uhrzeiteinstellungen Ihres Computers, da Bitcoin Core ansonsten nicht ordnungsgemäß funktionieren wird.</translation>
|
||||
|
@ -3117,6 +3137,10 @@ zum Beispiel: alertnotify=echo %%s | mail -s \"Bitcoin Alert\" admin@foo.com
|
|||
<source>Whitelisted peers cannot be DoS banned and their transactions are always relayed, even if they are already in the mempool, useful e.g. for a gateway</source>
|
||||
<translation>Erlaubte Gegenstellen werden nicht für DoS-Attacken gesperrt und ihre Transkationen werden immer weitergeleitet, auch wenn sie sich bereits im Speicherpool befinden, was z.B. für Gateways sinnvoll ist.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Accept public REST requests (default: %u)</source>
|
||||
<translation>Öffentliche REST-Anfragen annehmen (Standard: %u)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Cannot resolve -whitebind address: '%s'</source>
|
||||
<translation>Kann Adresse in -whitebind nicht auflösen: '%s'</translation>
|
||||
|
@ -3137,6 +3161,10 @@ zum Beispiel: alertnotify=echo %%s | mail -s \"Bitcoin Alert\" admin@foo.com
|
|||
<source>Error loading wallet.dat: Wallet requires newer version of Bitcoin Core</source>
|
||||
<translation>Fehler beim Laden von wallet.dat: Wallet benötigt neuere Version von Bitcoin Core</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Error reading from database, shutting down.</source>
|
||||
<translation>Fehler beim lesen der Datenbank, Ausführung wird beendet.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Error: Unsupported argument -tor found, use -onion.</source>
|
||||
<translation>Fehler: Nicht unterstütztes Argument -tor gefunden, bitte -onion verwenden.</translation>
|
||||
|
@ -3153,6 +3181,10 @@ zum Beispiel: alertnotify=echo %%s | mail -s \"Bitcoin Alert\" admin@foo.com
|
|||
<source>Initialization sanity check failed. Bitcoin Core is shutting down.</source>
|
||||
<translation>Initialisierungsplausibilitätsprüfung fehlgeschlagen. Bitcoin Core wird beendet.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Invalid amount for -maxtxfee=<amount>: '%s'</source>
|
||||
<translation>Ungültiger Betrag für -maxtxfee=<amount>: '%s'</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Invalid amount for -minrelaytxfee=<amount>: '%s'</source>
|
||||
<translation>Ungültiger Betrag für -minrelaytxfee=<amount>: '%s'</translation>
|
||||
|
@ -3169,10 +3201,6 @@ zum Beispiel: alertnotify=echo %%s | mail -s \"Bitcoin Alert\" admin@foo.com
|
|||
<source>Invalid netmask specified in -whitelist: '%s'</source>
|
||||
<translation>Ungültige Netzmaske angegeben in -whitelist: '%s'</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Keep at most <n> unconnectable blocks in memory (default: %u)</source>
|
||||
<translation>Maximal <n> nicht-verbindbare Blöcke im Speicher halten (Standard: %u)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Keep at most <n> unconnectable transactions in memory (default: %u)</source>
|
||||
<translation>Maximal <n> nicht-verbindbare Transaktionen im Speicher halten (Standard: %u)</translation>
|
||||
|
@ -3185,10 +3213,6 @@ zum Beispiel: alertnotify=echo %%s | mail -s \"Bitcoin Alert\" admin@foo.com
|
|||
<source>Node relay options:</source>
|
||||
<translation>Knoten-Weiterleitungsoptionen:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Print block on startup, if found in block index</source>
|
||||
<translation>Block beim Starten ausgeben, wenn dieser im Blockindex gefunden wurde.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>RPC SSL options: (see the Bitcoin Wiki for SSL setup instructions)</source>
|
||||
<translation>RPC-SSL-Optionen (siehe Bitcoin-Wiki für SSL-Einrichtung):</translation>
|
||||
|
@ -3197,6 +3221,10 @@ zum Beispiel: alertnotify=echo %%s | mail -s \"Bitcoin Alert\" admin@foo.com
|
|||
<source>RPC server options:</source>
|
||||
<translation>RPC-Serveroptionen:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>RPC support for HTTP persistent connections (default: %d)</source>
|
||||
<translation>Unterstützung für persistente HTTP-Verbindungen bei RPC (Standard: %d)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Randomly drop 1 of every <n> network messages</source>
|
||||
<translation>Zufällig eine von <n> Netzwerknachrichten verwerfen</translation>
|
||||
|
@ -3237,6 +3265,10 @@ zum Beispiel: alertnotify=echo %%s | mail -s \"Bitcoin Alert\" admin@foo.com
|
|||
<source>Transaction amounts must be positive</source>
|
||||
<translation>Transaktionsbeträge müssen positiv sein</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Transaction too large for fee policy</source>
|
||||
<translation>Transaktion ist für die Gebührenrichtlinie zu groß</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Transaction too large</source>
|
||||
<translation>Transaktion zu groß</translation>
|
||||
|
@ -3333,10 +3365,6 @@ zum Beispiel: alertnotify=echo %%s | mail -s \"Bitcoin Alert\" admin@foo.com
|
|||
<source>How thorough the block verification of -checkblocks is (0-4, default: %u)</source>
|
||||
<translation>Legt fest, wie gründlich die Blockverifikation von -checkblocks ist (0-4, Standard: %u)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>If paytxfee is not set, include enough fee so transactions are confirmed on average within n blocks (default: %u)</source>
|
||||
<translation>Wenn keine Transaktionsgebühr festgelegt wurde eine Gebühr einbeziehen, sodass Transaktionen im Schnitt innerhalb von <n> Blöcken bestätigt werden (Standard: %u)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Log transaction priority and fee per kB when mining blocks (default: %u)</source>
|
||||
<translation>Transaktionspriorität und Gebühr pro kB beim Erzeugen von Blöcken protokollieren (Standard: %u)</translation>
|
||||
|
@ -3425,10 +3453,6 @@ zum Beispiel: alertnotify=echo %%s | mail -s \"Bitcoin Alert\" admin@foo.com
|
|||
<source>Prepend debug output with timestamp (default: %u)</source>
|
||||
<translation>Debugausgaben einen Zeitstempel voranstellen (Standard: %u)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Print block tree on startup (default: %u)</source>
|
||||
<translation>Blockbaum beim Starten ausgeben (Standard: %u)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Relay and mine data carrier transactions (default: %u)</source>
|
||||
<translation>"Data Carrier"-Transaktionen weiterleiten und erarbeiten (Standard: %u)</translation>
|
||||
|
@ -3505,10 +3529,6 @@ zum Beispiel: alertnotify=echo %%s | mail -s \"Bitcoin Alert\" admin@foo.com
|
|||
<source>Invalid amount for -paytxfee=<amount>: '%s'</source>
|
||||
<translation>Ungültiger Betrag für -paytxfee=<amount>: '%s'</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Invalid amount</source>
|
||||
<translation>Ungültiger Betrag</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Insufficient funds</source>
|
||||
<translation>Unzureichender Kontostand</translation>
|
||||
|
@ -3541,10 +3561,6 @@ zum Beispiel: alertnotify=echo %%s | mail -s \"Bitcoin Alert\" admin@foo.com
|
|||
<source>Done loading</source>
|
||||
<translation>Laden abgeschlossen</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>To use the %s option</source>
|
||||
<translation>Zur Nutzung der %s-Option</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Error</source>
|
||||
<translation>Fehler</translation>
|
||||
|
|
|
@ -1,10 +1,6 @@
|
|||
<TS language="el_GR" version="2.0">
|
||||
<TS language="el_GR" version="2.1">
|
||||
<context>
|
||||
<name>AddressBookPage</name>
|
||||
<message>
|
||||
<source>Double-click to edit address or label</source>
|
||||
<translation>Διπλό-κλικ για επεξεργασία της διεύθυνσης ή της ετικέτας</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Create a new address</source>
|
||||
<translation>Δημιουργία νέας διεύθυνσης</translation>
|
||||
|
@ -2476,43 +2472,10 @@ Address: %4
|
|||
<source>Accept connections from outside (default: 1 if no -proxy or -connect)</source>
|
||||
<translation>Να δέχεσαι συνδέσεις από έξω(προεπιλογή:1)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>%s, you must set a rpcpassword in the configuration file:
|
||||
%s
|
||||
It is recommended you use the following random password:
|
||||
rpcuser=bitcoinrpc
|
||||
rpcpassword=%s
|
||||
(you do not need to remember this password)
|
||||
The username and password MUST NOT be the same.
|
||||
If the file does not exist, create it with owner-readable-only file permissions.
|
||||
It is also recommended to set alertnotify so you are notified of problems;
|
||||
for example: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com
|
||||
</source>
|
||||
<translation>%s, you must set a rpcpassword in the configuration file:
|
||||
%s
|
||||
It is recommended you use the following random password:
|
||||
rpcuser=bitcoinrpc
|
||||
rpcpassword=%s
|
||||
(you do not need to remember this password)
|
||||
The username and password MUST NOT be the same.
|
||||
If the file does not exist, create it with owner-readable-only file permissions.
|
||||
It is also recommended to set alertnotify so you are notified of problems;
|
||||
for example: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com
|
||||
</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Bind to given address and always listen on it. Use [host]:port notation for IPv6</source>
|
||||
<translation>Αποθηκευση σε συγκεκριμένη διεύθυνση. Χρησιμοποιήστε τα πλήκτρα [Host] : συμβολισμός θύρα για IPv6</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Error: The transaction was rejected! This might happen if some of the coins in your wallet were already spent, such as if you used a copy of wallet.dat and coins were spent in the copy but not marked as spent here.</source>
|
||||
<translation>Σφάλμα: Η συναλλαγή απορρίφθηκε.
|
||||
Αυτό ίσως οφείλεται στο ότι τα νομίσματά σας έχουν ήδη ξοδευτεί, π.χ. με την αντιγραφή του wallet.dat σε άλλο σύστημα και την χρήση τους εκεί, χωρίς η συναλλαγή να έχει καταγραφεί στο παρόν σύστημα.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Error: This transaction requires a transaction fee of at least %s because of its amount, complexity, or use of recently received funds!</source>
|
||||
<translation>Σφάλμα: Αυτή η συναλλαγή απαιτεί αμοιβή συναλλαγής τουλάχιστον %s λόγω του μεγέθους, πολυπλοκότητας ή της χρήσης πρόσφατης παραλαβής κεφαλαίου</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Execute command when a wallet transaction changes (%s in cmd is replaced by TxID)</source>
|
||||
<translation>Εκτέλεσε την εντολή όταν το καλύτερο μπλοκ αλλάξει(%s στην εντολή αντικαθίσταται από το hash του μπλοκ)</translation>
|
||||
|
@ -2589,10 +2552,6 @@ for example: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com
|
|||
<source>Error: Disk space is low!</source>
|
||||
<translation>Προειδοποίηση: Χαμηλός χώρος στο δίσκο </translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Error: Wallet locked, unable to create transaction!</source>
|
||||
<translation>Σφάλμα: το πορτοφόλι είναι κλειδωμένο, δεν μπορεί να δημιουργηθεί συναλλαγή</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Failed to listen on any port. Use -listen=0 if you want this.</source>
|
||||
<translation>ταλαιπωρηθειτε για να ακούσετε σε οποιαδήποτε θύρα. Χρήση - ακούστε = 0 , αν θέλετε αυτό.</translation>
|
||||
|
@ -2797,10 +2756,6 @@ for example: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com
|
|||
<source>Invalid -proxy address: '%s'</source>
|
||||
<translation>Δεν είναι έγκυρη η διεύθυνση διαμεσολαβητή: '%s'</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Print block tree on startup (default: %u)</source>
|
||||
<translation>Εκτύπωση μπλοκ δέντρου κατά την εκκίνηση (προεπιλογή: %u)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Server certificate file (default: %s)</source>
|
||||
<translation>Αρχείο πιστοποιητικού του διακομιστή (προεπιλογή: %s)</translation>
|
||||
|
@ -2833,10 +2788,6 @@ for example: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com
|
|||
<source>Invalid amount for -paytxfee=<amount>: '%s'</source>
|
||||
<translation>Μη έγκυρο ποσό για την παράμετρο -paytxfee=<amount>: '%s'</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Invalid amount</source>
|
||||
<translation>Λάθος ποσότητα</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Insufficient funds</source>
|
||||
<translation>Ανεπαρκές κεφάλαιο</translation>
|
||||
|
@ -2869,10 +2820,6 @@ for example: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com
|
|||
<source>Done loading</source>
|
||||
<translation>Η φόρτωση ολοκληρώθηκε</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>To use the %s option</source>
|
||||
<translation>Χρήση της %s επιλογής</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Error</source>
|
||||
<translation>Σφάλμα</translation>
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,10 +1,6 @@
|
|||
<TS language="eo" version="2.0">
|
||||
<TS language="eo" version="2.1">
|
||||
<context>
|
||||
<name>AddressBookPage</name>
|
||||
<message>
|
||||
<source>Double-click to edit address or label</source>
|
||||
<translation>Duoble-klaku por redakti adreson aŭ etikedon</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Create a new address</source>
|
||||
<translation>Krei novan adreson</translation>
|
||||
|
@ -89,6 +85,10 @@
|
|||
<source>Comma separated file (*.csv)</source>
|
||||
<translation>Perkome disigita dosiero (*.csv)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Exporting Failed</source>
|
||||
<translation>ekspotado malsukcesinta</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>AddressTableModel</name>
|
||||
|
@ -282,6 +282,10 @@
|
|||
<source>Open &URI...</source>
|
||||
<translation>Malfermi &URI-on...</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Bitcoin Core client</source>
|
||||
<translation>kliento de bitmon-kerno</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Importing blocks from disk...</source>
|
||||
<translation>Importado de blokoj el disko...</translation>
|
||||
|
@ -422,6 +426,10 @@
|
|||
<source>%1 and %2</source>
|
||||
<translation>%1 kaj %2</translation>
|
||||
</message>
|
||||
<message numerus="yes">
|
||||
<source>%n year(s)</source>
|
||||
<translation><numerusform>%n jaro</numerusform><numerusform>%n jaroj</numerusform></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>%1 behind</source>
|
||||
<translation>mankas %1</translation>
|
||||
|
@ -2079,6 +2087,10 @@ Adreso: %4
|
|||
<source>Show transaction details</source>
|
||||
<translation>Montri detalojn de transakcio</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Exporting Failed</source>
|
||||
<translation>ekspotado malsukcesinta</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Comma separated file (*.csv)</source>
|
||||
<translation>Perkome disigita dosiero (*.csv)</translation>
|
||||
|
@ -2190,42 +2202,10 @@ Adreso: %4
|
|||
<source>Accept connections from outside (default: 1 if no -proxy or -connect)</source>
|
||||
<translation>Akcepti konektojn el ekstere (defaŭlte: 1 se ne estas -proxy nek -connect)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>%s, you must set a rpcpassword in the configuration file:
|
||||
%s
|
||||
It is recommended you use the following random password:
|
||||
rpcuser=bitcoinrpc
|
||||
rpcpassword=%s
|
||||
(you do not need to remember this password)
|
||||
The username and password MUST NOT be the same.
|
||||
If the file does not exist, create it with owner-readable-only file permissions.
|
||||
It is also recommended to set alertnotify so you are notified of problems;
|
||||
for example: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com
|
||||
</source>
|
||||
<translation>%s, vi devas specifi rpcpassword en la konfigura dosiero:
|
||||
%s
|
||||
Estas konsilinde uzi tiun ĉi aleatore kreitan pasvorton:
|
||||
rpcuser=bitcoinrpc
|
||||
rpcpassword=%s
|
||||
(ne utilas al vi memorigi tiun ĉi pasvorton)
|
||||
La salutnomo kaj la pasvorto estu nepre MALSAMAJ.
|
||||
Se la dosiero ne ekzistas, kreu ĝin kun permeso "nur posedanto rajtas legi".
|
||||
Estas konsilinde ankaŭ agordi alertnotify por ke vi ricevu avertojn pri eventualaj problemoj;
|
||||
ekzemple: alertnotify=echo %%s | mail -s "Averto de Bitmono" admin@foo.com
|
||||
</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Bind to given address and always listen on it. Use [host]:port notation for IPv6</source>
|
||||
<translation>Bindi al donita adreso kaj ĉiam aŭskulti per ĝi. Uzu la formaton [gastigo]:pordo por IPv6</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Error: The transaction was rejected! This might happen if some of the coins in your wallet were already spent, such as if you used a copy of wallet.dat and coins were spent in the copy but not marked as spent here.</source>
|
||||
<translation>Eraro: la transakcio estas rifuzita. Tio povas okazi se iom da Bitmono en via monujo jam elspeziĝis (ekz. se vi uzis kopion de wallet.dat kies Bitmono jam elspeziĝis, sed ne estis markita kiel elspezita ĉi tie).</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Error: This transaction requires a transaction fee of at least %s because of its amount, complexity, or use of recently received funds!</source>
|
||||
<translation>Eraro: tiu ĉi transakcio bezonas krompagon de almenaŭ %s pro la sumo, la komplekseco, aŭ la uzo de ĵus ricevita mono!</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Execute command when a wallet transaction changes (%s in cmd is replaced by TxID)</source>
|
||||
<translation>Plenumi komandon kiam monuja transakcio ŝanĝiĝas (%s en cmd anstataŭiĝas per TxID)</translation>
|
||||
|
@ -2302,10 +2282,6 @@ ekzemple: alertnotify=echo %%s | mail -s "Averto de Bitmono" admin@foo.com
|
|||
<source>Error: Disk space is low!</source>
|
||||
<translation>Eraro: restas malmulte da diskospaco!</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Error: Wallet locked, unable to create transaction!</source>
|
||||
<translation>Eraro: monujo ŝlosita, ne eblas krei transakcion!</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Failed to listen on any port. Use -listen=0 if you want this.</source>
|
||||
<translation>Ne sukcesis aŭskulti ajnan pordon. Uzu -listen=0 se tion vi volas.</translation>
|
||||
|
@ -2382,6 +2358,10 @@ ekzemple: alertnotify=echo %%s | mail -s "Averto de Bitmono" admin@foo.com
|
|||
<source>Signing transaction failed</source>
|
||||
<translation>Subskriba transakcio fiaskis</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>This is experimental software.</source>
|
||||
<translation>ĝi estas eksperimenta programo</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Transaction amount too small</source>
|
||||
<translation>Transakcia sumo tro malgranda</translation>
|
||||
|
@ -2474,10 +2454,6 @@ ekzemple: alertnotify=echo %%s | mail -s "Averto de Bitmono" admin@foo.com
|
|||
<source>Invalid amount for -paytxfee=<amount>: '%s'</source>
|
||||
<translation>Nevalida sumo por -paytxfee=<amount>: '%s'</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Invalid amount</source>
|
||||
<translation>Nevalida sumo</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Insufficient funds</source>
|
||||
<translation>Nesufiĉa mono</translation>
|
||||
|
@ -2510,10 +2486,6 @@ ekzemple: alertnotify=echo %%s | mail -s "Averto de Bitmono" admin@foo.com
|
|||
<source>Done loading</source>
|
||||
<translation>Ŝargado finiĝis</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>To use the %s option</source>
|
||||
<translation>Por uzi la agordon %s</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Error</source>
|
||||
<translation>Eraro</translation>
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
<TS language="es" version="2.0">
|
||||
<TS language="es" version="2.1">
|
||||
<context>
|
||||
<name>AddressBookPage</name>
|
||||
<message>
|
||||
<source>Double-click to edit address or label</source>
|
||||
<translation>Haga doble clic para editar la etiqueta o dirección </translation>
|
||||
<source>Right-click to edit address or label</source>
|
||||
<translation>Haz-clic para editar la dirección o etiqueta</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Create a new address</source>
|
||||
|
@ -35,7 +35,7 @@
|
|||
</message>
|
||||
<message>
|
||||
<source>Export the data in the current tab to a file</source>
|
||||
<translation>Exportar a un archivo los datos de esta pestaña</translation>
|
||||
<translation>Exportar los datos en la ficha actual a un archivo</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>&Export</source>
|
||||
|
@ -47,11 +47,11 @@
|
|||
</message>
|
||||
<message>
|
||||
<source>Choose the address to send coins to</source>
|
||||
<translation>Escoja la dirección a la que enviar bitcoins</translation>
|
||||
<translation>Elije la dirección para enviar monedas a</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Choose the address to receive coins with</source>
|
||||
<translation>Escoja la dirección de la que recibir bitcoins</translation>
|
||||
<translation>Elije la dirección para recibir monedas con</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>C&hoose</source>
|
||||
|
@ -67,11 +67,11 @@
|
|||
</message>
|
||||
<message>
|
||||
<source>These are your Bitcoin addresses for sending payments. Always check the amount and the receiving address before sending coins.</source>
|
||||
<translation>Estas son sus direcciones Bitcoin para enviar pagos. Compruebe siempre la cantidad y la dirección receptora antes de enviar bitcoins.</translation>
|
||||
<translation>Estas son tus direcciones Bitcoin para enviar los pagos. Comprueba siempre la cantidad y la dirección receptora antes de enviar las monedas.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>These are your Bitcoin addresses for receiving payments. It is recommended to use a new receiving address for each transaction.</source>
|
||||
<translation>Estas son sus direcciones de Bitcoin para recibir pagos. Se recomienda utilizar una nueva dirección de recepción para cada transacción.</translation>
|
||||
<translation>Estas son tus direcciones de Bitcoin para recibir los pagos. Se recomienda utilizar una nueva dirección de recepción para cada transacción.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Copy &Label</source>
|
||||
|
@ -87,17 +87,13 @@
|
|||
</message>
|
||||
<message>
|
||||
<source>Comma separated file (*.csv)</source>
|
||||
<translation>Archivos de columnas separadas por coma (*.csv)</translation>
|
||||
<translation>Archivos separados por coma (*.csv)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Exporting Failed</source>
|
||||
<translation>Error exportando</translation>
|
||||
<translation>Fallo al exportar</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>There was an error trying to save the address list to %1. Please try again.</source>
|
||||
<translation>Se ha producido un error al intentar guardar la lista de direcciones en %1. Por favor vuelva a intentarlo.</translation>
|
||||
</message>
|
||||
</context>
|
||||
</context>
|
||||
<context>
|
||||
<name>AddressTableModel</name>
|
||||
<message>
|
||||
|
@ -157,7 +153,7 @@
|
|||
</message>
|
||||
<message>
|
||||
<source>Enter the old and new passphrase to the wallet.</source>
|
||||
<translation>Introduzca la contraseña anterior del monedero y la nueva. </translation>
|
||||
<translation>Introduce la antigua y la nueva contraseña a el monedero.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Confirm wallet encryption</source>
|
||||
|
@ -169,7 +165,7 @@
|
|||
</message>
|
||||
<message>
|
||||
<source>Are you sure you wish to encrypt your wallet?</source>
|
||||
<translation>¿Seguro que desea cifrar su monedero?</translation>
|
||||
<translation>¿Estás seguro que deseas cifrar tu monedero ?</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>IMPORTANT: Any previous backups you have made of your wallet file should be replaced with the newly generated, encrypted wallet file. For security reasons, previous backups of the unencrypted wallet file will become useless as soon as you start using the new, encrypted wallet.</source>
|
||||
|
@ -177,7 +173,7 @@
|
|||
</message>
|
||||
<message>
|
||||
<source>Warning: The Caps Lock key is on!</source>
|
||||
<translation>Aviso: ¡La tecla de bloqueo de mayúsculas está activada!</translation>
|
||||
<translation>Aviso: ¡La tecla de Mayúsculas está activada!</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Wallet encrypted</source>
|
||||
|
@ -1288,6 +1284,14 @@ Dirección: %4
|
|||
<source>Refund from %1</source>
|
||||
<translation>Devolución desde %1</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Payment request %1 is too large (%2 bytes, allowed %3 bytes).</source>
|
||||
<translation>La petición de pago %1 es demasiado grande (%2 bytes, permitidos %3 bytes).</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Payment request DoS protection</source>
|
||||
<translation> Solicitud pago de protección DoS</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Error communicating with %1: %2</source>
|
||||
<translation>Error en la comunicación con %1: %2</translation>
|
||||
|
@ -1848,18 +1852,42 @@ Dirección: %4
|
|||
<source>Transaction Fee:</source>
|
||||
<translation>Comisión de Transacción:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Choose...</source>
|
||||
<translation>Elija...</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>collapse fee-settings</source>
|
||||
<translation>Colapsar ajustes de cuota</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Minimize</source>
|
||||
<translation>Minimizar</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>If the custom fee is set to 1000 satoshis and the transaction is only 250 bytes, then "per kilobyte" only pays 250 satoshis in fee, while "at least" pays 1000 satoshis. For transactions bigger than a kilobyte both pay by kilobyte.</source>
|
||||
<translation>Si la tarifa de aduana se establece en 1000 satoshis y la transacción está a disponible a solo 250 bytes, entonces "por kilobyte" sólo paga 250 satoshis de cuota, mientras que "por lo menos" paga 1.000 satoshis. Para las transacciones más grandes que un kilobyte ambos pagan por kilobyte.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>per kilobyte</source>
|
||||
<translation>por kilobyte</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>If the custom fee is set to 1000 satoshis and the transaction is only 250 bytes, then "per kilobyte" only pays 250 satoshis in fee, while "total at least" pays 1000 satoshis. For transactions bigger than a kilobyte both pay by kilobyte.</source>
|
||||
<translation>Si la tarifa de aduana se establece en 1000 satoshis y la transacción está a sólo 250 bytes, entonces "por kilobyte" sólo paga 250 satoshis de cuota, mientras que "el mínimo total" pagaría 1.000 satoshis. Para las transacciones más grandes que un kilobyte ambos pagan por kilobyte</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>total at least</source>
|
||||
<translation>total por lo menos</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Paying only the minimum fee is just fine as long as there is less transaction volume than space in the blocks. But be aware that this can end up in a never confirming transaction once there is more demand for bitcoin transactions than the network can process.</source>
|
||||
<translation>Pagando solamente la cuota mínima es correcto, siempre y cuando haya menos volumen de transacciones que el espacio en los bloques. Pero tenga en cuenta que esto puede terminar en una transacción nunca confirmada, una vez que haya más demanda para transacciones Bitcoin que la red pueda procesar.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>(read the tooltip)</source>
|
||||
<translation>(leer la sugerencia)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Recommended:</source>
|
||||
<translation>Recomendado:</translation>
|
||||
|
@ -1884,6 +1912,10 @@ Dirección: %4
|
|||
<source>fast</source>
|
||||
<translation>rápido</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Send as zero-fee transaction if possible</source>
|
||||
<translation>Enviar transacción, si es posible, sin comisión</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>(confirmation may take longer)</source>
|
||||
<translation>(confirmación puede tardar más tiempo)</translation>
|
||||
|
@ -2778,30 +2810,6 @@ Dirección: %4
|
|||
<source>Accept connections from outside (default: 1 if no -proxy or -connect)</source>
|
||||
<translation>Aceptar conexiones desde el exterior (predeterminado: 1 si no -proxy o -connect)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>%s, you must set a rpcpassword in the configuration file:
|
||||
%s
|
||||
It is recommended you use the following random password:
|
||||
rpcuser=bitcoinrpc
|
||||
rpcpassword=%s
|
||||
(you do not need to remember this password)
|
||||
The username and password MUST NOT be the same.
|
||||
If the file does not exist, create it with owner-readable-only file permissions.
|
||||
It is also recommended to set alertnotify so you are notified of problems;
|
||||
for example: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com
|
||||
</source>
|
||||
<translation>%s, debe establecer un valor rpcpassword en el archivo de configuración:
|
||||
%s
|
||||
Se recomienda utilizar la siguiente contraseña aleatoria:
|
||||
rpcuser=bitcoinrpc
|
||||
rpcpassword=%s
|
||||
(no es necesario recordar esta contraseña)
|
||||
El nombre de usuario y la contraseña DEBEN NO ser iguales.
|
||||
Si el archivo no existe, créelo con permisos de archivo de solo lectura.
|
||||
Se recomienda también establecer alertnotify para recibir notificaciones de problemas.
|
||||
Por ejemplo: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com
|
||||
</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Bind to given address and always listen on it. Use [host]:port notation for IPv6</source>
|
||||
<translation>Vincular a la dirección dada y escuchar siempre en ella. Utilice la notación [host]:port para IPv6</translation>
|
||||
|
@ -2818,14 +2826,6 @@ Por ejemplo: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com
|
|||
<source>Enter regression test mode, which uses a special chain in which blocks can be solved instantly.</source>
|
||||
<translation>Ingresar en el modo de prueba de regresión, que utiliza una cadena especial en la que los bloques se pueden resolver instantáneamente.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Error: The transaction was rejected! This might happen if some of the coins in your wallet were already spent, such as if you used a copy of wallet.dat and coins were spent in the copy but not marked as spent here.</source>
|
||||
<translation>¡Error: se ha rechazado la transacción! Esto puede ocurrir si ya se han gastado algunos de los bitcoins del monedero, como ocurriría si hubiera hecho una copia de wallet.dat y se hubieran gastado bitcoins a partir de la copia, con lo que no se habrían marcado aquí como gastados.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Error: This transaction requires a transaction fee of at least %s because of its amount, complexity, or use of recently received funds!</source>
|
||||
<translation>¡Error: Esta transacción requiere una comisión de al menos %s debido a su cantidad, complejidad, o al uso de fondos recién recibidos!</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Execute command when a wallet transaction changes (%s in cmd is replaced by TxID)</source>
|
||||
<translation>Ejecutar comando cuando una transacción del monedero cambia (%s en cmd se remplazará por TxID)</translation>
|
||||
|
@ -2938,10 +2938,6 @@ Por ejemplo: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com
|
|||
<source>Error: Disk space is low!</source>
|
||||
<translation>Error: ¡Espacio en disco bajo!</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Error: Wallet locked, unable to create transaction!</source>
|
||||
<translation>Error: ¡El monedero está bloqueado; no se puede crear la transacción!</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Failed to listen on any port. Use -listen=0 if you want this.</source>
|
||||
<translation>Ha fallado la escucha en todos los puertos. Use -listen=0 si desea esto.</translation>
|
||||
|
@ -3066,18 +3062,62 @@ Por ejemplo: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com
|
|||
<source>Fees (in BTC/Kb) smaller than this are considered zero fee for transaction creation (default: %s)</source>
|
||||
<translation>Tarifas (en BTC/Kb) más pequeños que esto se consideran cero cuota para la creación de la transacción (por defecto: %s)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>If paytxfee is not set, include enough fee so transactions begin confirmation on average within n blocks (default: %u)</source>
|
||||
<translation>Si el pago de comisión no está establecido, incluir la cuota suficiente para que las transacciones comiencen la confirmación en una media de n bloques ( por defecto :%u)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Maximum size of data in data carrier transactions we relay and mine (default: %u)</source>
|
||||
<translation>El tamaño máximo de los datos en las operaciones de transporte de datos que transmitimos y el mio (default: %u)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Query for peer addresses via DNS lookup, if low on addresses (default: 1 unless -connect)</source>
|
||||
<translation>Consulta de direcciones pares mediante búsqueda de DNS, si bajo en direcciones (por defecto: 1 a menos que - conectar)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Require high priority for relaying free or low-fee transactions (default:%u)</source>
|
||||
<translation>Se requiere alta prioridad para retransmitir transacciones gratis o de baja comisión (por defecto:%u)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Set maximum size of high-priority/low-fee transactions in bytes (default: %d)</source>
|
||||
<translation>Establecer tamaño máximo de las transacciones de alta prioridad/baja comisión en bytes (predeterminado: %d)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Set the number of threads for coin generation if enabled (-1 = all cores, default: %d)</source>
|
||||
<translation>Ajuste el número de hilos para la generación de moneda si está habilitado (-1 = all cores, default: %d)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>This product includes software developed by the OpenSSL Project for use in the OpenSSL Toolkit <https://www.openssl.org/> and cryptographic software written by Eric Young and UPnP software written by Thomas Bernard.</source>
|
||||
<translation>Este producto incluye software desarrollado por el OpenSSL Project para su uso en OpenSSL Toolkit <https://www.openssl.org/>, software de cifrado escrito por Eric Young y software UPnP escrito por Thomas Bernard.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>To use bitcoind, or the -server option to bitcoin-qt, you must set an rpcpassword in the configuration file:
|
||||
%s
|
||||
It is recommended you use the following random password:
|
||||
rpcuser=bitcoinrpc
|
||||
rpcpassword=%s
|
||||
(you do not need to remember this password)
|
||||
The username and password MUST NOT be the same.
|
||||
If the file does not exist, create it with owner-readable-only file permissions.
|
||||
It is also recommended to set alertnotify so you are notified of problems;
|
||||
for example: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com
|
||||
</source>
|
||||
<translation>Para utilizar bitcoind, o la -opción servidor a bitcoin-qt, debes establecer una rpcpassword en el fichero de configuración:
|
||||
%s
|
||||
Se recomienda utilizar la siguiente contraseña aleatoria:
|
||||
rpcuser=bitcoinrpc
|
||||
rpcpassword=%s
|
||||
(no es necesario que recuerdes esta contraseña)
|
||||
El nombre de usuario y contraseña NO DEBEN ser la misma.
|
||||
Si no existe el archivo, crearlo con los permisos de archivos de propietarios de -sólo lectura-.
|
||||
También se recomienda establecer una notificación de alerta para ser notificado de problemas;
|
||||
por ejemplo: alertnotify=echo %% s | correo -s "Alerta Bitcoin" admin@foo.com
|
||||
</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Warning: -maxtxfee is set very high! Fees this large could be paid on a single transaction.</source>
|
||||
<translation>Advertencia: ¡-maxtxfee se establece muy alta! Esta gran tarifa podría ser pagada en una sola transacción .</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Warning: Please check that your computer's date and time are correct! If your clock is wrong Bitcoin Core will not work properly.</source>
|
||||
<translation>Aviso: ¡Comprueba la fecha y hora de tu ordenador y verifica si es correcta! Si no es correcta Bitcoin Core no funcionará adecuadamente.</translation>
|
||||
|
@ -3086,6 +3126,14 @@ Por ejemplo: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com
|
|||
<source>Whitelisted peers cannot be DoS banned and their transactions are always relayed, even if they are already in the mempool, useful e.g. for a gateway</source>
|
||||
<translation>A los equipos en lista blanca no se les pueden prohibir los ataques DoS y sus transacciones siempre son retransmitidas, incluso si ya están en el mempool, es útil por ejemplo para un gateway.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Accept public REST requests (default: %u)</source>
|
||||
<translation>Aceptar solicitudes públicas en FERIADOS (por defecto: %u)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Cannot resolve -whitebind address: '%s'</source>
|
||||
<translation>No se puede resolver -whitebind address: '%s'</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Connect through SOCKS5 proxy</source>
|
||||
<translation>Conectar usando SOCKS5 proxy</translation>
|
||||
|
@ -3094,10 +3142,22 @@ Por ejemplo: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com
|
|||
<source>Copyright (C) 2009-%i The Bitcoin Core Developers</source>
|
||||
<translation>Copyright (C) 2009-%i The Bitcoin Core Developers</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Could not parse -rpcbind value %s as network address</source>
|
||||
<translation>No se pudo analizar -rpcbind valor%s como dirección de red</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Error loading wallet.dat: Wallet requires newer version of Bitcoin Core</source>
|
||||
<translation>Error al cargar wallet.dat: El monedero requiere una versión más reciente de Bitcoin Core</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Error reading from database, shutting down.</source>
|
||||
<translation>Error al leer la base de datos, cerrando.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Error: Unsupported argument -tor found, use -onion.</source>
|
||||
<translation>Error: Argumento encontrado -tor no soportado, utilice -onion</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Fee (in BTC/kB) to add to transactions you send (default: %s)</source>
|
||||
<translation>Cuota (in BTC/kB) para añadir a las transacciones que envíes (por defecto: %s)</translation>
|
||||
|
@ -3110,6 +3170,10 @@ Por ejemplo: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com
|
|||
<source>Initialization sanity check failed. Bitcoin Core is shutting down.</source>
|
||||
<translation>La inicialización de la verificación de validez falló. Se está apagando Bitcoin Core.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Invalid amount for -maxtxfee=<amount>: '%s'</source>
|
||||
<translation>Monto inválido para -maxtxfee=<amount>: '%s'</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Invalid amount for -minrelaytxfee=<amount>: '%s'</source>
|
||||
<translation>Cantidad inválida para -minrelaytxfee=<amount>: '%s'</translation>
|
||||
|
@ -3126,10 +3190,6 @@ Por ejemplo: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com
|
|||
<source>Invalid netmask specified in -whitelist: '%s'</source>
|
||||
<translation>Máscara de red inválida especificada en -whitelist: '%s'</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Keep at most <n> unconnectable blocks in memory (default: %u)</source>
|
||||
<translation>Mantener como máximo <n> bloques no conectables en memoria (por defecto: %u)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Keep at most <n> unconnectable transactions in memory (default: %u)</source>
|
||||
<translation>Mantener como máximo <n> transacciones no conectables en memoria (por defecto: %u)</translation>
|
||||
|
@ -3142,10 +3202,6 @@ Por ejemplo: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com
|
|||
<source>Node relay options:</source>
|
||||
<translation>Opciones de nodos de retransmisión:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Print block on startup, if found in block index</source>
|
||||
<translation>Imprimir bloque al iniciar, si se encuentra en el índice de bloques</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>RPC SSL options: (see the Bitcoin Wiki for SSL setup instructions)</source>
|
||||
<translation>Opciones SSL de RPC: (véase la wiki de Bitcoin para las instrucciones de instalación de SSL)</translation>
|
||||
|
@ -3154,6 +3210,10 @@ Por ejemplo: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com
|
|||
<source>RPC server options:</source>
|
||||
<translation>Opciones de servidor RPC:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>RPC support for HTTP persistent connections (default: %d)</source>
|
||||
<translation>Soporte RPC para conexiones HTTP persistentes (por defecto: %d)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Randomly drop 1 of every <n> network messages</source>
|
||||
<translation>Ignorar 1 de cada <n> mensajes de red al azar</translation>
|
||||
|
@ -3166,6 +3226,10 @@ Por ejemplo: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com
|
|||
<source>Send trace/debug info to console instead of debug.log file</source>
|
||||
<translation>Enviar información de trazas/depuración a la consola en lugar de al archivo debug.log</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Send transactions as zero-fee transactions if possible (default: %u)</source>
|
||||
<translation>Mandar transacciones como comisión-cero si es posible (por defecto: %u)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Show all debugging options (usage: --help -help-debug)</source>
|
||||
<translation>Muestra todas las opciones de depuración (uso: --help -help-debug)</translation>
|
||||
|
@ -3190,6 +3254,10 @@ Por ejemplo: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com
|
|||
<source>Transaction amounts must be positive</source>
|
||||
<translation>Las cantidades en las transacciones deben ser positivas</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Transaction too large for fee policy</source>
|
||||
<translation>Operación demasiado grande para la política de tasas</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Transaction too large</source>
|
||||
<translation>Transacción demasiado grande</translation>
|
||||
|
@ -3219,6 +3287,10 @@ Por ejemplo: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com
|
|||
<source>Warning: This version is obsolete, upgrade required!</source>
|
||||
<translation>Aviso: Esta versión es obsoleta, actualización necesaria!</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Warning: Unsupported argument -benchmark ignored, use -debug=bench.</source>
|
||||
<translation>Advertencia: Argumento no soportado -benchmark ignored, use -debug=bench.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Warning: Unsupported argument -debugnet ignored, use -debug=net.</source>
|
||||
<translation>Aviso: Argumento no sportado -debugnet anticuado, utilice -debug=net.</translation>
|
||||
|
@ -3274,6 +3346,10 @@ Por ejemplo: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com
|
|||
<source>Error loading wallet.dat: Wallet corrupted</source>
|
||||
<translation>Error al cargar wallet.dat: el monedero está dañado</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>(1 = keep tx meta data e.g. account owner and payment request information, 2 = drop tx meta data)</source>
|
||||
<translation>(1 = keep tx meta data e.g. account owner and payment request information, 2 = drop tx meta data)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Flush database activity from memory pool to disk log every <n> megabytes (default: %u)</source>
|
||||
<translation>Volcar la actividad de la base de datos de memoria al registro en disco cada <n> megabytes (predeterminado: %u)</translation>
|
||||
|
@ -3374,14 +3450,14 @@ Por ejemplo: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com
|
|||
<source>Prepend debug output with timestamp (default: %u)</source>
|
||||
<translation>Anteponer marca temporal a la información de depuración (por defecto: %u)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Print block tree on startup (default: %u)</source>
|
||||
<translation>Imprimir árbol de bloques al iniciar (predeterminado: %u)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Relay and mine data carrier transactions (default: %u)</source>
|
||||
<translation>Retransmitir y minar transacciones de transporte de datos (por defecto: %u)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Relay non-P2SH multisig (default: %u)</source>
|
||||
<translation>Relay non-P2SH multisig (default: %u)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Run a thread to flush wallet periodically (default: %u)</source>
|
||||
<translation>Ejecutar un hilo para limpiar de la memoria el monedero periódicamente (predeterminado: %u)</translation>
|
||||
|
@ -3450,10 +3526,6 @@ Por ejemplo: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com
|
|||
<source>Invalid amount for -paytxfee=<amount>: '%s'</source>
|
||||
<translation>Cantidad inválida para -paytxfee=<amount>: '%s'</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Invalid amount</source>
|
||||
<translation>Cuantía no válida</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Insufficient funds</source>
|
||||
<translation>Fondos insuficientes</translation>
|
||||
|
@ -3486,10 +3558,6 @@ Por ejemplo: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com
|
|||
<source>Done loading</source>
|
||||
<translation>Se terminó de cargar</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>To use the %s option</source>
|
||||
<translation>Para utilizar la opción %s</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Error</source>
|
||||
<translation>Error</translation>
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue