use of com.icodici.universa.contract.Contract in project universa by UniversaBlockchain.
the class SplitJoinPermission method checkMerge.
private void checkMerge(Contract changed, MapDelta<String, Binder, Binder> dataChanges, Decimal newValue) {
boolean isValid;
// merge means there are mergeable contracts in the revoking items
Decimal sum = Decimal.ZERO;
for (Approvable a : changed.getRevokingItems()) {
if (a instanceof Contract) {
Contract c = (Contract) a;
if (!isMergeable(c) || !validateMergeFields(changed, c))
return;
sum = sum.add(new Decimal(getFieldName(c)));
}
}
isValid = sum.compareTo(newValue) == 0;
if (!isValid)
isValid = checkSplitJoinCase(changed);
if (isValid)
dataChanges.remove(fieldName);
}
use of com.icodici.universa.contract.Contract in project universa by UniversaBlockchain.
the class Wallet method joinAndRemoveFromContracts.
private Contract joinAndRemoveFromContracts(List<Contract> selectedContracts) throws Exception {
Contract result = selectedContracts.get(0).copy();
result.getRevokingItems().addAll(selectedContracts);
this.contracts.removeAll(selectedContracts);
result.setKeysToSignWith(selectedContracts.get(0).getKeysToSignWith());
return result;
}
use of com.icodici.universa.contract.Contract in project universa by UniversaBlockchain.
the class Wallet method determineWallets.
public static List<Wallet> determineWallets(List<Contract> contracts) {
Map<Object, Wallet> wallets = new HashMap<>();
for (Contract contract : contracts) {
if (contract.getPermissions() == null)
continue;
Collection<Permission> splitJoinCollection = contract.getPermissions().get("split_join");
if (splitJoinCollection == null || splitJoinCollection.size() == 0)
continue;
Object split_join = splitJoinCollection.toArray()[0];
if (!(split_join instanceof SplitJoinPermission))
continue;
Object join_match_fields = ((SplitJoinPermission) split_join).getParams().get("join_match_fields");
Object field;
if (join_match_fields instanceof List)
field = ((List) join_match_fields).get(0);
else
field = join_match_fields;
Wallet wallet = wallets.get(field);
if (wallet == null) {
wallet = new Wallet();
}
wallet.addContract(contract);
wallets.put(field, wallet);
}
return new ArrayList<>(wallets.values());
}
use of com.icodici.universa.contract.Contract in project universa by UniversaBlockchain.
the class Wallet method buildContractWithValue.
/**
* Join this contract with other (split when the sum of contracts is greater) or
* split the current one to have the input value in the one contract.
*
* @param fieldName is name of field for split or join
* @param value is value to have in a one contract
* @return built {@link Contract}
* @throws Exception if something went wrong
*/
public synchronized Contract buildContractWithValue(String fieldName, @NonNull Decimal value) throws Exception {
if (value == null || Decimal.ZERO.equals(value) || this.contracts.size() == 0)
return null;
Contract result = null;
// sort here because someone could add a new contract to the list at any time
this.contracts.sort(Comparator.comparing(c -> getValue(c, fieldName)));
List<Contract> selectedContracts = new ArrayList<>();
int contractsSize = this.contracts.size();
Decimal sum = Decimal.ZERO;
for (int i = 0; i < contractsSize; i++) {
Contract contract = this.contracts.get(i);
Decimal cValue = getValue(contract, fieldName);
sum = sum.add(cValue);
if (selectedContracts.size() >= MAX_SELECTIONS_OF_CONTRACTS && selectedContracts.get(i % MAX_SELECTIONS_OF_CONTRACTS) != null) {
sum.subtract(getValue(selectedContracts.get(i % MAX_SELECTIONS_OF_CONTRACTS), fieldName));
selectedContracts.set(i % MAX_SELECTIONS_OF_CONTRACTS, contract);
} else
selectedContracts.add(i % MAX_SELECTIONS_OF_CONTRACTS, contract);
int compared = sum.compareTo(value);
if (compared == 0) {
result = joinAndRemoveFromContracts(selectedContracts);
result.getStateData().set(fieldName, sum);
break;
} else if (compared == 1) {
result = joinAndRemoveFromContracts(selectedContracts);
result.getStateData().set(fieldName, sum);
// split with change and add it back to the contracts
Contract newContract = result.splitValue(fieldName, sum.subtract(value));
this.contracts.add(newContract);
break;
}
}
if (result == null)
throw new IllegalArgumentException("The amount of contracts from the walled does not match the expected value.");
return result;
}
use of com.icodici.universa.contract.Contract in project universa by UniversaBlockchain.
the class PostgresLedger method putItem.
@Override
public void putItem(StateRecord record, Approvable item, Instant keepTill) {
if (item instanceof Contract) {
try (PooledDb db = dbPool.db()) {
try (PreparedStatement statement = db.statement("insert into items(id,packed,keepTill) values(?,?,?);")) {
statement.setLong(1, record.getRecordId());
statement.setBytes(2, ((Contract) item).getPackedTransaction());
statement.setLong(3, keepTill.getEpochSecond());
db.updateWithStatement(statement);
} catch (Exception e) {
e.printStackTrace();
throw e;
}
} catch (SQLException se) {
se.printStackTrace();
throw new Failure("item save failed:" + se);
} catch (Exception e) {
e.printStackTrace();
}
}
}
Aggregations