Skip to content

Commit

Permalink
Refactor ffi block iterator for general use
Browse files Browse the repository at this point in the history
Move this code to the Python FFI module and make it more general purpose.

Signed-off-by: Adam Ludvik <ludvik@bitwise.io>
  • Loading branch information
Adam Ludvik committed Oct 1, 2018
1 parent 7a6e6f5 commit 240e4a9
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 46 deletions.
36 changes: 36 additions & 0 deletions validator/sawtooth_validator/ffi.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@
import os
import sys

from sawtooth_validator.protobuf.block_pb2 import Block


LOGGER = logging.getLogger(__name__)

Expand Down Expand Up @@ -185,3 +187,37 @@ def callback_wrapper(*args):
return sender.send(*args)

return callback_wrapper


class BlockIterator(OwnedPointer):

def __init__(self, check_return_code, initialized_ptr=None):
super().__init__("{}_drop".format(self.name), initialized_ptr)
self._check_return_code = check_return_code

def __iter__(self):
return self

def __next__(self):
if not self.pointer:
raise StopIteration()

(vec_ptr, vec_len, vec_cap) = prepare_vec_result()

self._check_return_code(
LIBRARY.call(
"{}_next".format(self.name),
self.pointer,
ctypes.byref(vec_ptr),
ctypes.byref(vec_len),
ctypes.byref(vec_cap)))

# Check if NULL
if not vec_ptr:
raise StopIteration()

payload = from_rust_vec(vec_ptr, vec_len, vec_cap)
block = Block()
block.ParseFromString(payload)

return block
59 changes: 13 additions & 46 deletions validator/sawtooth_validator/journal/block_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@
from enum import IntEnum

from sawtooth_validator.ffi import OwnedPointer
from sawtooth_validator.protobuf.block_pb2 import Block
from sawtooth_validator import ffi


Expand Down Expand Up @@ -134,7 +133,10 @@ def _pylibexec(name, *args):


def _exec(library, name, *args):
res = library.call(name, *args)
_check_error(library.call(name, *args))


def _check_error(res):
if res == ErrorCode.Success:
return

Expand All @@ -156,86 +158,51 @@ def _exec(library, name, *args):
raise Exception("There was an unknown error: {}".format(res))


class _BlockIterator:

def __del__(self):
if self._c_iter_ptr:
_libexec("{}_drop".format(self.name), self._c_iter_ptr)

def __iter__(self):
return self

def __next__(self):
if not self._c_iter_ptr:
raise StopIteration()

(vec_ptr, vec_len, vec_cap) = ffi.prepare_vec_result()

_libexec("{}_next".format(self.name),
self._c_iter_ptr,
ctypes.byref(vec_ptr),
ctypes.byref(vec_len),
ctypes.byref(vec_cap))

# Check if NULL
if not vec_ptr:
raise StopIteration()

payload = ffi.from_rust_vec(vec_ptr, vec_len, vec_cap)
block = Block()
block.ParseFromString(payload)

return block


class _GetBlockIterator(_BlockIterator):
class _GetBlockIterator(ffi.BlockIterator):

name = "block_manager_get_iterator"

def __init__(self, block_manager_ptr, block_ids):
super().__init__(_check_error)

c_block_ids = (ctypes.c_char_p * len(block_ids))()
for i, block_id in enumerate(block_ids):
c_block_ids[i] = ctypes.c_char_p(block_id.encode())

self._c_iter_ptr = ctypes.c_void_p()

_libexec("{}_new".format(self.name),
block_manager_ptr,
c_block_ids,
ctypes.c_size_t(len(block_ids)),
ctypes.byref(self._c_iter_ptr))
ctypes.byref(self.pointer))


class _BranchDiffIterator(_BlockIterator):
class _BranchDiffIterator(ffi.BlockIterator):

name = "block_manager_branch_diff_iterator"

def __init__(self, block_manager_ptr, tip, exclude):
super().__init__(_check_error)

c_tip = ctypes.c_char_p(tip.encode())
c_exclude = ctypes.c_char_p(exclude.encode())

self._c_iter_ptr = ctypes.c_void_p()

_libexec("{}_new".format(self.name),
block_manager_ptr,
c_tip,
c_exclude,
ctypes.byref(self._c_iter_ptr))
ctypes.byref(self.pointer))


class _BranchIterator(_BlockIterator):
class _BranchIterator(ffi.BlockIterator):

name = "block_manager_branch_iterator"

def __init__(self, block_manager_ptr, tip):
super().__init__(_check_error)

c_tip = ctypes.c_char_p(tip.encode())

self._c_iter_ptr = ctypes.c_void_p()

_libexec("{}_new".format(self.name),
block_manager_ptr,
c_tip,
ctypes.byref(self._c_iter_ptr))
ctypes.byref(self.pointer))

0 comments on commit 240e4a9

Please sign in to comment.