else:
raise ValueError('unknown share type: %r' % (share['type'],))
-DONATION_SCRIPT = '4104ffd03de44a6e11b9917f3a29f9443283d9871c9d743ef30d5eddcd37094b64d1b3d8090496b53256786bf5c82932ec23c3b74d9f05a6f95a8b5529352656664bac'.decode('hex')
+DONATION_SCRIPT = '410418ca0d3ae9712c1640692030f4774d66428edce1d75790d470d2e460fd03327141279a73beb92cdcbd64204a90901d135b6e5e6f9d299517424c5ab08d4fac22ac'.decode('hex')
class Share(object):
VERSION = 13
gentx = dict(
version=1,
+ # coinbase timestamp must be older than share/block timestamp
+ # maybe there are more elegant solution, but this hack works quite well for now
+ timestamp=share_info['timestamp'],
tx_ins=[dict(
previous_output=None,
sequence=None,
)
merkle_root = bitcoin_data.check_merkle_link(self.gentx_hash, self.merkle_link)
self.header = dict(self.min_header, merkle_root=merkle_root)
- self.pow_hash = net.PARENT.POW_FUNC(bitcoin_data.block_header_type.pack(self.header))
- self.hash = self.header_hash = bitcoin_data.hash256(bitcoin_data.block_header_type.pack(self.header))
+ self.pow_hash = self.hash = self.header_hash = bitcoin_data.scrypt(bitcoin_data.block_header_type.pack(self.header))
if self.target > net.MAX_TARGET:
from p2pool import p2p
share_info, gentx, other_tx_hashes2, get_share = self.generate_transaction(tracker, self.share_info['share_data'], self.header['bits'].target, self.share_info['timestamp'], self.share_info['bits'].target, self.contents['ref_merkle_link'], [(h, None) for h in other_tx_hashes], self.net, last_txout_nonce=self.contents['last_txout_nonce'])
assert other_tx_hashes2 == other_tx_hashes
+# workaround
if share_info != self.share_info:
raise ValueError('share_info invalid')
if bitcoin_data.hash256(bitcoin_data.tx_type.pack(gentx)) != self.gentx_hash:
other_txs = self._get_other_txs(tracker, known_txs)
if other_txs is None:
return None # not all txs present
- return dict(header=self.header, txs=[self.check(tracker)] + other_txs)
+ return dict(header=self.header, txs=[self.check(tracker)] + other_txs, signature='')
class WeightsSkipList(forest.TrackerSkipList):
try:
share.check(self)
except:
- log.err(None, 'Share check failed:')
+ log.err(None, 'Share check failed: %064x -> %064x' % (share.hash, share.previous_hash if share.previous_hash is not None else 0))
return False
else:
self.verified.add(share)
def think(self, block_rel_height_func, previous_block, bits, known_txs):
desired = set()
+ bad_peer_addresses = set()
# O(len(self.heads))
# make 'unverified heads' set?
# for each overall head, attempt verification
# if it fails, attempt on parent, and repeat
# if no successful verification because of lack of parents, request parent
- bads = set()
+ bads = []
for head in set(self.heads) - set(self.verified.heads):
head_height, last = self.get_height_and_last(head)
for share in self.get_chain(head, head_height if last is None else min(5, max(0, head_height - self.net.CHAIN_LENGTH))):
if self.attempt_verify(share):
break
- if share.hash in self.heads:
- bads.add(share.hash)
+ bads.append(share.hash)
else:
if last is not None:
desired.add((
))
for bad in bads:
assert bad not in self.verified.items
- assert bad in self.heads
+ #assert bad in self.heads
+ bad_share = self.items[bad]
+ if bad_share.peer_addr is not None:
+ bad_peer_addresses.add(bad_share.peer_addr)
if p2pool.DEBUG:
print "BAD", bad
- self.remove(bad)
+ try:
+ self.remove(bad)
+ except NotImplementedError:
+ pass
# try to get at least CHAIN_LENGTH height for each verified head, requesting parents if needed
for head in list(self.verified.heads):
for peer_addr, hash, ts, targ in desired:
print ' ', None if peer_addr is None else '%s:%i' % peer_addr, format_hash(hash), math.format_dt(time.time() - ts), bitcoin_data.target_to_difficulty(targ), ts >= timestamp_cutoff, targ <= target_cutoff
- return best, [(peer_addr, hash) for peer_addr, hash, ts, targ in desired if ts >= timestamp_cutoff], decorated_heads
+ return best, [(peer_addr, hash) for peer_addr, hash, ts, targ in desired if ts >= timestamp_cutoff], decorated_heads, bad_peer_addresses
def score(self, share_hash, block_rel_height_func):
# returns approximate lower bound on chain's hashrate in the last self.net.CHAIN_LENGTH*15//16*self.net.SHARE_PERIOD time
res[share.desired_version] = res.get(share.desired_version, 0) + bitcoin_data.target_to_average_attempts(share.target)
return res
-def get_warnings(tracker, best_share, net, bitcoind_warning, bitcoind_work_value):
+def get_warnings(tracker, best_share, net, bitcoind_getinfo, bitcoind_work_value):
res = []
desired_version_counts = get_desired_version_counts(tracker, best_share,
'An upgrade is likely necessary. Check http://p2pool.forre.st/ for more information.' % (
majority_desired_version, 100*desired_version_counts[majority_desired_version]/sum(desired_version_counts.itervalues())))
- if bitcoind_warning is not None:
- if 'This is a pre-release test build' not in bitcoind_warning:
- res.append('(from bitcoind) %s' % (bitcoind_warning,))
+ if bitcoind_getinfo['errors'] != '':
+ if 'This is a pre-release test build' not in bitcoind_getinfo['errors']:
+ res.append('(from bitcoind) %s' % (bitcoind_getinfo['errors'],))
+
+ version_warning = getattr(net, 'VERSION_WARNING', lambda v: None)(bitcoind_getinfo['version'])
+ if version_warning is not None:
+ res.append(version_warning)
if time.time() > bitcoind_work_value['last_update'] + 60:
res.append('''LOST CONTACT WITH BITCOIND for %s! Check that it isn't frozen or dead!''' % (math.format_dt(time.time() - bitcoind_work_value['last_update']),))