use of com.icodici.universa.Decimal 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.Decimal 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.Decimal in project universa by UniversaBlockchain.
the class ContractTest method calculateSplitProcessingCostbreakWhileUnpacking.
@Test
public void calculateSplitProcessingCostbreakWhileUnpacking() throws Exception {
// Should create contract, sign and seal it, then create revision and split.
// Then while calculating cost should break while unpacking contract (signs verifying).
// should repeat contract processing procedure on the Node
// (Contract.fromPackedTransaction() -> Contract(byte[], TransactionPack) -> Contract.check())
Contract contract = createCoin100apiv3();
contract.addSignerKeyFromFile(PRIVATE_KEY_PATH);
sealCheckTrace(contract, true);
System.out.println("Split");
Contract forSplit = contract.createRevision();
Contract splitted = forSplit.splitValue(FIELD_NAME, new Decimal(20));
splitted.addSignerKeyFromFile(PRIVATE_KEY_PATH);
sealCheckTrace(splitted, true);
sealCheckTrace(forSplit, true);
assertEquals(new Decimal(80), forSplit.getStateData().get("amount"));
assertEquals(new Decimal(20), new Decimal(Long.valueOf(splitted.getStateData().get("amount").toString())));
System.out.println("Calculated processing cost (forSplit): " + forSplit.getProcessedCost() + " (UTN)");
System.out.println("Calculated processing cost (splitted): " + splitted.getProcessedCost() + " (UTN)");
// Check 4096 bits signature own (8) +
// Check 4096 bits signature new item (8) +
// Check 4096 bits signature revoking item (8) +
// Register a self version (20) +
// Register new item a version (20) +
// Register revoking item a version (20) +
// Check self change owner permission (1) +
// Check self change split join permission (1+2) +
// Check self change revoke permission (1) +
// Check new item change owner permission (1) +
// Check new item change split join permission (1+2) +
// Check new item change revoke permission (1)
int costShouldBeForSplit = 94;
boolean exceptionThrown = false;
try {
processContractAsItWillBeOnTheNode(forSplit, 20);
} catch (Quantiser.QuantiserException e) {
System.out.println("Thrown correct exception: " + e.getMessage());
exceptionThrown = true;
} catch (BiSerializationException e) {
System.out.println("Thrown correct exception: " + e.getMessage());
exceptionThrown = true;
}
assertEquals(true, exceptionThrown);
}
use of com.icodici.universa.Decimal in project universa by UniversaBlockchain.
the class WalletTest method shouldTransferAndSplitRest.
@Test
public void shouldTransferAndSplitRest() throws Exception {
Decimal valueToSend = new Decimal(15);
List<Contract> listOfCoinsWithAmount = createListOfCoinsWithAmount(Arrays.asList(1, 2, 3, 5, 8));
List<Wallet> wallets = Wallet.determineWallets(listOfCoinsWithAmount);
assertEquals(1, wallets.size());
assertEquals(5, wallets.get(0).getContracts().size());
Wallet wallet = wallets.get(0);
Contract contract = wallet.buildContractWithValue(FIELD_NAME, valueToSend);
contract.addSignerKeyFromFile(PRIVATE_KEY_PATH);
assertEquals(1, wallet.getContracts().size());
sealCheckTrace(contract, true);
Contract restContract = wallet.getContracts().get(0);
assertEquals(4, restContract.getStateData().getIntOrThrow(FIELD_NAME));
sealCheckTrace(restContract, true);
TransactionPack tp = contract.getTransactionPack();
Contract contractToSend = new Contract(contract.seal(), tp);
contractToSend.addSignerKeyFromFile(PRIVATE_KEY_PATH);
sealCheckTrace(contractToSend, true);
assertEquals(valueToSend.intValue(), contractToSend.getStateData().getIntOrThrow(FIELD_NAME));
}
use of com.icodici.universa.Decimal in project universa by UniversaBlockchain.
the class CLIMainTest method calculateContractProcessingCostFromManySources.
@Test
public void calculateContractProcessingCostFromManySources() throws Exception {
// Should use contracts from all sources, call one -cost command for all of them and print cost of processing it.
Contract contract = createCoin();
contract.getStateData().set(FIELD_NAME, new Decimal(100));
contract.addSignerKeyFromFile(PRIVATE_KEY_PATH);
contract.seal();
// sealCheckTrace(contract, true);
CLIMain.saveContract(contract, basePath + "contract_for_cost1.unicon");
CLIMain.saveContract(contract, basePath + "contract_for_cost2.unicon");
System.out.println("--- cost checking ---");
// Check 4096 bits signature (8) +
// Register a version (20)
int costShouldBe = (int) Math.floor(28 / Quantiser.quantaPerUTN) + 1;
callMain("--cost", basePath + "contract_for_cost1.unicon", basePath + "contract_for_cost2.unicon");
System.out.println(output);
assertTrue(output.indexOf("Contract processing cost is " + costShouldBe + " TU") >= 2);
}
Aggregations