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());
}
}