make blockchain.size() threadsafe
This commit is contained in:
parent
622f459c41
commit
d71c9d5be3
|
@ -27,6 +27,8 @@
|
|||
|
||||
import os
|
||||
import util
|
||||
import threading
|
||||
|
||||
import bitcoin
|
||||
from bitcoin import *
|
||||
|
||||
|
@ -101,6 +103,9 @@ class Blockchain(util.PrintError):
|
|||
self.catch_up = None # interface catching up
|
||||
self.checkpoint = checkpoint
|
||||
self.parent_id = parent_id
|
||||
self.lock = threading.Lock()
|
||||
with self.lock:
|
||||
self.update_size()
|
||||
|
||||
def parent(self):
|
||||
return blockchains[self.parent_id]
|
||||
|
@ -124,18 +129,23 @@ class Blockchain(util.PrintError):
|
|||
height = header.get('block_height')
|
||||
return header_hash == self.get_hash(height)
|
||||
|
||||
def fork(parent, checkpoint):
|
||||
def fork(parent, header):
|
||||
checkpoint = header.get('block_height')
|
||||
self = Blockchain(parent.config, checkpoint, parent.checkpoint)
|
||||
# create file
|
||||
open(self.path(), 'w+').close()
|
||||
self.save_header(header)
|
||||
return self
|
||||
|
||||
def height(self):
|
||||
return self.checkpoint + self.size() - 1
|
||||
|
||||
def size(self):
|
||||
with self.lock:
|
||||
return self._size
|
||||
|
||||
def update_size(self):
|
||||
p = self.path()
|
||||
return os.path.getsize(p)/80 if os.path.exists(p) else 0
|
||||
self._size = os.path.getsize(p)/80 if os.path.exists(p) else 0
|
||||
|
||||
def verify_header(self, header, prev_header, bits, target):
|
||||
prev_hash = hash_header(prev_header)
|
||||
|
@ -181,9 +191,11 @@ class Blockchain(util.PrintError):
|
|||
if d < 0:
|
||||
chunk = chunk[-d:]
|
||||
d = 0
|
||||
with open(filename, 'rb+') as f:
|
||||
f.seek(d)
|
||||
f.write(chunk)
|
||||
with self.lock:
|
||||
with open(filename, 'rb+') as f:
|
||||
f.seek(d)
|
||||
f.write(chunk)
|
||||
self.update_size()
|
||||
self.swap_with_parent()
|
||||
|
||||
def swap_with_parent(self):
|
||||
|
@ -199,16 +211,20 @@ class Blockchain(util.PrintError):
|
|||
with open(parent.path(), 'rb+') as f:
|
||||
f.seek((checkpoint - parent.checkpoint)*80)
|
||||
parent_data = f.read(parent_branch_size*80)
|
||||
f.seek((checkpoint - parent.checkpoint)*80)
|
||||
f.truncate()
|
||||
with open(self.path(), 'rb+') as f:
|
||||
my_data = f.read()
|
||||
f.seek(0)
|
||||
f.truncate()
|
||||
f.write(parent_data)
|
||||
with open(parent.path(), 'rb+') as f:
|
||||
f.seek((checkpoint - parent.checkpoint)*80)
|
||||
f.write(my_data)
|
||||
with self.lock:
|
||||
with open(self.path(), 'rb+') as f:
|
||||
my_data = f.read()
|
||||
f.seek(0)
|
||||
f.truncate()
|
||||
f.write(parent_data)
|
||||
self.update_size()
|
||||
with parent.lock:
|
||||
with open(parent.path(), 'rb+') as f:
|
||||
f.seek((checkpoint - parent.checkpoint)*80)
|
||||
f.truncate()
|
||||
f.seek((checkpoint - parent.checkpoint)*80)
|
||||
f.write(my_data)
|
||||
parent.update_size()
|
||||
# store file path
|
||||
for b in blockchains.values():
|
||||
b.old_path = b.path()
|
||||
|
@ -231,9 +247,11 @@ class Blockchain(util.PrintError):
|
|||
data = serialize_header(header).decode('hex')
|
||||
assert delta == self.size()
|
||||
assert len(data) == 80
|
||||
with open(filename, 'rb+') as f:
|
||||
f.seek(delta * 80)
|
||||
f.write(data)
|
||||
with self.lock:
|
||||
with open(filename, 'rb+') as f:
|
||||
f.seek(delta * 80)
|
||||
f.write(data)
|
||||
self.update_size()
|
||||
# order files
|
||||
self.swap_with_parent()
|
||||
|
||||
|
|
|
@ -854,8 +854,7 @@ class Network(util.DaemonThread):
|
|||
if bh > interface.good:
|
||||
if not interface.blockchain.check_header(interface.bad_header):
|
||||
if interface.blockchain.can_connect(interface.bad_header, check_height=False):
|
||||
b = interface.blockchain.fork(interface.bad)
|
||||
b.save_header(interface.bad_header)
|
||||
b = interface.blockchain.fork(interface.bad_header)
|
||||
self.blockchains[interface.bad] = b
|
||||
interface.blockchain = b
|
||||
interface.print_error("new chain", b.checkpoint)
|
||||
|
|
Loading…
Reference in New Issue