Search in sources :

Example 1 with MapDelta

use of net.sergeych.diff.MapDelta in project universa by UniversaBlockchain.

the class ContractDelta method check.

// todo: need to test this synchronized attribute, should not affects overall node's concurrency
public synchronized void check() throws Quantiser.QuantiserException {
    try {
        BiMapper mapper = BossBiMapper.getInstance();
        MapDelta rootDelta = Delta.between(mapper.serialize(existing), mapper.serialize(changed));
        MapDelta definitionDelta = (MapDelta) rootDelta.getChange("definition");
        stateDelta = (MapDelta) rootDelta.getChange("state");
        if (definitionDelta != null) {
            addError(ILLEGAL_CHANGE, "definition", "definition must not be changed");
        }
        // check immutable root area
        // should be only one change here: state
        int allowedRootChanges = 1;
        Delta ch = rootDelta.getChange("api_level");
        if (ch != null) {
            allowedRootChanges++;
        }
        // or can be changed section "transactional"
        Delta transactionalDelta = rootDelta.getChange("transactional");
        if (transactionalDelta != null) {
            allowedRootChanges++;
        }
        if (rootDelta.getChanges().size() > allowedRootChanges)
            addError(ILLEGAL_CHANGE, "root", "root level changes are forbidden except the state");
        // check only permitted changes in data
        checkStateChange();
    } catch (ClassCastException e) {
        e.printStackTrace();
        addError(FAILED_CHECK, "", "failed to compare, structure is broken or not supported");
    }
}
Also used : BossBiMapper(net.sergeych.biserializer.BossBiMapper) BiMapper(net.sergeych.biserializer.BiMapper) Delta(net.sergeych.diff.Delta) MapDelta(net.sergeych.diff.MapDelta) MapDelta(net.sergeych.diff.MapDelta)

Example 2 with MapDelta

use of net.sergeych.diff.MapDelta in project universa by UniversaBlockchain.

the class ChangeNumberPermission method checkChanges.

/**
 * Check and remove changes that this permission allow. Note that it does not add errors itself,
 * to allow using several such permission, from which some may allow the change, and some may not. If a check
 * will add error, though, it will prevent subsequent permission objects to allow the change.
 *  @param contract     source (valid) contract
 * @param changed is contract for checking
 * @param stateChanges map of changes, see {@link Delta} for details
 */
@Override
public void checkChanges(Contract contract, Contract changed, Map<String, Delta> stateChanges) {
    MapDelta<String, Binder, Binder> dataChanges = (MapDelta<String, Binder, Binder>) stateChanges.get("data");
    if (dataChanges == null)
        return;
    Delta delta = dataChanges.getChange(fieldName);
    if (delta != null) {
        if (!(delta instanceof ChangedItem))
            return;
        try {
            int valueDelta = (int) delta.newValue() - (int) delta.oldValue();
            if (valueDelta < minStep || valueDelta > maxStep)
                return;
            else {
                newValue = (int) delta.newValue();
                if (newValue > maxValue || newValue < minValue)
                    return;
                else {
                    dataChanges.remove(fieldName);
                }
            }
        } catch (Exception e) {
            return;
        }
    }
}
Also used : Binder(net.sergeych.tools.Binder) Delta(net.sergeych.diff.Delta) MapDelta(net.sergeych.diff.MapDelta) ChangedItem(net.sergeych.diff.ChangedItem) MapDelta(net.sergeych.diff.MapDelta)

Example 3 with MapDelta

use of net.sergeych.diff.MapDelta in project universa by UniversaBlockchain.

the class ModifyDataPermission method checkChanges.

/**
 * checkChanges processes the map of changes with the list of fields with predefined data options for a role.
 *
 * @param contract     source (valid) contract
 * @param changedContract is contract for checking
 * @param stateChanges map of changes, see {@link Delta} for details
 */
@Override
public void checkChanges(Contract contract, Contract changedContract, Map<String, Delta> stateChanges) {
    Delta data = stateChanges.get("data");
    if (data != null && data instanceof MapDelta) {
        Map mapChanges = ((MapDelta) data).getChanges();
        mapChanges.keySet().removeIf(key -> {
            Object changed = mapChanges.get(key);
            Object value = "";
            if (changed != null && changed instanceof ChangedItem) {
                value = ((ChangedItem) mapChanges.get(key)).newValue();
            }
            boolean containsField = this.fields.containsKey(key);
            List<String> foundField = this.fields.get(key);
            return (containsField && foundField == null) || (foundField != null && foundField.contains(value) || isEmptyOrNull(foundField, value));
        });
    }
}
Also used : Delta(net.sergeych.diff.Delta) MapDelta(net.sergeych.diff.MapDelta) ChangedItem(net.sergeych.diff.ChangedItem) MapDelta(net.sergeych.diff.MapDelta)

