Skip to content

Commit a8c69ba

Browse files
committed
Simplify merkle tree classes by directly accessing variables
Remove the getters and setters in Node, InternalNode, and Leaf to simplify the code. This also improves consistency by always using 'digest' instead of 'hash' for merkle tree variable names Signed-off-by: marinamoore <[email protected]>
1 parent 412625d commit a8c69ba

1 file changed

Lines changed: 44 additions & 63 deletions

File tree

tuf/repository_lib.py

Lines changed: 44 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,7 @@ def _generate_and_write_metadata(rolename, metadata_filename,
131131

132132

133133
elif rolename == 'snapshot':
134-
if (snapshot_merkle):
134+
if snapshot_merkle:
135135
root, leaves, metadata = generate_snapshot_metadata(metadata_directory,
136136
roleinfo['version'], roleinfo['expires'],
137137
storage_backend, consistent_snapshot, repository_name,
@@ -140,12 +140,12 @@ def _generate_and_write_metadata(rolename, metadata_filename,
140140

141141
# Add the merkle tree root hash to the timestamp roleinfo
142142
timestamp_roleinfo = tuf.roledb.get_roleinfo('timestamp', repository_name)
143-
timestamp_roleinfo['merkle_root'] = root.hash()
143+
timestamp_roleinfo['merkle_root'] = root.digest
144144

145145
tuf.roledb.update_roleinfo('timestamp', timestamp_roleinfo,
146146
repository_name=repository_name)
147147

148-
write_merkle_paths(root, leaves, storage_backend, metadata_directory)
148+
_write_merkle_paths(root, leaves, storage_backend, metadata_directory)
149149

150150
else:
151151
metadata = generate_snapshot_metadata(metadata_directory,
@@ -1557,57 +1557,44 @@ def _get_hashes_and_length_if_needed(use_length, use_hashes, full_file_path,
15571557

15581558
class Node(object):
15591559
"""
1560-
Merkle tree node that keeps track of the node hash and the parent node.
1560+
Merkle tree node that keeps track of the node digest and the parent node.
15611561
"""
1562-
_parent = None
1563-
_hash = None
1562+
parent = None
1563+
digest = None
15641564

15651565
def __init__(self):
15661566
return
15671567

1568-
def parent(self):
1569-
return self._parent
1570-
1571-
def set_parent(self, parent):
1572-
self._parent = parent
1568+
def is_leaf(self):
1569+
return False
15731570

1574-
def hash(self):
1575-
return self._hash
15761571

15771572

15781573

15791574
class InternalNode(Node):
15801575
"""
15811576
An internal Merkle tree node that keeps track of a left and a right
15821577
child. Upon creation, this node takes in a left and right Node
1583-
and computes the hash of (left + right). In addition, the constructor
1578+
and computes the digest of (left + right). In addition, the constructor
15841579
sets the parent node of left and right to this node to allow for
15851580
traversal of the tree.
15861581
"""
1587-
_left = None
1588-
_right = None
1582+
left = None
1583+
right = None
15891584

15901585
def __init__(self, left, right):
15911586
super(InternalNode, self).__init__()
1592-
self._left = left
1593-
self._right = right
1587+
self.left = left
1588+
self.right = right
15941589

1595-
left.set_parent(self)
1596-
right.set_parent(self)
1590+
left.parent = self
1591+
right.parent = self
15971592
digest_object = securesystemslib.hash.digest(algorithm=HASH_FUNCTION)
15981593

1599-
digest_object.update((left.hash() + right.hash()).encode('utf-8'))
1594+
digest_object.update((left.digest + right.digest).encode('utf-8'))
16001595

1601-
self._hash = digest_object.hexdigest()
1596+
self.digest = digest_object.hexdigest()
16021597

1603-
def left(self):
1604-
return self._left
1605-
1606-
def right(self):
1607-
return self._right
1608-
1609-
def isLeaf(self):
1610-
return False
16111598

16121599

16131600

@@ -1617,44 +1604,38 @@ class Leaf(Node):
16171604
The name should correspond with a metadata file and the contents should
16181605
contain the snapshot information for that metadata file.
16191606
1620-
The constructor takes in a name and contents and computes the hash
1621-
of the contents. The hash may be provided to save computation time
1607+
The constructor takes in a name and contents and computes the digest
1608+
of the contents. The digest may be provided to save computation time
16221609
if it has already been computed.
16231610
"""
16241611
# Merkle Tree leaf
1625-
_contents = None
1626-
_name = None
1612+
contents = None
1613+
name = None
16271614

1628-
def __init__(self, name, contents, digest = None):
1615+
def __init__(self, name, contents, digest=None):
16291616
super(Leaf, self).__init__()
1630-
# Include the name to ensure the hash differs between elements and cannot be replayed
1617+
# Include the name to ensure the digest differs between elements and cannot be replayed
16311618
contents["name"] = name
1632-
self._contents = contents
1633-
self._name = name
1619+
self.contents = contents
1620+
self.name = name
16341621

16351622
if digest:
1636-
self._hash = digest
1623+
self.digest = digest
16371624
else:
16381625
digest_object = securesystemslib.hash.digest(algorithm=HASH_FUNCTION)
16391626
# Hash the canonical json form of the data to ensure consistency
16401627
json_contents = securesystemslib.formats.encode_canonical(contents)
16411628

16421629
digest_object.update(json_contents.encode('utf-8'))
1643-
self._hash = digest_object.hexdigest()
1644-
1645-
def name(self):
1646-
return self._name
1647-
1648-
def contents(self):
1649-
return self._contents
1630+
self.digest = digest_object.hexdigest()
16501631

1651-
def isLeaf(self):
1632+
def is_leaf(self):
16521633
return True
16531634

16541635

16551636

16561637

1657-
def build_merkle_tree(fileinfodict):
1638+
def _build_merkle_tree(fileinfodict):
16581639
"""
16591640
Create a Merkle tree from the snapshot fileinfo and writes it to individual snapshot files
16601641
@@ -1705,7 +1686,7 @@ def build_merkle_tree(fileinfodict):
17051686
# this path to the client for verification
17061687
return root, leaves
17071688

1708-
def write_merkle_paths(root, leaves, storage_backend, merkle_directory):
1689+
def _write_merkle_paths(root, leaves, storage_backend, merkle_directory):
17091690
# The root and leaves must be part of the same fully constructed
17101691
# Merkle tree. Create a path from
17111692
# Each leaf to the root node. This path will be downloaded by
@@ -1720,16 +1701,16 @@ def write_merkle_paths(root, leaves, storage_backend, merkle_directory):
17201701
index = 0
17211702

17221703
while(current_node != root):
1723-
next_node = current_node.parent()
1704+
next_node = current_node.parent
17241705
# TODO: determine left or right upon node creation.
17251706
# This currently determines which sibling to use by
1726-
# finding the sibling that does not match the current hash.
1727-
h_left = next_node.left().hash()
1728-
h_right = next_node.right().hash()
1729-
if current_node.hash() == h_left:
1707+
# finding the sibling that does not match the current digest.
1708+
h_left = next_node.left.digest
1709+
h_right = next_node.right.digest
1710+
if current_node.digest == h_left:
17301711
merkle_path[str(index)] = h_right
17311712
path_directions[str(index)] = -1
1732-
elif current_node.hash() == h_right:
1713+
elif current_node.digest== h_right:
17331714
merkle_path[str(index)] = h_left
17341715
path_directions[str(index)] = 1
17351716
else:
@@ -1742,15 +1723,15 @@ def write_merkle_paths(root, leaves, storage_backend, merkle_directory):
17421723
# Write the path to the merkle_directory
17431724
file_contents = tuf.formats.build_dict_conforming_to_schema(
17441725
tuf.formats.SNAPSHOT_MERKLE_SCHEMA,
1745-
leaf_contents=l.contents(),
1726+
leaf_contents=l.contents,
17461727
merkle_path=merkle_path,
17471728
path_directions=path_directions)
17481729
if storage_backend is None:
17491730
storage_backend = securesystemslib.storage.FilesystemBackend()
17501731
file_content = _get_written_metadata(file_contents)
17511732
file_object = tempfile.TemporaryFile()
17521733
file_object.write(file_content)
1753-
filename = os.path.join(merkle_directory, l.name() + '-snapshot.json')
1734+
filename = os.path.join(merkle_directory, l.name + '-snapshot.json')
17541735
storage_backend.put(file_object, filename)
17551736
file_object.close()
17561737

@@ -1761,12 +1742,12 @@ def _print_merkle_tree(node, level):
17611742
"""
17621743
Recursive function used by print_merkle_tree
17631744
"""
1764-
print('--'* level + node.hash())
1765-
if not node.isLeaf():
1766-
_print_merkle_tree(node.left(), level + 1)
1767-
_print_merkle_tree(node.right(), level + 1)
1745+
print('--'* level + node.digest)
1746+
if not node.is_leaf():
1747+
_print_merkle_tree(node.left, level + 1)
1748+
_print_merkle_tree(node.right, level + 1)
17681749
else:
1769-
print('--' * (level+1) + node.name())
1750+
print('--' * (level+1) + node.name)
17701751

17711752

17721753

@@ -1935,7 +1916,7 @@ def generate_snapshot_metadata(metadata_directory, version, expiration_date,
19351916
meta=fileinfodict)
19361917

19371918
if snapshot_merkle:
1938-
root, leaves = build_merkle_tree(fileinfodict)
1919+
root, leaves = _build_merkle_tree(fileinfodict)
19391920
return root, leaves, metadata
19401921
return metadata
19411922

0 commit comments

Comments
 (0)