import threading
import traceback
import urllib
-
+from ltc_scrypt import getPoWHash
from backends.bitcoind import deserialize
from processor import Processor, print_log
from utils import *
}
def get_header(self, height):
- block_hash = self.bitcoind('getblockhash', [height])
- b = self.bitcoind('getblock', [block_hash])
+ b = self.bitcoind('getblockbynumber', [height])
return self.block2header(b)
def init_headers(self, db_height):
self.flush_headers()
def hash_header(self, header):
- return rev_hex(Hash(header_to_string(header).decode('hex')).encode('hex'))
+ return rev_hex(getPoWHash(header_to_string(header).decode('hex')).encode('hex'))
def read_header(self, block_height):
if os.path.exists(self.headers_filename):
vds = deserialize.BCDataStream()
vds.write(raw_tx.decode('hex'))
try:
- return deserialize.parse_Transaction(vds, is_coinbase=False)
+ return deserialize.parse_Transaction(vds, is_coinbase=False, is_coinstake=False)
except:
print_log("ERROR: cannot parse", txid)
return None
def get_merkle(self, tx_hash, height):
- block_hash = self.bitcoind('getblockhash', [height])
- b = self.bitcoind('getblock', [block_hash])
+ b = self.bitcoind('getblockbynumber', [height])
tx_list = b.get('tx')
tx_pos = tx_list.index(tx_hash)
def deserialize_block(self, block):
+ is_stake_block = False
txlist = block.get('tx')
+ if "proof-of-stake" in block.get('flags'): # scan block flags list for
+ is_stake_block = True # "proof-of-stake" substring
+
tx_hashes = [] # ordered txids
txdict = {} # deserialized tx
- is_coinbase = True
- for raw_tx in txlist:
- tx_hash = hash_encode(Hash(raw_tx.decode('hex')))
+
+ for i in xrange(len(txlist)):
+ if is_stake_block and i == 0: # skip coinbase for
+ continue # stake block
+ tx_hash = hash_encode(Hash(txlist[i].decode('hex')))
vds = deserialize.BCDataStream()
- vds.write(raw_tx.decode('hex'))
+ vds.write(txlist[i].decode('hex'))
try:
- tx = deserialize.parse_Transaction(vds, is_coinbase)
- except:
+ tx = deserialize.parse_Transaction(vds, i == 0, is_stake_block and i == 1) # first transaction is always coinbase
+ except: # second transaction is coinstake if we have a stake block
print_log("ERROR: cannot parse", tx_hash)
continue
tx_hashes.append(tx_hash)
txdict[tx_hash] = tx
- is_coinbase = False
return tx_hashes, txdict
elif result != '':
self.push_response(session, {'id': message_id, 'result': result})
-
- def getfullblock(self, block_hash):
- block = self.bitcoind('getblock', [block_hash])
-
- rawtxreq = []
- i = 0
- for txid in block['tx']:
- rawtxreq.append({
- "method": "getrawtransaction",
- "params": [txid],
- "id": i,
- })
- i += 1
-
- postdata = dumps(rawtxreq)
- try:
- respdata = urllib.urlopen(self.bitcoind_url, postdata).read()
- except:
- print_log("bitcoind error (getfullblock)")
- traceback.print_exc(file=sys.stdout)
- self.shared.stop()
-
- r = loads(respdata)
- rawtxdata = []
- for ir in r:
- if ir['error'] is not None:
- self.shared.stop()
- print_log("Error: make sure you run bitcoind with txindex=1; use -reindex if needed.")
- raise BaseException(ir['error'])
- rawtxdata.append(ir['result'])
- block['tx'] = rawtxdata
- return block
-
def catch_up(self, sync=True):
prev_root_hash = None
# not done..
self.up_to_date = False
- next_block_hash = self.bitcoind('getblockhash', [self.storage.height + 1])
- next_block = self.getfullblock(next_block_hash)
+ next_block = self.bitcoind('getblockbynumber', [self.storage.height + 1, True])
+ next_block_hash = next_block.get('hash')
self.mtime('daemon')
# fixme: this is unsafe, if we revert when the undo info is not yet written
else:
# revert current block
- block = self.getfullblock(self.storage.last_hash)
+ block = self.bitcoind('getblock', [self.storage.last_hash, True])
print_log("blockchain reorg", self.storage.height, block.get('previousblockhash'), self.storage.last_hash)
self.import_block(block, self.storage.last_hash, self.storage.height, sync, revert=True)
self.pop_header()
return d
-def parse_Transaction(vds, is_coinbase):
+def parse_Transaction(vds, is_coinbase, is_coinstake):
d = {}
start = vds.read_cursor
d['version'] = vds.read_int32()
+ d['timestamp'] = vds.read_int32()
n_vin = vds.read_compact_size()
d['inputs'] = []
for i in xrange(n_vin):
# print("skipping strange tx output with zero value")
# continue
# if o['address'] != "None":
- d['outputs'].append(o)
+ if not is_coinstake or i > 0: # first coinstake output
+ d['outputs'].append(o) # transaction doesn't make any sense
d['lockTime'] = vds.read_uint32()
return d
match2 = [ opcodes.OP_2, opcodes.OP_PUSHDATA4, opcodes.OP_PUSHDATA4, opcodes.OP_2, opcodes.OP_CHECKMULTISIG ]
if match_decoded(dec2, match2):
pubkeys = [ dec2[1][1].encode('hex'), dec2[2][1].encode('hex') ]
- return pubkeys, signatures, hash_160_to_bc_address(hash_160(redeemScript), 5)
+ return pubkeys, signatures, hash_160_to_bc_address(hash_160(redeemScript), 20)
# 2 of 3
match2 = [ opcodes.OP_2, opcodes.OP_PUSHDATA4, opcodes.OP_PUSHDATA4, opcodes.OP_PUSHDATA4, opcodes.OP_3, opcodes.OP_CHECKMULTISIG ]
if match_decoded(dec2, match2):
pubkeys = [ dec2[1][1].encode('hex'), dec2[2][1].encode('hex'), dec2[3][1].encode('hex') ]
- return pubkeys, signatures, hash_160_to_bc_address(hash_160(redeemScript), 5)
+ return pubkeys, signatures, hash_160_to_bc_address(hash_160(redeemScript), 20)
return [], [], None
# p2sh
match = [ opcodes.OP_HASH160, opcodes.OP_PUSHDATA4, opcodes.OP_EQUAL ]
if match_decoded(decoded, match):
- addr = hash_160_to_bc_address(decoded[1][1],5)
+ addr = hash_160_to_bc_address(decoded[1][1],20)
return addr
return None
fi
-electrum_config="/etc/electrum.conf"
+electrum_config="electrum.conf"
if [ ! -f $electrum_config ]; then
echo "$electrum_config does not exist"
rmdir $path --ignore-fail-on-non-empty
-if [ ! -d $path ]; then
- echo "Database not found in $path."
- read -p "Do you want to download it from the Electrum foundry to $path ? " -n 1 -r
- echo
- if [[ $REPLY =~ ^[Yy]$ ]]; then
- mkdir -p $path
- wget -O - "http://foundry.electrum.org/leveldb-dump/electrum-fulltree-100-latest.tar.gz" | tar --extract --gunzip --strip-components 1 --directory $path --file -
- fi
-fi
+#if [ ! -d $path ]; then
+# echo "Database not found in $path."
+# read -p "Do you want to download it from the Electrum foundry to $path ? " -n 1 -r
+# echo
+# if [[ $REPLY =~ ^[Yy]$ ]]; then
+# mkdir -p $path
+# wget -O - "http://foundry.electrum.org/leveldb-dump/electrum-fulltree-100-latest.tar.gz" | tar --extract --gunzip --strip-components 1 --directory $path --file -
+# fi
+#fi
echo "Starting server as daemon"
-nohup /usr/bin/python -u server.py &> /var/log/electrum.log &
+nohup /usr/bin/python -u server.py &> electrum.log &