diff --git a/cic/attachment.py b/cic/attachment.py index 434038f..bc41ceb 100644 --- a/cic/attachment.py +++ b/cic/attachment.py @@ -1,6 +1,5 @@ # standard imports import os -import hashlib import logging # local imports @@ -13,17 +12,9 @@ class Attachment(Data): def __init__(self, path='.'): super(Attachment, self).__init__() - self.contents = [] - self.digests = [] + self.contents = {} self.path = path self.attachment_path = os.path.join(self.path, 'attachments') - self.__hasher = self.__basehasher - - - def __basehasher(self, v): - h = hashlib.sha256() - h.update(v) - return h.digest() def load(self): @@ -32,24 +23,24 @@ class Attachment(Data): f = open(fp, 'rb') r = f.read() f.close() - self.contents.append(fp) - z = self.__hasher(r) - self.digests.append(z) + z = self.hash(r).hex() + self.contents[z] = fp - logg.debug('loaded attachment file {} digest {}'.format(fp, z.hex())) + logg.debug('loaded attachment file {} digest {}'.format(fp, z)) def start(self): super(Attachment, self).start() - os.makedirs(self.attachment_path) - def get(self): - def maphex(v): - return v.hex() - return list(map(maphex, self.digests)) + def get(self, k): + return self.contents[k] + + + def asdict(self): + return self.contents def __str__(self): diff --git a/cic/base.py b/cic/base.py index 5c8b752..d5d5c81 100644 --- a/cic/base.py +++ b/cic/base.py @@ -1,5 +1,6 @@ # standard imports import os +import hashlib mod_dir = os.path.dirname(os.path.realpath(__file__)) @@ -17,6 +18,17 @@ class Data: self.dirty = False self.inited = False self.__version = self.__default_version + self.__hasher = self.__basehasher + + + def __basehasher(self, v): + h = hashlib.sha256() + h.update(v) + return h.digest() + + + def hash(self, v): + return self.__hasher(v) def load(self): diff --git a/cic/cmd/export.py b/cic/cmd/export.py index 61ea0fd..c4ff411 100644 --- a/cic/cmd/export.py +++ b/cic/cmd/export.py @@ -27,9 +27,9 @@ def execute(config, eargs): cmd_mod = importlib.import_module(modname) ct = Token(path=eargs.directory) - cp = Proof(path=eargs.directory) cm = Meta(path=eargs.directory) ca = Attachment(path=eargs.directory) + cp = Proof(path=eargs.directory, attachments=ca) cn = Network(path=eargs.directory) ct.load() @@ -40,4 +40,4 @@ def execute(config, eargs): ref = cn.reference(eargs.target) logg.debug('found reference {} for target {}'.format(ref, eargs.target)) - getattr(cmd_mod, 'new')(ref, ca.get(), signer_hint=eargs.signer) + getattr(cmd_mod, 'new')(ref, cp, signer_hint=eargs.signer) diff --git a/cic/ext/eth/__init__.py b/cic/ext/eth/__init__.py index 4980803..5c07be0 100644 --- a/cic/ext/eth/__init__.py +++ b/cic/ext/eth/__init__.py @@ -22,11 +22,11 @@ logg = logging.getLogger(__name__) class CICEth: - def __init__(self, chain_spec, resources, proofs, signer=None, rpc=None, nonce_oracle=None, fee_oracle=None): + def __init__(self, chain_spec, resources, proof, signer=None, rpc=None, nonce_oracle=None, fee_oracle=None): """resources will be modified """ self.resources = resources - self.proofs = proofs + self.proof = proof self.chain_spec = chain_spec self.signer = signer self.rpc = rpc @@ -170,7 +170,7 @@ class CICEth: signer_address = self.resources['address_declarator']['key_address'] r = [] - for proof in self.proofs: + for proof in self.proof.get(): o = c.add_declaration(contract_address, signer_address, self.token_address, proof, tx_format=self.tx_format) if self.rpc != None: r.append(self.rpc.do(o[1])) @@ -198,5 +198,5 @@ class CICEth: getattr(self, 'process_̈́ ' + task)() -def new(resources, proofs, signer_hint=None): - return CICEth(resources, proofs, signer=None) +def new(resources, proof, signer_hint=None): + return CICEth(resources, proof, signer=None) diff --git a/cic/proof.py b/cic/proof.py index 56b4346..ca6d3cf 100644 --- a/cic/proof.py +++ b/cic/proof.py @@ -2,6 +2,11 @@ import os import json import logging +import tempfile +import cbor2 + +# external imports +from hexathon import strip_0x # local imports from .base import * @@ -11,12 +16,15 @@ logg = logging.getLogger(__name__) class Proof(Data): - def __init__(self, path='.'): + def __init__(self, path='.', attachments=None): super(Proof, self).__init__() self.namespace = 'ge' self.description = None self.path = path + self.extra_attachments = attachments + self.attachments = {} self.proof_path = os.path.join(self.path, 'proof.json') + self.temp_proof_path = tempfile.mkstemp()[1] def load(self): @@ -46,6 +54,42 @@ class Proof(Data): json.dump(o, f) f.close() - + + def asdict(self): + return { + 'version': self.version(), + 'namespace': self.namespace, + 'description': self.description, + } + + + def __get_ordered_hashes(self): + ks = list(self.attachments.keys()) + ks.sort() + + return ks + + + def get(self): + v = self.asdict() + b = cbor2.dumps(v) + + f = open(self.temp_proof_path, 'wb') + f.write(b) + f.close() + + hsh = self.hash(b).hex() + self.attachments[hsh] = self.temp_proof_path + + if self.extra_attachments != None: + a = self.extra_attachments.asdict() + for k in a.keys(): + self.attachments[k] = a[k] + + hshs = self.__get_ordered_hashes() + + return hshs + + def __str__(self): return "description = {}\n".format(self.description) diff --git a/tests/eth/base_eth.py b/tests/eth/base_eth.py index 0698f89..55c401a 100644 --- a/tests/eth/base_eth.py +++ b/tests/eth/base_eth.py @@ -1,7 +1,7 @@ -# standard imports -import unittest -import logging +# standard imports import unittestimport logging import random +import os +import logging # external imports from chainlib.chain import ChainSpec @@ -14,6 +14,11 @@ from funga.eth.keystore.dict import DictKeystore # local imports from cic.ext.eth import CICEth +from cic import Proof +from cic.attachment import Attachment + +# test imports +from tests.base_cic import test_data_dir logg = logging.getLogger(__name__) @@ -40,6 +45,8 @@ class TestCICEthBase(EthTesterCase): 'key_address': addresses[2], }, } - self.proofs = [] - for i in range(3): - self.proofs.append(random.randbytes(32).hex()) + proof_dir = os.path.join(test_data_dir, 'proof') + attach = Attachment(path=proof_dir) + attach.load() + self.proofs = Proof(proof_dir, attachments=attach) + self.proofs.load() diff --git a/tests/testdata/proof/proof.json b/tests/testdata/proof/proof.json new file mode 100644 index 0000000..f290d0f --- /dev/null +++ b/tests/testdata/proof/proof.json @@ -0,0 +1,5 @@ +{ + "version": 0, + "namespace": "ge", + "description": "foo bar baz" +}