Search in sources :

Example 1 with Quantiser

use of com.icodici.universa.node2.Quantiser in project universa by UniversaBlockchain.

the class TransactionPack method deserialize.

@Override
public void deserialize(Binder data, BiDeserializer deserializer) throws IOException {
    synchronized (this) {
        // It is local quantiser that should throw exception
        // if limit is got while deserializing TransactionPack.
        Quantiser quantiser = new Quantiser();
        quantiser.reset(Contract.getTestQuantaLimit());
        List<Object> keysList = deserializer.deserializeCollection(data.getList("keys", new ArrayList<>()));
        keysForPack = new HashSet<>();
        if (keysList != null) {
            for (Object x : keysList) {
                if (x instanceof Bytes)
                    x = ((Bytes) x).toArray();
                if (x instanceof byte[]) {
                    keysForPack.add(new PublicKey((byte[]) x));
                } else {
                    throw new IllegalArgumentException("unsupported key object: " + x.getClass().getName());
                }
            }
        }
        List<Bytes> foreignReferenceBytesList = deserializer.deserializeCollection(data.getList("referencedItems", new ArrayList<>()));
        if (foreignReferenceBytesList != null) {
            for (Bytes b : foreignReferenceBytesList) {
                Contract frc = new Contract(b.toArray(), this);
                quantiser.addWorkCostFrom(frc.getQuantiser());
                referencedItems.put(frc.getId(), frc);
            }
        }
        List<Bytes> subItemsBytesList = deserializer.deserializeCollection(data.getListOrThrow("subItems"));
        HashMap<ContractDependencies, Bytes> allContractsTrees = new HashMap<>();
        List<HashId> allContractsHids = new ArrayList<>();
        ArrayList<Bytes> sortedSubItemsBytesList = new ArrayList<>();
        if (subItemsBytesList != null) {
            // First of all extract contracts dependencies from subItems
            for (Bytes b : subItemsBytesList) {
                ContractDependencies ct = new ContractDependencies(b.toArray());
                allContractsTrees.put(ct, b);
                allContractsHids.add(ct.id);
            }
            // and add items to subItems on the each level of tree's hierarchy
            do {
                // first add contract from ends of trees, means without own subitems
                sortedSubItemsBytesList = new ArrayList<>();
                List<ContractDependencies> removingContractDependencies = new ArrayList<>();
                for (ContractDependencies ct : allContractsTrees.keySet()) {
                    if (ct.dependencies.size() == 0) {
                        sortedSubItemsBytesList.add(allContractsTrees.get(ct));
                        removingContractDependencies.add(ct);
                    }
                }
                // remove found items from tree's list
                for (ContractDependencies ct : removingContractDependencies) {
                    allContractsTrees.remove(ct);
                }
                // then add contract with already exist subitems in the subItems or will never find in the tree
                removingContractDependencies = new ArrayList<>();
                for (ContractDependencies ct : allContractsTrees.keySet()) {
                    boolean allDependenciesSafe = true;
                    for (HashId hid : ct.dependencies) {
                        if (!subItems.containsKey(hid) && allContractsHids.contains(hid)) {
                            allDependenciesSafe = false;
                        }
                    }
                    if (allDependenciesSafe) {
                        sortedSubItemsBytesList.add(allContractsTrees.get(ct));
                        removingContractDependencies.add(ct);
                    }
                }
                // remove found items from tree's list
                for (ContractDependencies ct : removingContractDependencies) {
                    allContractsTrees.remove(ct);
                }
                // add found binaries on the hierarchy level to subItems
                for (int i = 0; i < sortedSubItemsBytesList.size(); i++) {
                    Contract c = new Contract(sortedSubItemsBytesList.get(i).toArray(), this);
                    quantiser.addWorkCostFrom(c.getQuantiser());
                    subItems.put(c.getId(), c);
                }
            // then repeat until we can find hierarchy
            } while (sortedSubItemsBytesList.size() != 0);
            // finally add not found binaries on the hierarchy levels to subItems
            for (Bytes b : allContractsTrees.values()) {
                Contract c = new Contract(b.toArray(), this);
                quantiser.addWorkCostFrom(c.getQuantiser());
                subItems.put(c.getId(), c);
            }
        }
        byte[] bb = data.getBinaryOrThrow("contract");
        contract = new Contract(bb, this);
        quantiser.addWorkCostFrom(contract.getQuantiser());
    }
}
Also used : HashId(com.icodici.universa.HashId) PublicKey(com.icodici.crypto.PublicKey) Quantiser(com.icodici.universa.node2.Quantiser) Bytes(net.sergeych.utils.Bytes)

Aggregations

PublicKey (com.icodici.crypto.PublicKey)1 HashId (com.icodici.universa.HashId)1 Quantiser (com.icodici.universa.node2.Quantiser)1 Bytes (net.sergeych.utils.Bytes)1