/** * Implementing join procedure. * <br><br> * Service create new revision of first contract, update amount field with sum of amount fields in the both contracts * and put second contract in revoking items of created new revision. * <br><br> * Given contract should have splitjoin permission for given keys. * <br><br> * * @param contract1 is contract should be join to * @param contract2 is contract should be join * @param fieldName is name of field that should be join by * @param keys is keys from owner of both contracts * @return working contract that should be register in the Universa to finish procedure. */ public synchronized static Contract createJoin(Contract contract1, Contract contract2, String fieldName, Set<PrivateKey> keys) { Contract joinTo = contract1.createRevision(); joinTo.getStateData().set( fieldName, InnerContractsService.getDecimalField(contract1, fieldName).add(InnerContractsService.getDecimalField(contract2, fieldName)) ); for (PrivateKey key : keys) { joinTo.addSignerKey(key); } joinTo.addRevokingItems(contract2); joinTo.seal(); return joinTo; }
contract.addRevokingItems(subContracts.get(i));
@Test @Ignore("it is snatch test") public void joinSnatch() throws Exception { PrivateKey key = new PrivateKey(Do.read(ROOT_PATH + "_xer0yfe2nn1xthc.private.unikey")); Set<PrivateKey> keys = new HashSet<>(); keys.add(key); Contract c1 = Contract.fromDslFile(ROOT_PATH + "coin100.yml"); c1.addSignerKey(key); assertTrue(c1.check()); c1.seal(); registerAndCheckApproved(c1); System.out.println("money before split (c1): " + c1.getStateData().getIntOrThrow("amount")); Contract c2 = ContractsService.createSplit(c1, new BigDecimal("99"), "amount", keys); Contract c3 = c2.getNew().get(0); System.out.println("money after split (c2): " + c2.getStateData().getIntOrThrow("amount")); System.out.println("money after split (c3): " + c3.getStateData().getIntOrThrow("amount")); registerAndCheckApproved(c3); Contract c4 = c3.createRevision(keys); c4.addRevokingItems(c1); c4.getStateData().set("amount", 199);//150); c4.seal(); System.out.println("money after snatch (c4): " + c4.getStateData().getIntOrThrow("amount")); System.out.println("check after snatch (c4): " + c4.check()); c4.traceErrors(); registerAndCheckDeclined(c4); }
@Test(timeout = 90000) public void createTokenContractWithEmissionBadSignature() throws Exception { Set<PrivateKey> stepaPrivateKeys = new HashSet<>(); Set<PublicKey> stepaPublicKeys = new HashSet<>(); stepaPrivateKeys.add(new PrivateKey(Do.read(ROOT_PATH + "keys/stepan_mamontov.private.unikey"))); for (PrivateKey pk : stepaPrivateKeys) stepaPublicKeys.add(pk.getPublicKey()); Set<PrivateKey> martyPrivateKeys = new HashSet<>(); martyPrivateKeys.add(new PrivateKey(Do.read(ROOT_PATH + "keys/marty_mcfly.private.unikey"))); Contract tokenContract1 = ContractsService.createMintableTokenContract(martyPrivateKeys, stepaPublicKeys, new BigDecimal("300000000000")); tokenContract1.check(); tokenContract1.traceErrors(); registerAndCheckApproved(tokenContract1); Contract tokenContract2 = ContractsService.createMintableTokenContract(stepaPrivateKeys, stepaPublicKeys, new BigDecimal("100000000000")); tokenContract2.check(); tokenContract2.traceErrors(); registerAndCheckApproved(tokenContract2); Contract joinedContract = tokenContract1.createRevision(stepaPrivateKeys); joinedContract.addRevokingItems(tokenContract2); joinedContract.getStateData().set("amount","400000000000"); joinedContract.seal(); joinedContract.check(); joinedContract.traceErrors(); registerAndCheckDeclined(joinedContract); assertEquals(joinedContract.getStateData().getString("amount"), "400000000000"); assertEquals(ItemState.APPROVED, node.waitItem(tokenContract1.getId(), 8000).state); assertEquals(ItemState.APPROVED, node.waitItem(tokenContract2.getId(), 8000).state); }
@Test public void shouldSplitJoinHasEnoughSumRevoking() throws Exception { // 2 coins: 1st v: 50 (r: 50 and 50), 2nd v: 50 (r: 50 and 50) Contract root = createCoinWithAmount("200", FIELD_NAME); Contract c1 = root.splitValue(FIELD_NAME, new Decimal(100)); sealCheckTrace(c1, true); // c1 split 50 50 c1 = c1.createRevision(ownerKey2); c1.seal(); Contract c50_1 = c1.splitValue(FIELD_NAME, new Decimal(50)); sealCheckTrace(c50_1, true); //good join Contract finalC = c50_1.createRevision(ownerKey2); finalC.seal(); finalC.getStateData().set(FIELD_NAME, new Decimal(100)); finalC.addRevokingItems(c50_1); finalC.addRevokingItems(c1); sealCheckTrace(finalC, true); }
@Test(timeout = 90000) public void createTokenContractWithEmission() throws Exception { Set<PrivateKey> stepaPrivateKeys = new HashSet<>(); Set<PublicKey> stepaPublicKeys = new HashSet<>(); stepaPrivateKeys.add(new PrivateKey(Do.read(ROOT_PATH + "keys/stepan_mamontov.private.unikey"))); for (PrivateKey pk : stepaPrivateKeys) stepaPublicKeys.add(pk.getPublicKey()); Set<PrivateKey> martyPrivateKeys = new HashSet<>(); martyPrivateKeys.add(new PrivateKey(Do.read(ROOT_PATH + "keys/marty_mcfly.private.unikey"))); Contract tokenContract1 = ContractsService.createMintableTokenContract(martyPrivateKeys, stepaPublicKeys, new BigDecimal("300000000000")); tokenContract1.check(); tokenContract1.traceErrors(); registerAndCheckApproved(tokenContract1); Contract tokenContract2 = ContractsService.createMintableTokenContract(martyPrivateKeys, stepaPublicKeys, new BigDecimal("100000000000")); tokenContract2.check(); tokenContract2.traceErrors(); registerAndCheckApproved(tokenContract2); Contract joinedContract = tokenContract1.createRevision(stepaPrivateKeys); joinedContract.addRevokingItems(tokenContract2); joinedContract.getStateData().set("amount","400000000000"); joinedContract.seal(); joinedContract.check(); joinedContract.traceErrors(); registerAndCheckApproved(joinedContract); assertEquals(joinedContract.getStateData().getString("amount"), "400000000000"); assertEquals(ItemState.REVOKED, node.waitItem(tokenContract1.getId(), 8000).state); assertEquals(ItemState.REVOKED, node.waitItem(tokenContract2.getId(), 8000).state); }
@Test public void splitJoinHasTwoDifferentCoinTypes() throws Exception { Contract root = createCoinWithAmount("200", FIELD_NAME); Contract c1 = root.splitValue(FIELD_NAME, new Decimal(100)); sealCheckTrace(c1, true); // c1 split 50 50 c1 = c1.createRevision(ownerKey2); c1.seal(); Contract c50_1 = c1.splitValue(FIELD_NAME, new Decimal(50)); sealCheckTrace(c50_1, true); //set wrong revoking with the same amount root = root.createRevision(ownerKey2); root.seal(); Contract cr50 = createCoinWithAmount("50", FIELD_NAME); // coin amount: 200 (revoking: 100 and 50 and 50 another different coin) root.getStateData().set(FIELD_NAME, new Decimal(200)); root.addRevokingItems(c50_1); root.addRevokingItems(cr50); sealCheckTrace(root, false); }
@Test(timeout = 90000) public void shouldDeclineSplitAndJoinWithWrongAmount() throws Exception { if(node == null) { System.out.println("network not inited"); return; } PrivateKey key = new PrivateKey(Do.read(ROOT_PATH + "_xer0yfe2nn1xthc.private.unikey")); // 100 Contract c = Contract.fromDslFile(ROOT_PATH + "coin100.yml"); c.addSignerKey(key); c.seal(); assertTrue(c.check()); registerAndCheckApproved(c); assertEquals(100, c.getStateData().get("amount")); // split 100 - 30 = 70 Contract c1 = ContractsService.createSplit(c, new BigDecimal("30"), "amount", new HashSet<PrivateKey>(Arrays.asList(key))); Contract c2 = c1.getNew().get(0); registerAndCheckApproved(c1); assertEquals("70", c1.getStateData().get("amount").toString()); assertEquals("30", c2.getStateData().get("amount").toString()); //wrong. send 500 out of 2 contracts (70 + 30) Contract c3 = c2.createRevision(); c3.getStateData().set("amount", new Decimal(500)); c3.addSignerKey(key); c3.addRevokingItems(c1); c3.seal(); assertFalse(c3.check()); registerAndCheckDeclined(c3); }
@Test public void goodRevokeAnother() throws Exception { Contract c1 = new Contract(ownerKey1); RoleLink rl = new RoleLink("@revoke", "owner"); rl.setContract(c1); c1.addPermission(new RevokePermission(rl)); c1.seal(); Contract c2 = new Contract(ownerKey2); c2.seal(); Assert.assertTrue(c2.check()); Contract c3 = c2.createRevision(ownerKey2); //to prevent "state is identical" c3.setOwnerKeys(ownerKey3); c3.addSignerKey(ownerKey1); c3.addRevokingItems(c1); c3.seal(); assertTrue(c3.check()); }
contract.addRevokingItems(subContracts.get(i));
@Test public void splitJoinHasNotEnoughSumRevoking() throws Exception { Contract root = createCoinWithAmount("200", FIELD_NAME); Contract c1 = root.splitValue(FIELD_NAME, new Decimal(100)); sealCheckTrace(c1, true); // c1 split 50 50 c1 = c1.createRevision(ownerKey2); c1.seal(); Contract c50_1 = c1.splitValue(FIELD_NAME, new Decimal(50)); sealCheckTrace(c50_1, true); //set wrong revoking with the same amount root = root.createRevision(ownerKey2); root.seal(); // c1 split 45 5 c1 = c50_1.createRevision(ownerKey2); c1.seal(); Contract c5 = c1.splitValue(FIELD_NAME, new Decimal(5)); sealCheckTrace(c5, true); // coin amount: 200 (revoking: 100 and 50 and 5) root.getStateData().set(FIELD_NAME, new Decimal(200)); root.addRevokingItems(c50_1); root.addRevokingItems(c5); sealCheckTrace(root, false); }
@Test public void revokeDifferentNameValidRefRoleNotRegistered() throws Exception { Contract referencedContract = new Contract(key1); referencedContract.seal(); Contract revokingContract = new Contract(key2); Reference revokeReference = new Reference(revokingContract); revokeReference.setName("ref1"); ArrayList<String> revokeCondtitions = new ArrayList<>(); revokeCondtitions.add("ref.id=="+referencedContract.getId().toBase64String()); revokeReference.setConditions(Binder.of("all_of",revokeCondtitions)); revokingContract.addReference(revokeReference); SimpleRole role = new SimpleRole("@revoke"); role.addRequiredReference(revokeReference.getName(), Role.RequiredMode.ALL_OF); RevokePermission permission = new RevokePermission(role); revokingContract.addPermission(permission); revokingContract.seal(); Contract transactionRoot = new Contract(key3); transactionRoot.addRevokingItems(revokingContract); Reference rootReference = new Reference(transactionRoot); rootReference.setName("ref2"); ArrayList<String> rootConditions = new ArrayList<>(); rootConditions.add("ref.id=="+referencedContract.getId().toBase64String()); rootReference.setConditions(Binder.of("all_of",rootConditions)); transactionRoot.addReference(rootReference); transactionRoot.seal(); transactionRoot.getTransactionPack().addReferencedItem(referencedContract); transactionRoot = Contract.fromPackedTransaction(transactionRoot.getPackedTransaction()); transactionRoot.check(); assertTrue(transactionRoot.isOk()); }
@Test public void badRevokeAnother() throws Exception { Contract c1 = new Contract(ownerKey1); RoleLink rl = new RoleLink("@revoke", "owner"); rl.setContract(c1); c1.addPermission(new RevokePermission(rl)); c1.seal(); Contract c2 = new Contract(ownerKey2); c2.seal(); Assert.assertTrue(c2.check()); Contract c3 = c2.createRevision(ownerKey2); //to prevent "state is identical" c3.setOwnerKeys(ownerKey3); c3.addRevokingItems(c1); c3.seal(); assertFalse(c3.check()); }
transactionRoot.addRevokingItems(revokingContract); Reference rootReference = new Reference(transactionRoot); rootReference.setName("ref2");
transactionRoot.addRevokingItems(revokingContract); Reference rootReference = new Reference(transactionRoot); rootReference.setName("ref1");
transactionRoot.addRevokingItems(revokingContract); Reference rootReference = new Reference(transactionRoot); rootReference.setName("ref1");
revContract.deserialize(b, new BiDeserializer()); revContract.addRevokingItems(baseContract); revContract.setOwnerKey(manufacturePrivateKey); revContract.addSignerKey(manufacturePrivateKey);
revContract.deserialize(b, new BiDeserializer()); revContract.addRevokingItems(baseContract); revContract.setOwnerKey(manufacturePrivateKey); revContract.addSignerKey(manufacturePrivateKey);
revContract.deserialize(b, new BiDeserializer()); revContract.addRevokingItems(baseContract); revContract.setOwnerKey(manufacturePrivateKey); revContract.addSignerKey(manufacturePrivateKey);
c4.addSignerKey(ownerKey1); c4.addRevokingItems(c3); c4.seal(); assertFalse(c4.check());