API

Chain

Tools for building and interpreting skipchains.

class hippiepug.chain.BlockBuilder(chain)

Customizable builder of skipchain blocks.

You can override the pre-commit hook (BlockBuilder.pre_commit()) to modify the payload before the block is committed to a chain. This is needed, say, if you want to sign the payload before commiting.

Parameters:chain – Chain to which the block should belong.

Set the payload before committing:

>>> from .store import Sha256DictStore
>>> store = Sha256DictStore()
>>> chain = Chain(store)
>>> builder = BlockBuilder(chain)
>>> builder.payload = b'Hello, world!'
>>> block = builder.commit()
>>> block == chain.head_block
True
chain

The associated chain.

commit()

Commit the block to the associated chain.

Returns:The block that was committed.
fingers

Anticipated skip-list fingers (back-pointers to previous blocks).

index

Anticipated index of the block being built.

payload

Anticipated block payload.

pre_commit()

Pre-commit hook.

This can be overriden. For example, you can add a signature that includes index and fingers into your payload before the block is committed.

static skipchain_indices(index)

Finger indices for a given index.

Parameters:index (int>=0) – Block index
class hippiepug.chain.Chain(object_store, head=None, cache=None)

Skipchain (hash chain with skip-list pointers).

To add a new block to a chain, use BlockBuilder.

Warning

All read accesses are cached. The cache is assumed to be trusted, so blocks retrieved from cache are not checked for integrity, unlike when they are retrieved from the object store.

class ChainIterator(current_index, chain)

Chain iterator.

Note

Iterates in the reverse order: latest block first.

__getitem__(index)

Get block by index.

get_block_by_index(index, return_proof=False)

Get block by index.

Optionally returns inclusion proof, that is a list of intermediate blocks, sufficient to verify the inclusion of the retrieved block.

Parameters:
  • index (int>=0) – Block index
  • return_proof (bool) – Whether to return inclusion proof
Returns:

Found block or None, or (block, proof) tuple if return_proof is True.

Raises:

If the index is out of bounds, raises IndexError.

head_block

The latest block in the chain.

hippiepug.chain.verify_chain_inclusion_proof(store, head, block, proof)

Verify inclusion proof for a block on a chain.

Parameters:
  • store – Object store, may be empty
  • head – Chain head
  • block – Block
  • proof (list of decoded blocks) – Inclusion proof
Returns:

bool

Tree

Tools for building and interpreting key-value Merkle trees.

class hippiepug.tree.Tree(object_store, root, cache=None)

View of a Merkle tree.

Use TreeBuilder to build a Merkle tree first.

Parameters:
  • object_store – Object store
  • root – The hash of the root node
  • cache (dict) – Cache

Warning

All read accesses are cached. The cache is assumed to be trusted, so blocks retrieved from cache are not checked for integrity, unlike when they are retrieved from the object store.

__contains__(lookup_key)

Check if lookup key is in the tree.

__getitem__(lookup_key)

Retrieve value by its lookup key.

Returns:Corresponding value
Raises:KeyError when the lookup key was not found.
get_value_by_lookup_key(lookup_key, return_proof=False)

Retrieve value by its lookup key.

Parameters:
  • lookup_key – Lookup key
  • return_proof – Whether to return inclusion proof
Returns:

Only the value when return_proof is False, and a (value, proof) tuple when return_proof is True. A value is None when the lookup key was not found.

root_node

The root node.

class hippiepug.tree.TreeBuilder(object_store)

Builder for a key-value Merkle tree.

Parameters:object_store – Object store

You can add items using a dict-like interface:

>>> from .store import Sha256DictStore
>>> store = Sha256DictStore()
>>> builder = TreeBuilder(store)
>>> builder['foo'] = b'bar'
>>> builder['baz'] = b'zez'
>>> tree = builder.commit()
>>> 'foo' in tree
True
__setitem__(lookup_key, value)

Add item for committing to the tree.

commit()

Commit items to the tree.

hippiepug.tree.verify_tree_inclusion_proof(store, root, lookup_key, value, proof)

Verify inclusion proof for a tree.

Parameters:
  • store – Object store, may be empty
  • head – Tree root
  • lookup_key – Lookup key
  • value – Value associated with the lookup key
  • proof (tuple containing list of decoded path nodes) – Inclusion proof
