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