Compare commits
	
		
			No commits in common. "d7b6ce1f25ded2fce4b40037c78c868f6658a718" and "4c2569810a95735e6a4b5fad310f35db8d004caf" have entirely different histories.
		
	
	
		
			d7b6ce1f25
			...
			4c2569810a
		
	
		
| @ -150,7 +150,7 @@ public class CordaClient { | |||||||
|         return actionResult.successStatus(); |         return actionResult.successStatus(); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     public GameBoard gameProposalAccept( |     public UUID gameProposalAccept( // TODO shall return newGameBoard | ||||||
|         HoldingIdentity myHoldingIdentity, |         HoldingIdentity myHoldingIdentity, | ||||||
|         UUID gameProposalUuid |         UUID gameProposalUuid | ||||||
|     ) { |     ) { | ||||||
|  | |||||||
| @ -1,7 +1,7 @@ | |||||||
| package djmil.cordacheckers.cordaclient.dao.flow.arguments; | package djmil.cordacheckers.cordaclient.dao.flow.arguments; | ||||||
| 
 | 
 | ||||||
| import djmil.cordacheckers.cordaclient.dao.GameBoard; | import java.util.UUID; | ||||||
| 
 | 
 | ||||||
| public record GameProposalCommandAcceptRes(GameBoard successStatus, String transactionId, String failureStatus) { | public record GameProposalCommandAcceptRes(UUID successStatus, String transactionId, String failureStatus) { | ||||||
|      |      | ||||||
| } | } | ||||||
|  | |||||||
| @ -143,16 +143,16 @@ public class CordaClientTest { | |||||||
|                 gpUuid); |                 gpUuid); | ||||||
|         }); |         }); | ||||||
| 
 | 
 | ||||||
|         final GameBoard gbState = cordaClient.gameProposalAccept( |         final UUID newGameBoardId = cordaClient.gameProposalAccept( | ||||||
|             holdingIdentityResolver.getByUsername(gpAcquier), |             holdingIdentityResolver.getByUsername(gpAcquier), | ||||||
|             gpUuid); |             gpUuid); | ||||||
| 
 | 
 | ||||||
|         System.out.println("New GameBoard UUID "+gbState); |         System.out.println("New GameBoard UUID "+newGameBoardId); | ||||||
| 
 | 
 | ||||||
|         List<GameBoard> gbListIssuer = cordaClient.gameBoardList( |         List<GameBoard> gbListIssuer = cordaClient.gameBoardList( | ||||||
|             holdingIdentityResolver.getByUsername(gpIssuer)); |             holdingIdentityResolver.getByUsername(gpIssuer)); | ||||||
| 
 | 
 | ||||||
