mirror of
https://github.com/bigchaindb/bigchaindb.git
synced 2024-10-13 13:34:05 +00:00
Compliance to legacy BDB models
This commit is contained in:
parent
45a946fc24
commit
b2b0f56e40
@ -2,6 +2,10 @@
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
class ConfigurationError(Exception):
|
||||||
|
"""Raised when there is a problem with server configuration"""
|
||||||
|
|
||||||
|
|
||||||
class OperationError(Exception):
|
class OperationError(Exception):
|
||||||
"""Raised when an operation cannot go through"""
|
"""Raised when an operation cannot go through"""
|
||||||
|
|
||||||
|
@ -103,24 +103,30 @@ class TransactionLink(object):
|
|||||||
# NOTE: In an IPLD implementation, this class is not necessary anymore, as an IPLD link can simply point to an
|
# NOTE: In an IPLD implementation, this class is not necessary anymore, as an IPLD link can simply point to an
|
||||||
# object, as well as an objects properties. So instead of having a (de)serializable class, we can have a
|
# object, as well as an objects properties. So instead of having a (de)serializable class, we can have a
|
||||||
# simple IPLD link of the form: `/<tx_id>/transaction/conditions/<cid>/`
|
# simple IPLD link of the form: `/<tx_id>/transaction/conditions/<cid>/`
|
||||||
def __init__(self, transaction_id=None, condition_id=None):
|
def __init__(self, txid=None, cid=None):
|
||||||
self.transaction_id = transaction_id
|
self.txid = txid
|
||||||
self.condition_id = condition_id
|
self.cid = cid
|
||||||
|
|
||||||
|
def is_defined(self):
|
||||||
|
if self.txid is None and self.cid is None:
|
||||||
|
return False
|
||||||
|
else:
|
||||||
|
return True
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def from_dict(cls, link):
|
def from_dict(cls, link):
|
||||||
try:
|
try:
|
||||||
return cls(link['transaction_id'], link['condition_id'])
|
return cls(link['txid'], link['cid'])
|
||||||
except TypeError:
|
except TypeError:
|
||||||
return cls()
|
return cls()
|
||||||
|
|
||||||
def to_dict(self):
|
def to_dict(self):
|
||||||
if self.transaction_id is None and self.condition_id is None:
|
if self.txid is None and self.cid is None:
|
||||||
return None
|
return None
|
||||||
else:
|
else:
|
||||||
return {
|
return {
|
||||||
'transaction_id': self.transaction_id,
|
'txid': self.txid,
|
||||||
'condition_id': self.condition_id,
|
'cid': self.cid,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -166,7 +172,7 @@ class Data(object):
|
|||||||
@classmethod
|
@classmethod
|
||||||
def from_dict(cls, payload):
|
def from_dict(cls, payload):
|
||||||
try:
|
try:
|
||||||
return cls(payload['payload'], payload['hash'])
|
return cls(payload['payload'], payload['uuid'])
|
||||||
except TypeError:
|
except TypeError:
|
||||||
return cls()
|
return cls()
|
||||||
|
|
||||||
@ -176,16 +182,18 @@ class Data(object):
|
|||||||
else:
|
else:
|
||||||
return {
|
return {
|
||||||
'payload': self.payload,
|
'payload': self.payload,
|
||||||
'hash': str(self.payload_id),
|
'uuid': self.payload_id,
|
||||||
}
|
}
|
||||||
|
|
||||||
def to_hash(self):
|
def to_hash(self):
|
||||||
return uuid4()
|
return str(uuid4())
|
||||||
|
|
||||||
|
|
||||||
class Transaction(object):
|
class Transaction(object):
|
||||||
CREATE = 'CREATE'
|
CREATE = 'CREATE'
|
||||||
TRANSFER = 'TRANSFER'
|
TRANSFER = 'TRANSFER'
|
||||||
|
GENESIS = 'GENESIS'
|
||||||
|
ALLOWED_OPERATIONS = (CREATE, TRANSFER, GENESIS)
|
||||||
VERSION = 1
|
VERSION = 1
|
||||||
|
|
||||||
def __init__(self, operation, fulfillments=None, conditions=None, data=None, timestamp=None, version=None):
|
def __init__(self, operation, fulfillments=None, conditions=None, data=None, timestamp=None, version=None):
|
||||||
@ -233,7 +241,7 @@ class Transaction(object):
|
|||||||
self.timestamp = timestamp if timestamp is not None else gen_timestamp()
|
self.timestamp = timestamp if timestamp is not None else gen_timestamp()
|
||||||
self.version = version if version is not None else Transaction.VERSION
|
self.version = version if version is not None else Transaction.VERSION
|
||||||
|
|
||||||
if operation is not Transaction.CREATE and operation is not Transaction.TRANSFER:
|
if operation not in Transaction.ALLOWED_OPERATIONS:
|
||||||
raise TypeError('`operation` must be either CREATE or TRANSFER')
|
raise TypeError('`operation` must be either CREATE or TRANSFER')
|
||||||
else:
|
else:
|
||||||
self.operation = operation
|
self.operation = operation
|
||||||
@ -257,6 +265,31 @@ class Transaction(object):
|
|||||||
else:
|
else:
|
||||||
self.data = data
|
self.data = data
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def create(cls, owners_before, owners_after, inputs, operation, payload=None):
|
||||||
|
if operation == Transaction.CREATE or operation == Transaction.GENESIS:
|
||||||
|
ffill = Fulfillment.gen_default(owners_after)
|
||||||
|
cond = ffill.gen_condition()
|
||||||
|
return cls(operation, [ffill], [cond], Data(payload))
|
||||||
|
else:
|
||||||
|
# TODO: Replace this with an actual implementation, maybe calling
|
||||||
|
# `self.transfer` is sufficient already :)
|
||||||
|
raise NotImplementedError()
|
||||||
|
|
||||||
|
def transfer(self, conditions):
|
||||||
|
# TODO: Check here if a condition is submitted or smth else
|
||||||
|
return Transaction(Transaction.TRANSFER, self._fulfillments_as_inputs(), conditions)
|
||||||
|
|
||||||
|
def simple_transfer(self, owners_after):
|
||||||
|
condition = Fulfillment.gen_default(owners_after).gen_condition()
|
||||||
|
return self.transfer([condition])
|
||||||
|
|
||||||
|
def _fulfillments_as_inputs(self):
|
||||||
|
return [Fulfillment(ffill.fulfillment,
|
||||||
|
ffill.owners_before,
|
||||||
|
TransactionLink(self.to_hash(), fulfillment_id))
|
||||||
|
for fulfillment_id, ffill in enumerate(self.fulfillments)]
|
||||||
|
|
||||||
def add_fulfillment(self, fulfillment):
|
def add_fulfillment(self, fulfillment):
|
||||||
if fulfillment is not None and not isinstance(fulfillment, Fulfillment):
|
if fulfillment is not None and not isinstance(fulfillment, Fulfillment):
|
||||||
raise TypeError('`fulfillment` must be a Fulfillment instance or None')
|
raise TypeError('`fulfillment` must be a Fulfillment instance or None')
|
||||||
@ -396,7 +429,7 @@ class Transaction(object):
|
|||||||
else:
|
else:
|
||||||
return tx.fulfillments_valid()
|
return tx.fulfillments_valid()
|
||||||
|
|
||||||
if self.operation is Transaction.CREATE:
|
if self.operation in (Transaction.CREATE, Transaction.GENESIS):
|
||||||
if not fulfillments_count == conditions_count:
|
if not fulfillments_count == conditions_count:
|
||||||
raise ValueError('Fulfillments, conditions must have the same count')
|
raise ValueError('Fulfillments, conditions must have the same count')
|
||||||
elif fulfillments_count > 1 and conditions_count > 1:
|
elif fulfillments_count > 1 and conditions_count > 1:
|
||||||
@ -411,7 +444,7 @@ class Transaction(object):
|
|||||||
else:
|
else:
|
||||||
return self._fulfillment_valid(input_condition_uris.pop())
|
return self._fulfillment_valid(input_condition_uris.pop())
|
||||||
else:
|
else:
|
||||||
raise TypeError('`operation` must be either `Transaction.TRANSFER` or `Transaction.CREATE`')
|
raise TypeError('`operation` must be either `TRANSFER`, `CREATE` or `GENESIS`')
|
||||||
|
|
||||||
def _fulfillment_valid(self, input_condition_uri=None):
|
def _fulfillment_valid(self, input_condition_uri=None):
|
||||||
# NOTE: We're always taking the first fulfillment, as this method is called recursively.
|
# NOTE: We're always taking the first fulfillment, as this method is called recursively.
|
||||||
@ -435,15 +468,6 @@ class Transaction(object):
|
|||||||
# it.
|
# it.
|
||||||
return parsed_fulfillment.validate(message=tx_serialized, now=gen_timestamp()) and input_condition_valid
|
return parsed_fulfillment.validate(message=tx_serialized, now=gen_timestamp()) and input_condition_valid
|
||||||
|
|
||||||
def transfer(self, conditions):
|
|
||||||
return Transaction(Transaction.TRANSFER, self._fulfillments_as_inputs(), conditions)
|
|
||||||
|
|
||||||
def _fulfillments_as_inputs(self):
|
|
||||||
return [Fulfillment(ffill.fulfillment,
|
|
||||||
ffill.owners_before,
|
|
||||||
TransactionLink(self.to_hash(), fulfillment_id))
|
|
||||||
for fulfillment_id, ffill in enumerate(self.fulfillments)]
|
|
||||||
|
|
||||||
def to_dict(self):
|
def to_dict(self):
|
||||||
try:
|
try:
|
||||||
data = self.data.to_dict()
|
data = self.data.to_dict()
|
||||||
@ -490,6 +514,10 @@ class Transaction(object):
|
|||||||
def _to_hash(value):
|
def _to_hash(value):
|
||||||
return hash_data(value)
|
return hash_data(value)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def id(self):
|
||||||
|
return self.to_hash()
|
||||||
|
|
||||||
def to_hash(self):
|
def to_hash(self):
|
||||||
return self.to_dict()['id']
|
return self.to_dict()['id']
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user