0 votes
1 view
in Blockchain by (12.4k points)

I have a problem with a very simple Hyperledger Composer applicationnamespace com.softwaremill.drivernetwork

participant Driver identified by licenseId {

  o String licenseId

  o String firstName

  o String lastName

  o Boolean licenseValid default =true

}

enum LaweEnforcerType {

  o POLICE

  o CUSTOMS

  o BORDER_GUARDS

}

participant LawEnforcer identified by lawEnforcerId {

  o String lawEnforcerId

  o LaweEnforcerType lawEnforcerType

}

participant Court identified by courtId {

  o String courtId

  o String description

}

enum FineState {

  o ISSUED

  o REJECTED

  o ACCEPTED

}

asset Fine identified by fineId {

  o String fineId

  o Integer penaltyPoints

  o DateTime date

  o FineState fineState default ="ISSUED"

  --> Driver driver

  --> LawEnforcer lawEnforcer

}

asset CourtCase identified by caseId {

  o String caseId

  --> Court court optional

  --> Fine fine

}

transaction AcceptedFine {

  --> Fine fine

}

transaction RejectedFine {

  --> Fine fine

}

LawEnforcer can issue a Fine. The Fine can be either Accepted or Rejected (then it goes to Court) by the driver.

What I am trying to do is to automatically invalidate the driver's license if the sum of all his accepted penaltyPoints on Fines exceeds 20 points.

So I have created a transaction processor

/**

 * Accept fine

 * @param {com.softwaremill.drivernetwork.AcceptedFine} acceptedFine

 * @transaction

 */

async function acceptedFine(acceptedFine) {

    console.log(`Accepting fine ${acceptedFine}`);

    const fineRegistry = await     getAssetRegistry('com.softwaremill.drivernetwork.Fine');

    acceptedFine.fine.fineState = 'ACCEPTED';

    await fineRegistry.update(acceptedFine.fine); // [1]

    const allFines = await query('selectAcceptedFinesByDriver', 

    {driver: `resource:com.softwaremill.drivernetwork.Driver#${acceptedFine.fine.driver.licenseId}`}); // [2]

    if (allFines.reduce((acc, val) => {return acc + val.penaltyPoints;}, 0) > 20) {

        console.log('Driver excceded 20 points, blocking license');

        const driverRegistry = await getParticipantRegistry('com.softwaremill.drivernetwork.Driver');

        acceptedFine.fine.driver.licenseValid = false;

        await driverRegistry.update(acceptedFine.fine.driver);

    }

}

And the query code

query selectAcceptedFinesByDriver {

  description: "Select all accepted fines for a given driver"

  statement:

    SELECT com.softwaremill.drivernetwork.Fine

      WHERE (driver == _$driver AND fineState == "ACCEPTED")

}

Now the code should set the Fine state to ACCEPTED at [1]. This works - after the transaction is processed I am able to see the property changed.

But the problem is that at [2] when the query is executed the Fine that just got updated at [1] has still status ISSUED (I've removed the right part of wherein the query to debug it).

What am I missing here? Is the shape of the blockchain someone frozen for the transaction? What is going on?

1 Answer

0 votes
by (29k points)

the issue is that you can't "read your own writes". Transactions are atomic (so all of the states being changed in one transaction get committed as one transaction, from the current state, or - the whole transaction gets rejected.

The query would only work (in this case) if that transaction is already committed ie by the organisations' peers that endorse/commit the transaction (atomic transaction) to a block (and the world state).

You can read more on transaction processors here -> https://hyperledger.github.io/composer/latest/reference/js_scripts

Welcome to Intellipaat Community. Get your technical queries answered by top developers !


Categories

...