Example 4 with MapDelta

use of net.sergeych.diff.MapDelta in project universa by UniversaBlockchain.

the class SplitJoinPermission method checkChanges.

/**
 * Check and remove changes that this permission allow. Note that it does not add errors itself, to allow using
 * several such permission, from which some may allow the change, and some may not. If a check will add error,
 * though, it will prevent subsequent permission objects to allow the change.
 *
 * @param contract     source (valid) contract
 * @param changed is contract for checking
 * @param stateChanges map of changes, see {@link Delta} for details
 */
@Override
public void checkChanges(Contract contract, Contract changed, Map<String, Delta> stateChanges) {
    MapDelta<String, Binder, Binder> dataChanges = (MapDelta<String, Binder, Binder>) stateChanges.get("data");
    if (dataChanges == null)
        return;
    Delta delta = dataChanges.getChange(fieldName);
    if (delta != null) {
        if (!(delta instanceof ChangedItem))
            return;
        try {
            Decimal oldValue = new Decimal(delta.oldValue().toString());
            Decimal newValue = new Decimal(delta.newValue().toString());
            int cmp = oldValue.compareTo(newValue);
            if (cmp > 0)
                checkSplit(changed, dataChanges, oldValue, newValue);
            else if (cmp < 0)
                checkMerge(changed, dataChanges, newValue);
        } catch (Exception e) {
            e.printStackTrace();
            return;
        }
    }
}
Also used : Binder(net.sergeych.tools.Binder) Decimal(com.icodici.universa.Decimal) Delta(net.sergeych.diff.Delta) MapDelta(net.sergeych.diff.MapDelta) ChangedItem(net.sergeych.diff.ChangedItem) MapDelta(net.sergeych.diff.MapDelta)

Example 5 with MapDelta

use of net.sergeych.diff.MapDelta in project universa by UniversaBlockchain.

the class ContractDelta method checkStateChange.

private void checkStateChange() throws Quantiser.QuantiserException {
    stateChanges = stateDelta.getChanges();
    stateChanges.remove("created_by");
    // todo: check siblings have different and proper branch ids
    stateChanges.remove("branch_id");
    // todo: these changes should be already checked
    stateChanges.remove("parent");
    stateChanges.remove("origin");
    if (insignificantKeys.containsAll(stateChanges.keySet())) {
        addError(BADSTATE, "", "new state is identical");
    }
    Role creator = changed.getRole("creator");
    if (creator == null) {
        addError(MISSING_CREATOR, "state.created_by", "");
        return;
    }
    ChangedItem<Integer, Integer> revision = (ChangedItem) stateChanges.get("revision");
    if (revision == null)
        addError(BAD_VALUE, "state.revision", "is not incremented");
    else {
        stateChanges.remove("revision");
        if (revision.oldValue() + 1 != revision.newValue())
            addError(BAD_VALUE, "state.revision", "wrong revision number");
    }
    Delta creationTimeChange = stateChanges.get("created_at");
    // if time is changed, it must be past:
    if (creationTimeChange != null) {
        stateChanges.remove("created_at");
        ChangedItem<ZonedDateTime, ZonedDateTime> ci = (ChangedItem) creationTimeChange;
        if (!ci.newValue().isAfter(ci.oldValue()))
            addError(BAD_VALUE, "state.created_at", "new creation datetime is before old one");
    }
    excludePermittedChanges();
    // Some changes coud be empty trees, cleared by permissions, which can not remove root
    // entries, so we should check them all:
    stateChanges.forEach((field, delta) -> {
        if (!delta.isEmpty()) {
            String reason = "";
            if (delta instanceof MapDelta)
                reason = " in " + ((MapDelta) delta).getChanges().keySet();
            addError(FORBIDDEN, "state." + field, "not permitted changes" + reason + ": " + delta.oldValue() + " -> " + delta.newValue());
        }
    });
}
Also used : Role(com.icodici.universa.contract.roles.Role) Delta(net.sergeych.diff.Delta) MapDelta(net.sergeych.diff.MapDelta) ZonedDateTime(java.time.ZonedDateTime) ChangedItem(net.sergeych.diff.ChangedItem) MapDelta(net.sergeych.diff.MapDelta)

Aggregations

Delta (net.sergeych.diff.Delta)5 MapDelta (net.sergeych.diff.MapDelta)5 ChangedItem (net.sergeych.diff.ChangedItem)4 Binder (net.sergeych.tools.Binder)2 Decimal (com.icodici.universa.Decimal)1 Role (com.icodici.universa.contract.roles.Role)1 ZonedDateTime (java.time.ZonedDateTime)1 BiMapper (net.sergeych.biserializer.BiMapper)1 BossBiMapper (net.sergeych.biserializer.BossBiMapper)1