Returns:

bool

Store

class hippiepug.store.BaseDictStore(backend=None)

Store with dict-like backend.

Parameters:backend (dict-like) – Backend
__contains__(obj_hash)

Check if obj with a given hash is in the store.

add(serialized_obj)

Add an object to the store.

If an object with this hash already exists, silently does nothing.

get(obj_hash, check_integrity=True)

Get an object with a given hash from the store.

If the object does not exist, returns None.

Parameters:
  • obj_hash – ASCII hash of the object
  • check_integrity – Whether to check the hash of the retrieved object against the given hash.
class hippiepug.store.BaseStore

Abstract base class for a content-addresable store.

__contains__(obj_hash)

Check whether the store contains an object with a give hash.

Parameters:obj_hash – ASCII hash
add(serialized_obj)

Put the object in the store.

Parameters:serialized_obj – Object, serialized to bytes
Returns:Hash of the object.
get(obj_hash, check_integrity=True)

Return the object by its ASCII hash value.

Parameters:
  • obj_hash – ASCII hash
  • check_integrity – Whether to check the hash upon retrieval
classmethod hash_object(serialized_obj)

Return the ASCII hash of the object.

Parameters:obj – Object, serialized to bytes
exception hippiepug.store.IntegrityValidationError
class hippiepug.store.Sha256DictStore(backend=None)

Dict-based store using truncated SHA256 hex-encoded hashes.

>>> store = Sha256DictStore()
>>> obj = b'dummy'
>>> obj_hash = store.hash_object(obj)
>>> store.add(obj) == obj_hash
True
>>> obj_hash in store
True
>>> b'nonexistent' not in store
True
>>> store.get(obj_hash) == obj
True
hash_object(serialized_obj)

Return a SHA256 hex-encoded hash of a serialized object.

Basic containers

Basic building blocks.

class hippiepug.struct.ChainBlock(payload, index=0, fingers=NOTHING)

Skipchain block.

Parameters:
  • payload – Block payload
  • index – Block index
  • fingers – Back-pointers to previous blocks
class hippiepug.struct.TreeLeaf(lookup_key=None, payload_hash=None)

Merkle tree leaf.

Parameters:
  • lookup_key – Lookup key
  • payload_hash – Hash of the payload
class hippiepug.struct.TreeNode(pivot_prefix, left_hash=None, right_hash=None)

Merkle tree intermediate node.

Parameters:
  • pivot_prefix – Pivot key for the subtree
  • left_hash – Hash of the left child
  • right_hash – Hash of the right child

Serialization

Serializers for chain blocks and tree nodes.

Warning

You need to take extra care when defining custom serializations. Be sure that your serialization includes all the fields in the original structure. E.g., for chain blocks:

  • self.index
  • self.fingers
  • Your payload

Unless this is done, the integrity of the data structures is screwed, since it’s the serialized versions of nodes and blocks that are hashed.

class hippiepug.pack.EncodingParams(encoder=NOTHING, decoder=NOTHING)

Thread-local container for default encoder and decoder funcs.

Parameters:
  • encoder – Default encoder
  • decoder – Default decoder

This is how you can override the defaults using this class:

>>> my_params = EncodingParams()
>>> my_params.encoder = lambda obj: b'encoded!'
>>> my_params.decoder = lambda encoded: b'decoded!'
>>> EncodingParams.set_global_default(my_params)
>>> encode(b'dummy') == b'encoded!'
True
>>> decode(b'encoded!') == b'decoded!'
True
>>> EncodingParams.reset_defaults()
hippiepug.pack.decode(serialized, decoder=None)

Deserialize object.

Parameters:
  • serialized – Encoded structure
  • encoder – Custom de-serializer
hippiepug.pack.encode(obj, encoder=None)

Serialize object.

Parameters:
  • obj – Chain block, tree node, or bytes
  • encoder – Custom serializer
hippiepug.pack.msgpack_decoder(serialized_obj)

Deserialize structure from msgpack-encoded tuple.

Default decoder.

hippiepug.pack.msgpack_encoder(obj)

Represent structure as tuple and serialize using msgpack.

Default encoder.