public ItemState getItemState() { if(record != null) return record.getState(); return ItemState.UNDEFINED; } }
private ItemState getState() { return record.getState(); }
/** * true if we need to get vote from a node * * @param node we might need vote from * * @return */ private final boolean needsVoteFrom(NodeInfo node) { return record.getState().isPending() && !positiveNodes.contains(node) && !negativeNodes.contains(node); }
public ResyncingItem(HashId hid, StateRecord record) { resyncingState = ResyncingItemProcessingState.WAIT_FOR_VOTES; this.hashId = hid; this.record = record; StateRecord recordWas = ledger.getRecord(hid); if (recordWas != null) { stateWas = recordWas.getState(); } else { stateWas = ItemState.UNDEFINED; } resyncNodes.put(ItemState.APPROVED, new HashSet<>()); resyncNodes.put(ItemState.REVOKED, new HashSet<>()); resyncNodes.put(ItemState.DECLINED, new HashSet<>()); resyncNodes.put(ItemState.UNDEFINED, new HashSet<>()); }
/** * Shortcut method: check that record exists and its state returns {@link ItemState#isApproved()}}. Check it to * ensure its meaning. * * @param id is {@link HashId} for checking item * @return true if it is. */ default boolean isApproved(HashId id) { StateRecord r = getRecord(id); return r != null && r.getState().isApproved(); }
/** * Shortcut method: check that record exists and its state returns {@link ItemState#isConsensusFound()}}. Check it to * ensure its meaning. * * @param id is {@link HashId} for checking item * @return true if it is. */ default boolean isConsensusFound(HashId id) { StateRecord r = getRecord(id); return r != null && r.getState().isConsensusFound(); }
/** * Initialize from a record and posession flag * * @param record record to get data from * @param haveCopy true if the node has a copy of the {@link Approvable} item (e.g. one can try go call {@link * com.icodici.universa.node2.network.Network#getItem(HashId, NodeInfo, Duration)} on it */ public ItemResult(StateRecord record, boolean haveCopy) { // if( record == null ) { // throw new IllegalStateException("record can not be null"); // } state = record.getState(); this.haveCopy = haveCopy; createdAt = record.getCreatedAt(); expiresAt = record.getExpiresAt(); }
@Override public String toString() { return "State<"+getId()+"/"+getRecordId()+":"+getState()+":"+getCreatedAt()+"/"+getExpiresAt()+">"; } }
protected void assertSameRecords(StateRecord r, StateRecord r1) { assertEquals(r.getId(), r1.getId()); assertEquals(r.getState(), r1.getState()); assertAlmostSame(r.getCreatedAt(), r1.getCreatedAt()); assertEquals(r.getRecordId(), r1.getRecordId()); assertEquals(r.getLockedByRecordId(), r1.getLockedByRecordId()); }
r1.reload(); StateRecord r3 = ledger.getRecord(r1.getId()); assertEquals(ItemState.APPROVED, r1.getState()); assertEquals(ItemState.APPROVED, r3.getState()); r2.reload(); assertEquals(ItemState.DECLINED, r2.getState()); Object y = ledger.transaction(() -> { r1.setState(ItemState.REVOKED); assert (y == null); r1.reload(); assertEquals(ItemState.APPROVED, r1.getState()); r2.reload(); assertEquals(ItemState.DECLINED, r2.getState());
@Test public void checkLockOwner() throws Exception { ledger.enableCache(true); StateRecord existing = ledger.findOrCreate(HashId.createRandom()); existing.approve(); StateRecord r = ledger.findOrCreate(HashId.createRandom()); StateRecord r1 = r.lockToRevoke(existing.getId()); existing.reload(); r.reload(); assertSameRecords(existing, r1); assertEquals(ItemState.LOCKED, existing.getState()); assertEquals(r.getRecordId(), existing.getLockedByRecordId()); StateRecord currentOwner = ledger.getLockOwnerOf(existing); System.out.println("existing: " + existing.getId()); System.out.println("locker: " + r.getId()); System.out.println("locked: " + r1.getId()); System.out.println("currentOwner: " + currentOwner.getId()); assertSameRecords(r, currentOwner); }
@Test public void checkNegativeBytesInId() throws Exception { HashId id = HashId.withDigest(Do.randomNegativeBytes(64)); StateRecord r1 = ledger.findOrCreate(id); r1.setState(ItemState.DECLINED); r1.save(); StateRecord r2 = ledger.getRecord(id); assertNotNull(r2); assertNotSame(r1, r2); assertEquals(r1.getState(), r2.getState()); ledger.enableCache(true); StateRecord r3 = ledger.getRecord(id); StateRecord r4 = ledger.getRecord(id); assertEquals(r3.toString(), r4.toString()); // why? assertSame(r3, r4); }
@Test public void checkNegatoveBytesInId() throws Exception { HashId id = HashId.withDigest(Do.randomNegativeBytes(64)); StateRecord r1 = ledger.findOrCreate(id); r1.setState(ItemState.DECLINED); r1.save(); StateRecord r2 = ledger.getRecord(id); assertNotNull(r2); assertNotSame(r1, r2); assertEquals(r1.getState(), r2.getState()); ledger.enableCache(true); StateRecord r3 = ledger.getRecord(id); StateRecord r4 = ledger.getRecord(id); assertEquals(r3.toString(), r4.toString()); // why? assertSame(r3, r4); }
@Test public void findOrCreateAndGet() throws Exception { // Atomic new record creation HashId id = HashId.createRandom(); StateRecord r = ledger.findOrCreate(id); assertNotNull(r); assertEquals(id, r.getId()); assertEquals(ItemState.PENDING, r.getState()); assertAlmostSame(ZonedDateTime.now(), r.getCreatedAt()); // returning existing record StateRecord r1 = ledger.findOrCreate(id); assertSameRecords(r, r1); StateRecord r2 = ledger.getRecord(id); assertSameRecords(r, r2); StateRecord r3 = ledger.getRecord(HashId.createRandom()); assert (r3 == null); }
@Test public void findOrCreateAndGet() throws Exception { // Atomic new record creation HashId id = HashId.createRandom(); StateRecord r = ledger.findOrCreate(id); assertNotNull(r); assertEquals(id, r.getId()); assertEquals(ItemState.PENDING, r.getState()); assertAlmostSame(ZonedDateTime.now(), r.getCreatedAt()); // returning existing record StateRecord r1 = ledger.findOrCreate(id); assertSameRecords(r, r1); StateRecord r2 = ledger.getRecord(id); assertSameRecords(r, r2); StateRecord r3 = ledger.getRecord(HashId.createRandom()); assert (r3 == null); }
@Test public void approve() throws Exception { StateRecord r1 = ledger.findOrCreate(HashId.createRandom()); assertFalse(r1.isApproved()); r1.approve(); assertEquals(ItemState.APPROVED, r1.getState()); assert (r1.isApproved()); r1.reload(); assert (r1.isApproved()); assertThrows(IllegalStateException.class, () -> { r1.approve(); return null; }); }
@Test public void approve() throws Exception { StateRecord r1 = ledger.findOrCreate(HashId.createRandom()); assertFalse(r1.isApproved()); r1.approve(); assertEquals(ItemState.APPROVED, r1.getState()); assert (r1.isApproved()); r1.reload(); assert (r1.isApproved()); assertThrows(IllegalStateException.class, () -> { r1.approve(); return null; }); }
@Test public void lockForRevoking() throws Exception { ledger.enableCache(true); StateRecord existing = ledger.findOrCreate(HashId.createRandom()); existing.approve(); StateRecord existing2 = ledger.findOrCreate(HashId.createRandom()); existing2.approve(); StateRecord r = ledger.findOrCreate(HashId.createRandom()); StateRecord r1 = r.lockToRevoke(existing.getId()); existing.reload(); r.reload(); assertSameRecords(existing, r1); assertEquals(ItemState.LOCKED, existing.getState()); assertEquals(r.getRecordId(), existing.getLockedByRecordId()); StateRecord r2 = r.lockToRevoke(existing.getId()); existing.reload(); r.reload(); assertSameRecords(existing, r1); assertSameRecords(existing, r2); assertSame(r1, r2); assertEquals(ItemState.LOCKED, existing.getState()); assertEquals(r.getRecordId(), existing.getLockedByRecordId()); StateRecord r3 = r.lockToRevoke(existing2.getId()); existing2.reload(); assertSameRecords(existing2, r3); assertEquals(ItemState.LOCKED, existing2.getState()); assertEquals(r.getRecordId(), existing2.getLockedByRecordId()); }
@Test public void createOutputLockRecord() throws Exception { ledger.enableCache(true); StateRecord owner = ledger.findOrCreate(HashId.createRandom()); StateRecord other = ledger.findOrCreate(HashId.createRandom()); HashId id = HashId.createRandom(); StateRecord r1 = owner.createOutputLockRecord(id); r1.reload(); assertEquals(id, r1.getId()); assertEquals(ItemState.LOCKED_FOR_CREATION, r1.getState()); assertEquals(owner.getRecordId(), r1.getLockedByRecordId()); StateRecord r2 = owner.createOutputLockRecord(id); assertSame(r2, r1); assertNull(owner.createOutputLockRecord(other.getId())); // And hacked low level operation must fail too assertNull(ledger.createOutputLockRecord(owner.getRecordId(), other.getId())); }
@Test public void createOutputLockRecord() throws Exception { ledger.enableCache(true); StateRecord owner = ledger.findOrCreate(HashId.createRandom()); StateRecord other = ledger.findOrCreate(HashId.createRandom()); HashId id = HashId.createRandom(); StateRecord r1 = owner.createOutputLockRecord(id); r1.reload(); assertEquals(id, r1.getId()); assertEquals(ItemState.LOCKED_FOR_CREATION, r1.getState()); assertEquals(owner.getRecordId(), r1.getLockedByRecordId()); StateRecord r2 = owner.createOutputLockRecord(id); assertSame(r2, r1); assertNull(owner.createOutputLockRecord(other.getId())); // And hacked low level operation must fail too assertNull(ledger.createOutputLockRecord(owner.getRecordId(), other.getId())); }