Dash Core  0.12.2.1
P2P Digital Currency
blockstore.py
Go to the documentation of this file.
1 # BlockStore: a helper class that keeps a map of blocks and implements
2 # helper functions for responding to getheaders and getdata,
3 # and for constructing a getheaders message
4 #
5 
6 from .mininode import *
7 import dbm
8 from io import BytesIO
9 
10 class BlockStore(object):
11  def __init__(self, datadir):
12  self.blockDB = dbm.open(datadir + "/blocks", 'c')
13  self.currentBlock = 0L
14  self.headers_map = dict()
15 
16  def close(self):
17  self.blockDB.close()
18 
19  def get(self, blockhash):
20  serialized_block = None
21  try:
22  serialized_block = self.blockDB[repr(blockhash)]
23  except KeyError:
24  return None
25  f = BytesIO(serialized_block)
26  ret = CBlock()
27  ret.deserialize(f)
28  ret.calc_sha256()
29  return ret
30 
31  def get_header(self, blockhash):
32  try:
33  return self.headers_map[blockhash]
34  except KeyError:
35  return None
36 
37  # Note: this pulls full blocks out of the database just to retrieve
38  # the headers -- perhaps we could keep a separate data structure
39  # to avoid this overhead.
40  def headers_for(self, locator, hash_stop, current_tip=None):
41  if current_tip is None:
42  current_tip = self.currentBlock
43  current_block_header = self.get_header(current_tip)
44  if current_block_header is None:
45  return None
46 
47  response = msg_headers()
48  headersList = [ current_block_header ]
49  maxheaders = 2000
50  while (headersList[0].sha256 not in locator.vHave):
51  prevBlockHash = headersList[0].hashPrevBlock
52  prevBlockHeader = self.get_header(prevBlockHash)
53  if prevBlockHeader is not None:
54  headersList.insert(0, prevBlockHeader)
55  else:
56  break
57  headersList = headersList[:maxheaders] # truncate if we have too many
58  hashList = [x.sha256 for x in headersList]
59  index = len(headersList)
60  if (hash_stop in hashList):
61  index = hashList.index(hash_stop)+1
62  response.headers = headersList[:index]
63  return response
64 
65  def add_block(self, block):
66  block.calc_sha256()
67  try:
68  self.blockDB[repr(block.sha256)] = bytes(block.serialize())
69  except TypeError as e:
70  print "Unexpected error: ", sys.exc_info()[0], e.args
71  self.currentBlock = block.sha256
72  self.headers_map[block.sha256] = CBlockHeader(block)
73 
74  def add_header(self, header):
75  self.headers_map[header.sha256] = header
76 
77  def get_blocks(self, inv):
78  responses = []
79  for i in inv:
80  if (i.type == 2): # MSG_BLOCK
81  block = self.get(i.hash)
82  if block is not None:
83  responses.append(msg_block(block))
84  return responses
85 
86  def get_locator(self, current_tip=None):
87  if current_tip is None:
88  current_tip = self.currentBlock
89  r = []
90  counter = 0
91  step = 1
92  lastBlock = self.get(current_tip)
93  while lastBlock is not None:
94  r.append(lastBlock.hashPrevBlock)
95  for i in range(step):
96  lastBlock = self.get(lastBlock.hashPrevBlock)
97  if lastBlock is None:
98  break
99  counter += 1
100  if counter > 10:
101  step *= 2
102  locator = CBlockLocator()
103  locator.vHave = r
104  return locator
105 
106 class TxStore(object):
107  def __init__(self, datadir):
108  self.txDB = dbm.open(datadir + "/transactions", 'c')
109 
110  def close(self):
111  self.txDB.close()
112 
113  def get(self, txhash):
114  serialized_tx = None
115  try:
116  serialized_tx = self.txDB[repr(txhash)]
117  except KeyError:
118  return None
119  f = BytesIO(serialized_tx)
120  ret = CTransaction()
121  ret.deserialize(f)
122  ret.calc_sha256()
123  return ret
124 
125  def add_transaction(self, tx):
126  tx.calc_sha256()
127  try:
128  self.txDB[repr(tx.sha256)] = bytes(tx.serialize())
129  except TypeError as e:
130  print "Unexpected error: ", sys.exc_info()[0], e.args
131 
132  def get_transactions(self, inv):
133  responses = []
134  for i in inv:
135  if (i.type == 1): # MSG_TX
136  tx = self.get(i.hash)
137  if tx is not None:
138  responses.append(msg_tx(tx))
139  return responses
def get_locator(self, current_tip=None)
Definition: blockstore.py:86
def headers_for(self, locator, hash_stop, current_tip=None)
Definition: blockstore.py:40
def get_header(self, blockhash)
Definition: blockstore.py:31