|         GameBoard gbAlice = findByUuid(gbListIssuer, gbState.id()); |         GameBoard gbAlice = findByUuid(gbListIssuer, newGameBoardId); | ||||||
|         assertThat(gbAlice).isNotNull(); |         assertThat(gbAlice).isNotNull(); | ||||||
|         assertThat(gbAlice.opponentName()).isEqualToIgnoringCase(gpAcquier); |         assertThat(gbAlice.opponentName()).isEqualToIgnoringCase(gpAcquier); | ||||||
|         assertThat(gbAlice.opponentColor()).isEqualByComparingTo(gpAcquierColor); |         assertThat(gbAlice.opponentColor()).isEqualByComparingTo(gpAcquierColor); | ||||||
| @ -162,7 +162,7 @@ public class CordaClientTest { | |||||||
|         List<GameBoard> gbListAcquier = cordaClient.gameBoardList( |         List<GameBoard> gbListAcquier = cordaClient.gameBoardList( | ||||||
|         holdingIdentityResolver.getByUsername(gpAcquier)); |         holdingIdentityResolver.getByUsername(gpAcquier)); | ||||||
| 
 | 
 | ||||||
|         GameBoard bgBob = findByUuid(gbListAcquier, gbState.id()); |         GameBoard bgBob = findByUuid(gbListAcquier, newGameBoardId); | ||||||
|         assertThat(bgBob).isNotNull(); |         assertThat(bgBob).isNotNull(); | ||||||
|         assertThat(bgBob.opponentName()).isEqualToIgnoringCase(gpIssuer); |         assertThat(bgBob.opponentName()).isEqualToIgnoringCase(gpIssuer); | ||||||
|         assertThat(bgBob.opponentColor()).isEqualByComparingTo(Piece.Color.BLACK); |         assertThat(bgBob.opponentColor()).isEqualByComparingTo(Piece.Color.BLACK); | ||||||
| @ -196,14 +196,14 @@ public class CordaClientTest { | |||||||
| 
 | 
 | ||||||
|         System.out.println("New GameProposal UUID "+ gpUuid); |         System.out.println("New GameProposal UUID "+ gpUuid); | ||||||
| 
 | 
 | ||||||
|         final GameBoard gbState = cordaClient.gameProposalAccept( |         final UUID newGameBoardId = cordaClient.gameProposalAccept( | ||||||
|             hiBob, gpUuid |             hiBob, gpUuid | ||||||
|         ); |         ); | ||||||
| 
 | 
 | ||||||
|         System.out.println("New GameBoard UUID "+ gbState.id()); |         System.out.println("New GameBoard UUID "+ newGameBoardId); | ||||||
| 
 | 
 | ||||||
|         final GameBoard gbSurrender = cordaClient.gameBoardCommand( |         GameBoard gbSurrender = cordaClient.gameBoardCommand( | ||||||
|             hiBob, gbState.id(),  |             hiBob, newGameBoardId,  | ||||||
|             new GameBoardCommand(GameBoardCommand.Type.SURRENDER) |             new GameBoardCommand(GameBoardCommand.Type.SURRENDER) | ||||||
|             ); |             ); | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -2,20 +2,16 @@ package djmil.cordacheckers.contracts; | |||||||
| 
 | 
 | ||||||
| import java.util.List; | import java.util.List; | ||||||
| 
 | 
 | ||||||
| import net.corda.v5.base.annotations.ConstructorForDeserialization; |  | ||||||
| import net.corda.v5.base.annotations.CordaSerializable; |  | ||||||
| import net.corda.v5.base.exceptions.CordaRuntimeException; | import net.corda.v5.base.exceptions.CordaRuntimeException; | ||||||
| import net.corda.v5.ledger.utxo.Command; | import net.corda.v5.ledger.utxo.Command; | ||||||
| 
 | 
 | ||||||
| public class GameBoardCommand implements Command { | public class GameBoardCommand implements Command { | ||||||
| 
 |  | ||||||
|     @CordaSerializable |  | ||||||
|     public static enum Type { |     public static enum Type { | ||||||
|         MOVE, |         MOVE, | ||||||
|         SURRENDER, |         SURRENDER, | ||||||
|         DRAW, |         REQUEST_DRAW, | ||||||
|         VICTORY, |         REQUEST_VICTORY, | ||||||
|         ACCEPT; // aka accept opponents DRAW or VICTORY request |         FINISH; // aka accept DRAW or VICTORY request | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     private final Type type; |     private final Type type; | ||||||
| @ -27,12 +23,6 @@ public class GameBoardCommand implements Command { | |||||||
|         this.move = null; |         this.move = null; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     @ConstructorForDeserialization |  | ||||||
|     public GameBoardCommand(Type type, List<Integer> move) { |  | ||||||
|         this.type = type; |  | ||||||
|         this.move = move; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     public GameBoardCommand(Type type) { |     public GameBoardCommand(Type type) { | ||||||
|         if (type == Type.MOVE) |         if (type == Type.MOVE) | ||||||
|             throw new CordaRuntimeException (BAD_ACTIONMOVE_CONSTRUCTOR); |             throw new CordaRuntimeException (BAD_ACTIONMOVE_CONSTRUCTOR); | ||||||
|  | |||||||
| @ -22,34 +22,23 @@ public class GameBoardContract implements net.corda.v5.ledger.utxo.Contract { | |||||||
|     public void verify(UtxoLedgerTransaction trx) { |     public void verify(UtxoLedgerTransaction trx) { | ||||||
|         log.info("GameBoardContract.verify() called"); |         log.info("GameBoardContract.verify() called"); | ||||||
| 
 | 
 | ||||||
|         requireThat(trx.getCommands().size() == 1, REQUIRE_SINGLE_COMMAND); |  | ||||||
|         final Command command = getSingleCommand(trx, Command.class); |         final Command command = getSingleCommand(trx, Command.class); | ||||||
| 
 | 
 | ||||||
|         if (command instanceof GameProposalCommand) { |         if (command instanceof GameProposalCommand) { | ||||||
|             log.info("GameBoardContract.verify() as GameProposalCommand "+(GameProposalCommand)command); |             log.info("GameBoardContract.verify() as GameProposalCommand "+(GameProposalCommand)command); | ||||||
|             switch ((GameProposalCommand)command) { |  | ||||||
|                 case ACCEPT: |  | ||||||
|                     GameProposalCommand.validateAcceptTrx(trx); |  | ||||||
|                     break; |  | ||||||
| 
 |  | ||||||
|                 default: |  | ||||||
|                     throw new CordaRuntimeException(UNKNOWN_COMMAND); |  | ||||||
|             } |  | ||||||
|         } else  |         } else  | ||||||
|         if (command instanceof GameBoardCommand) { |         if (command instanceof GameBoardCommand) { | ||||||
|             log.info("GameBoardContract.verify() as GameBoardCommand "+((GameBoardCommand)command).getType()); |             log.info("GameBoardContract.verify() as GameBoardCommand "+((GameBoardCommand)command).getType()); | ||||||
|             switch (((GameBoardCommand)command).getType()) { |             switch (((GameBoardCommand)command).getType()) { | ||||||
|                 case MOVE: |                 case MOVE: | ||||||
|                 break; |                 break; | ||||||
|                  |  | ||||||
|                 case SURRENDER: |                 case SURRENDER: | ||||||
|                 break; |                 break; | ||||||
| 
 |                 case REQUEST_DRAW: | ||||||
|                 case DRAW: |  | ||||||
|                 break; |                 break; | ||||||
|                 case VICTORY: |                 case REQUEST_VICTORY: | ||||||
|                 break; |                 break; | ||||||
|                 case ACCEPT: |                 case FINISH: | ||||||
|                 break; |                 break; | ||||||
|             } |             } | ||||||
|         } else { |         } else { | ||||||
|  | |||||||
| @ -1,15 +1,9 @@ | |||||||
| package djmil.cordacheckers.contracts; | package djmil.cordacheckers.contracts; | ||||||
| 
 | 
 | ||||||
| import djmil.cordacheckers.states.GameBoardState; |  | ||||||
| import djmil.cordacheckers.states.GameProposalState; | import djmil.cordacheckers.states.GameProposalState; | ||||||
| import net.corda.v5.base.types.MemberX500Name; | import net.corda.v5.base.types.MemberX500Name; | ||||||
| import net.corda.v5.ledger.utxo.Command; | import net.corda.v5.ledger.utxo.Command; | ||||||
| import net.corda.v5.ledger.utxo.StateAndRef; | import net.corda.v5.ledger.utxo.StateAndRef; | ||||||
| import net.corda.v5.ledger.utxo.transaction.UtxoLedgerTransaction; |  | ||||||
| 
 |  | ||||||
| import static djmil.cordacheckers.contracts.UtxoLedgerTransactionUtil.getSingleInputState; |  | ||||||
| import static djmil.cordacheckers.contracts.UtxoLedgerTransactionUtil.getSingleOutputState; |  | ||||||
| import static djmil.cordacheckers.contracts.UtxoLedgerTransactionUtil.requireThat; |  | ||||||
| 
 | 
 | ||||||
| public enum GameProposalCommand implements Command {  | public enum GameProposalCommand implements Command {  | ||||||
|     CREATE, |     CREATE, | ||||||
| @ -51,52 +45,5 @@ public enum GameProposalCommand implements Command { | |||||||
|         return getRespondent(utxoGameProposal.getState().getContractState()); |         return getRespondent(utxoGameProposal.getState().getContractState()); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     public static void validateCreateTrx(UtxoLedgerTransaction trx) { |  | ||||||
|         requireThat(trx.getInputContractStates().isEmpty(), CREATE_INPUT_STATE); |  | ||||||
|         requireThat(trx.getOutputContractStates().size() == 1, CREATE_OUTPUT_STATE); |  | ||||||
| 
 |  | ||||||
|         GameProposalState outputState = getSingleOutputState(trx, GameProposalState.class); |  | ||||||
| 
 |  | ||||||
|         requireThat(outputState.getAcquierColor() != null, NON_NULL_RECIPIENT_COLOR); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     public static void validateAcceptTrx(UtxoLedgerTransaction trx) { |  | ||||||
|         requireThat(trx.getInputContractStates().size() == 1, ACCEPT_INPUT_STATE); |  | ||||||
|         requireThat(trx.getOutputContractStates().size() == 1, ACCEPT_OUTPUT_STATE); |  | ||||||
| 
 |  | ||||||
|         GameProposalState inGameProposal = getSingleInputState(trx, GameProposalState.class); |  | ||||||
|         GameBoardState outGameBoard      = getSingleOutputState(trx, GameBoardState.class); |  | ||||||
| 
 |  | ||||||
|         requireThat(outGameBoard.getParticipants().containsAll(inGameProposal.getParticipants()), ACCEPT_PARTICIPANTS); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     public static void validateRejectTrx(UtxoLedgerTransaction trx) { |  | ||||||
|         requireThat(trx.getInputContractStates().size() == 1, REJECT_INPUT_STATE); |  | ||||||
|         requireThat(trx.getOutputContractStates().isEmpty(), REJECT_OUTPUT_STATE); |  | ||||||
| 
 |  | ||||||
|         getSingleInputState(trx, GameProposalState.class); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     public static void validateCancelTrx(UtxoLedgerTransaction trx) { |  | ||||||
|         requireThat(trx.getInputContractStates().size() == 1, CANCEL_INPUT_STATE); |  | ||||||
|         requireThat(trx.getOutputContractStates().isEmpty(), CANCEL_OUTPUT_STATE); |  | ||||||
|          |  | ||||||
|         getSingleInputState(trx, GameProposalState.class); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     public static final String UNSUPPORTED_VALUE_OF = "Unsupported GameProposalCommand value: "; |     public static final String UNSUPPORTED_VALUE_OF = "Unsupported GameProposalCommand value: "; | ||||||
| 
 |  | ||||||
|     static final String CREATE_INPUT_STATE  = "Create command should have no input states"; |  | ||||||
|     static final String CREATE_OUTPUT_STATE = "Create command should output exactly one GameProposal state"; |  | ||||||
|     static final String NON_NULL_RECIPIENT_COLOR = "GameProposal.recipientColor field can not be null"; |  | ||||||
| 
 |  | ||||||
|     static final String REJECT_INPUT_STATE  = "Reject command should have exactly one GameProposal input state"; |  | ||||||
|     static final String REJECT_OUTPUT_STATE = "Reject command should have no output states"; |  | ||||||
| 
 |  | ||||||
|     static final String CANCEL_INPUT_STATE  = "Cancel command should have exactly one GameProposal input state"; |  | ||||||
|     static final String CANCEL_OUTPUT_STATE = "Cancel command should have no output states"; |  | ||||||
| 
 |  | ||||||
|     static final String ACCEPT_INPUT_STATE  = "Accept command should have exactly one GameProposal input state"; |  | ||||||
|     static final String ACCEPT_OUTPUT_STATE = "Accept command should have exactly one GameBoard output state"; |  | ||||||
|     static final String ACCEPT_PARTICIPANTS = "Accept command: GameBoard participants should math GameProposal participants"; |  | ||||||
| } | } | ||||||
|  | |||||||
| @ -1,14 +1,17 @@ | |||||||
| package djmil.cordacheckers.contracts; | package djmil.cordacheckers.contracts; | ||||||
| 
 | 
 | ||||||
|  | import static djmil.cordacheckers.contracts.UtxoLedgerTransactionUtil.getSingleCommand; | ||||||
|  | import static djmil.cordacheckers.contracts.UtxoLedgerTransactionUtil.getSingleInputState; | ||||||
|  | import static djmil.cordacheckers.contracts.UtxoLedgerTransactionUtil.getSingleOutputState; | ||||||
|  | 
 | ||||||
| import org.slf4j.Logger; | import org.slf4j.Logger; | ||||||
| import org.slf4j.LoggerFactory; | import org.slf4j.LoggerFactory; | ||||||
| 
 | 
 | ||||||
|  | import djmil.cordacheckers.states.GameBoardState; | ||||||
|  | import djmil.cordacheckers.states.GameProposalState; | ||||||
| import net.corda.v5.base.exceptions.CordaRuntimeException; | import net.corda.v5.base.exceptions.CordaRuntimeException; | ||||||
| import net.corda.v5.ledger.utxo.transaction.UtxoLedgerTransaction; | import net.corda.v5.ledger.utxo.transaction.UtxoLedgerTransaction; | ||||||
| 
 | 
 | ||||||
| import static djmil.cordacheckers.contracts.UtxoLedgerTransactionUtil.getSingleCommand; |  | ||||||
| import static djmil.cordacheckers.contracts.UtxoLedgerTransactionUtil.requireThat; |  | ||||||
| 
 |  | ||||||
| public class GameProposalContract implements net.corda.v5.ledger.utxo.Contract { | public class GameProposalContract implements net.corda.v5.ledger.utxo.Contract { | ||||||
| 
 | 
 | ||||||
|     private final static Logger log = LoggerFactory.getLogger(GameProposalContract.class); |     private final static Logger log = LoggerFactory.getLogger(GameProposalContract.class); | ||||||
| @ -17,24 +20,40 @@ public class GameProposalContract implements net.corda.v5.ledger.utxo.Contract { | |||||||
|     public void verify(UtxoLedgerTransaction trx) { |     public void verify(UtxoLedgerTransaction trx) { | ||||||
|         log.info("GameProposalContract.verify() called"); |         log.info("GameProposalContract.verify() called"); | ||||||
| 
 | 
 | ||||||
|         requireThat(trx.getCommands().size() == 1, REQUIRE_SINGLE_COMMAND); |  | ||||||
|         final GameProposalCommand command = getSingleCommand(trx, GameProposalCommand.class); |         final GameProposalCommand command = getSingleCommand(trx, GameProposalCommand.class); | ||||||
| 
 | 
 | ||||||
|         switch (command) { |         switch (command) { | ||||||
|             case CREATE: |             case CREATE: { | ||||||
|                 GameProposalCommand.validateCreateTrx(trx); |                 requireThat(trx.getInputContractStates().isEmpty(), CREATE_INPUT_STATE); | ||||||
|                 break; |                 requireThat(trx.getOutputContractStates().size() == 1, CREATE_OUTPUT_STATE); | ||||||
| 
 | 
 | ||||||
|             case ACCEPT: |                 GameProposalState outputState = getSingleOutputState(trx, GameProposalState.class); | ||||||
|                 GameProposalCommand.validateAcceptTrx(trx); |  | ||||||
|                 break; |  | ||||||
| 
 | 
 | ||||||
|             case REJECT: |                 requireThat(outputState.getAcquierColor() != null, NON_NULL_RECIPIENT_COLOR); | ||||||
|                 GameProposalCommand.validateRejectTrx(trx); |                 break; } | ||||||
|                 break; | 
 | ||||||
|  |             case ACCEPT: { | ||||||
|  |                 requireThat(trx.getInputContractStates().size() == 1, ACCEPT_INPUT_STATE); | ||||||
|  |                 requireThat(trx.getOutputContractStates().size() == 1, ACCEPT_OUTPUT_STATE); | ||||||
|  | 
 | ||||||
|  |                 GameProposalState inGameProposal = getSingleInputState(trx, GameProposalState.class); | ||||||
|  |                 GameBoardState outGameBoard      = getSingleOutputState(trx, GameBoardState.class); | ||||||
|  | 
 | ||||||
|  |                 requireThat(outGameBoard.getParticipants().containsAll(inGameProposal.getParticipants()), ACCEPT_PARTICIPANTS); | ||||||
|  |                 break; }  | ||||||
|  | 
 | ||||||
|  |             case REJECT: { | ||||||
|  |                 requireThat(trx.getInputContractStates().size() == 1, REJECT_INPUT_STATE); | ||||||
|  |                 requireThat(trx.getOutputContractStates().isEmpty(), REJECT_OUTPUT_STATE); | ||||||
|  | 
 | ||||||
|  |                 getSingleInputState(trx, GameProposalState.class); | ||||||
|  |                 break; } | ||||||
| 
 | 
 | ||||||
|             case CANCEL: |             case CANCEL: | ||||||
|                 GameProposalCommand.validateCancelTrx(trx); |                 requireThat(trx.getInputContractStates().size() == 1, CANCEL_INPUT_STATE); | ||||||
|  |                 requireThat(trx.getOutputContractStates().isEmpty(), CANCEL_OUTPUT_STATE); | ||||||
|  |                  | ||||||
|  |                 getSingleInputState(trx, GameProposalState.class); | ||||||
|                 break; |                 break; | ||||||
| 
 | 
 | ||||||
|             default: |             default: | ||||||
| @ -42,6 +61,26 @@ public class GameProposalContract implements net.corda.v5.ledger.utxo.Contract { | |||||||
|         } |         } | ||||||
|     } |     } | ||||||
|      |      | ||||||
|  |     private void requireThat(boolean asserted, String errorMessage) { | ||||||
|  |         if (!asserted) { | ||||||
|  |             throw new CordaRuntimeException("Failed requirement: " + errorMessage); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     static final String REQUIRE_SINGLE_COMMAND = "Require a single command"; |     static final String REQUIRE_SINGLE_COMMAND = "Require a single command"; | ||||||
|     static final String UNKNOWN_COMMAND = "Unsupported command"; |     static final String UNKNOWN_COMMAND = "Unsupported command"; | ||||||
|   } | 
 | ||||||
|  |     static final String CREATE_INPUT_STATE  = "Create command should have no input states"; | ||||||
|  |     static final String CREATE_OUTPUT_STATE = "Create command should output exactly one GameProposal state"; | ||||||
|  |     static final String NON_NULL_RECIPIENT_COLOR = "GameProposal.recipientColor field can not be null"; | ||||||
|  | 
 | ||||||
|  |     static final String REJECT_INPUT_STATE  = "Reject command should have exactly one GameProposal input state"; | ||||||
|  |     static final String REJECT_OUTPUT_STATE = "Reject command should have no output states"; | ||||||
|  | 
 | ||||||
|  |     static final String CANCEL_INPUT_STATE  = "Cancel command should have exactly one GameProposal input state"; | ||||||
|  |     static final String CANCEL_OUTPUT_STATE = "Cancel command should have no output states"; | ||||||
|  | 
 | ||||||
|  |     static final String ACCEPT_INPUT_STATE  = "Accept command should have exactly one GameProposal input state"; | ||||||
|  |     static final String ACCEPT_OUTPUT_STATE = "Accept command should have exactly one GameBoard output state"; | ||||||
|  |     static final String ACCEPT_PARTICIPANTS = "Accept command: GameBoard participants should math GameProposal participants"; | ||||||
|  | } | ||||||
|  | |||||||
| @ -40,12 +40,6 @@ public class UtxoLedgerTransactionUtil { | |||||||
|         return optional(utxoTrx.getOutputStates(clazz), clazz); |         return optional(utxoTrx.getOutputStates(clazz), clazz); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     public static void requireThat(boolean asserted, String errorMessage) { |  | ||||||
|         if (!asserted) { |  | ||||||
|             throw new IllegalStateException("Failed requirement: " + errorMessage); |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     private static <T> Optional<T> optional(List<T> list, Class<T> clazz) { |     private static <T> Optional<T> optional(List<T> list, Class<T> clazz) { | ||||||
|         return list |         return list | ||||||
|             .stream() |             .stream() | ||||||
|  | |||||||
| @ -67,7 +67,9 @@ public class ListFlow implements ClientStartableFlow { | |||||||
|         final UtxoLedgerTransaction utxoGameBoard = utxoLedgerService |         final UtxoLedgerTransaction utxoGameBoard = utxoLedgerService | ||||||
|             .findLedgerTransaction(trxId); |             .findLedgerTransaction(trxId); | ||||||
| 
 | 
 | ||||||
|         return new GameBoardView(myName, utxoGameBoard); |         var newGbView = new GameBoardView(myName, utxoGameBoard); | ||||||
|  | 
 | ||||||
|  |         return newGbView; | ||||||
|     } |     } | ||||||
|      |      | ||||||
| } | } | ||||||
|  | |||||||
| @ -6,9 +6,7 @@ import org.slf4j.Logger; | |||||||
| import org.slf4j.LoggerFactory; | import org.slf4j.LoggerFactory; | ||||||
| 
 | 
 | ||||||
| import djmil.cordacheckers.FlowResult; | import djmil.cordacheckers.FlowResult; | ||||||
| import djmil.cordacheckers.contracts.GameBoardCommand; |  | ||||||
| import djmil.cordacheckers.contracts.GameProposalCommand; | import djmil.cordacheckers.contracts.GameProposalCommand; | ||||||
| import djmil.cordacheckers.gameboard.GameBoardView; |  | ||||||
| import djmil.cordacheckers.states.GameBoardState; | import djmil.cordacheckers.states.GameBoardState; | ||||||
| import djmil.cordacheckers.states.GameProposalState; | import djmil.cordacheckers.states.GameProposalState; | ||||||
| import net.corda.v5.application.flows.ClientRequestBody; | import net.corda.v5.application.flows.ClientRequestBody; | ||||||
| @ -16,13 +14,10 @@ import net.corda.v5.application.flows.ClientStartableFlow; | |||||||
| import net.corda.v5.application.flows.CordaInject; | import net.corda.v5.application.flows.CordaInject; | ||||||
| import net.corda.v5.application.flows.FlowEngine; | import net.corda.v5.application.flows.FlowEngine; | ||||||
| import net.corda.v5.application.marshalling.JsonMarshallingService; | import net.corda.v5.application.marshalling.JsonMarshallingService; | ||||||
| import net.corda.v5.application.membership.MemberLookup; |  | ||||||
| import net.corda.v5.base.annotations.Suspendable; | import net.corda.v5.base.annotations.Suspendable; | ||||||
| import net.corda.v5.base.types.MemberX500Name; |  | ||||||
| import net.corda.v5.crypto.SecureHash; | import net.corda.v5.crypto.SecureHash; | ||||||
| import net.corda.v5.ledger.utxo.StateAndRef; | import net.corda.v5.ledger.utxo.StateAndRef; | ||||||
| import net.corda.v5.ledger.utxo.UtxoLedgerService; | import net.corda.v5.ledger.utxo.UtxoLedgerService; | ||||||
| import net.corda.v5.ledger.utxo.transaction.UtxoLedgerTransaction; |  | ||||||
| import net.corda.v5.ledger.utxo.transaction.UtxoSignedTransaction; | import net.corda.v5.ledger.utxo.transaction.UtxoSignedTransaction; | ||||||
| import net.corda.v5.ledger.utxo.transaction.UtxoTransactionBuilder; | import net.corda.v5.ledger.utxo.transaction.UtxoTransactionBuilder; | ||||||
| 
 | 
 | ||||||
| @ -37,14 +32,11 @@ public class CommandFlow implements ClientStartableFlow { | |||||||
|     public JsonMarshallingService jsonMarshallingService; |     public JsonMarshallingService jsonMarshallingService; | ||||||
| 
 | 
 | ||||||
|     @CordaInject |     @CordaInject | ||||||
|     public UtxoLedgerService utxoLedgerService; |     public UtxoLedgerService ledgerService; | ||||||
| 
 | 
 | ||||||
|     @CordaInject |     @CordaInject | ||||||
|     public FlowEngine flowEngine; |     public FlowEngine flowEngine; | ||||||
| 
 | 
 | ||||||
|     @CordaInject |  | ||||||
|     public MemberLookup memberLookup;     |  | ||||||
| 
 |  | ||||||
|     @Override |     @Override | ||||||
|     @Suspendable |     @Suspendable | ||||||
|     public String call(ClientRequestBody requestBody) { |     public String call(ClientRequestBody requestBody) { | ||||||
| @ -52,17 +44,17 @@ public class CommandFlow implements ClientStartableFlow { | |||||||
|             final CommandFlowArgs args = requestBody.getRequestBodyAs(jsonMarshallingService, CommandFlowArgs.class); |             final CommandFlowArgs args = requestBody.getRequestBodyAs(jsonMarshallingService, CommandFlowArgs.class); | ||||||
|             final GameProposalCommand command = args.getCommand(); |             final GameProposalCommand command = args.getCommand(); | ||||||
| 
 | 
 | ||||||
|             final StateAndRef<GameProposalState> gpStateAndRef = findUnconsumedGameProposalState(args.getGameProposalUuid()); |             final StateAndRef<GameProposalState> utxoGameProposal = findUnconsumedGameProposalState(args.getGameProposalUuid()); | ||||||
| 
 | 
 | ||||||
|             final UtxoSignedTransaction trxCandidate = prepareSignedTransaction(command, gpStateAndRef); |             final UtxoSignedTransaction trx = prepareSignedTransaction(command, utxoGameProposal); | ||||||
| 
 | 
 | ||||||
|             final SecureHash trxId = this.flowEngine |             final SecureHash trxId = this.flowEngine | ||||||
|                 .subFlow( new CommitSubFlow(trxCandidate, command.getRespondent(gpStateAndRef)) ); |                 .subFlow( new CommitSubFlow(trx, command.getRespondent(utxoGameProposal)) ); | ||||||
| 
 | 
 | ||||||
|             if (command == GameProposalCommand.ACCEPT) { |             if (command == GameProposalCommand.ACCEPT) { | ||||||
|                 final GameBoardView gbView = prepareGameBoardView(trxId); |                 GameBoardState newGb = (GameBoardState)trx.getOutputStateAndRefs().get(0).getState().getContractState(); | ||||||
| 
 | 
 | ||||||
|                 return new FlowResult(gbView, trxId)  |                 return new FlowResult(newGb.getId(), trxId)  | ||||||
|                     .toJsonEncodedString(jsonMarshallingService); |                     .toJsonEncodedString(jsonMarshallingService); | ||||||
|             } |             } | ||||||
| 
 | 
 | ||||||
| @ -77,16 +69,16 @@ public class CommandFlow implements ClientStartableFlow { | |||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     @Suspendable |     @Suspendable | ||||||
|     private StateAndRef<GameProposalState> findUnconsumedGameProposalState (UUID gpUuid) { |     private StateAndRef<GameProposalState> findUnconsumedGameProposalState (UUID gameProposalUuid) { | ||||||
|         /* |         /* | ||||||
|          * Get list of all unconsumed aka 'active' GameProposalStates, then filter by UUID. |          * Get list of all unconsumed aka 'active' GameProposalStates, then filter by UUID. | ||||||
|          * Note, this is an inefficient way to perform this operation if there are a large |          * Note, this is an inefficient way to perform this operation if there are a large | ||||||
|          * number of 'active' GameProposals exists in storage. |          * number of 'active' GameProposals exists in storage. | ||||||
|          */ |          */ | ||||||
|         return this.utxoLedgerService |         return this.ledgerService | ||||||
|             .findUnconsumedStatesByType(GameProposalState.class) |             .findUnconsumedStatesByType(GameProposalState.class) | ||||||
|             .stream() |             .stream() | ||||||
|             .filter(sar -> sar.getState().getContractState().getId().equals(gpUuid)) |             .filter(sar -> sar.getState().getContractState().getId().equals(gameProposalUuid)) | ||||||
|             .reduce((a, b) -> {throw new IllegalStateException("Multiple states: " +a +", " +b);}) |             .reduce((a, b) -> {throw new IllegalStateException("Multiple states: " +a +", " +b);}) | ||||||
|             .get(); |             .get(); | ||||||
|     } |     } | ||||||
| @ -94,18 +86,18 @@ public class CommandFlow implements ClientStartableFlow { | |||||||
|     @Suspendable |     @Suspendable | ||||||
|     private UtxoSignedTransaction prepareSignedTransaction( |     private UtxoSignedTransaction prepareSignedTransaction( | ||||||
|         GameProposalCommand command, |         GameProposalCommand command, | ||||||
|         StateAndRef<GameProposalState> gpStateAndRef |         StateAndRef<GameProposalState> utxoGameProposal | ||||||
|     ) { |     ) { | ||||||
|         UtxoTransactionBuilder trxBuilder = utxoLedgerService.createTransactionBuilder() |         UtxoTransactionBuilder trxBuilder = ledgerService.createTransactionBuilder() | ||||||
|             .setNotary(gpStateAndRef.getState().getNotaryName()) |             .setNotary(utxoGameProposal.getState().getNotaryName()) | ||||||
|             .setTimeWindowBetween(Instant.now(), Instant.now().plusMillis(Duration.ofDays(1).toMillis())) |             .setTimeWindowBetween(Instant.now(), Instant.now().plusMillis(Duration.ofDays(1).toMillis())) | ||||||
|             .addInputState(gpStateAndRef.getRef()) |             .addInputState(utxoGameProposal.getRef()) | ||||||
|             .addCommand(command) |             .addCommand(command) | ||||||
|             .addSignatories(gpStateAndRef.getState().getContractState().getParticipants()); |             .addSignatories(utxoGameProposal.getState().getContractState().getParticipants()); | ||||||
| 
 | 
 | ||||||
|         if (command == GameProposalCommand.ACCEPT) { |         if (command == GameProposalCommand.ACCEPT) { | ||||||
|             trxBuilder = trxBuilder |             trxBuilder = trxBuilder | ||||||
|                 .addOutputState(new GameBoardState(gpStateAndRef)); |                 .addOutputState(new GameBoardState(utxoGameProposal)); | ||||||
|                 //A state cannot be both an input and a reference input in the same transaction |                 //A state cannot be both an input and a reference input in the same transaction | ||||||
|                 //.addReferenceState(utxoGameProposal.getRef()); |                 //.addReferenceState(utxoGameProposal.getRef()); | ||||||
|         } |         } | ||||||
| @ -113,14 +105,4 @@ public class CommandFlow implements ClientStartableFlow { | |||||||
|         return trxBuilder.toSignedTransaction(); |         return trxBuilder.toSignedTransaction(); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     @Suspendable |  | ||||||
|     private GameBoardView prepareGameBoardView(SecureHash gbUtxoTrxId) { |  | ||||||
|         final MemberX500Name myName = memberLookup.myInfo().getName(); |  | ||||||
| 
 |  | ||||||
|         final UtxoLedgerTransaction utxoGameBoard = utxoLedgerService |  | ||||||
|             .findLedgerTransaction(gbUtxoTrxId); |  | ||||||
| 
 |  | ||||||
|         return new GameBoardView(myName, utxoGameBoard); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
| } | } | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user