GamePrposal: Accept to return GameBoard
This commit is contained in:
		
							parent
							
								
									4c2569810a
								
							
						
					
					
						commit
						a836d14fbd
					
				| @ -150,7 +150,7 @@ public class CordaClient { | ||||
|         return actionResult.successStatus(); | ||||
|     } | ||||
| 
 | ||||
|     public UUID gameProposalAccept( // TODO shall return newGameBoard | ||||
|     public GameBoard gameProposalAccept( | ||||
|         HoldingIdentity myHoldingIdentity, | ||||
|         UUID gameProposalUuid | ||||
|     ) { | ||||
|  | ||||
| @ -1,7 +1,7 @@ | ||||
| package djmil.cordacheckers.cordaclient.dao.flow.arguments; | ||||
| 
 | ||||
| import java.util.UUID; | ||||
| import djmil.cordacheckers.cordaclient.dao.GameBoard; | ||||
| 
 | ||||
| public record GameProposalCommandAcceptRes(UUID successStatus, String transactionId, String failureStatus) { | ||||
| public record GameProposalCommandAcceptRes(GameBoard successStatus, String transactionId, String failureStatus) { | ||||
|      | ||||
| } | ||||
|  | ||||
| @ -143,16 +143,16 @@ public class CordaClientTest { | ||||
|                 gpUuid); | ||||
|         }); | ||||
| 
 | ||||
|         final UUID newGameBoardId = cordaClient.gameProposalAccept( | ||||
|         final GameBoard gbState = cordaClient.gameProposalAccept( | ||||
|             holdingIdentityResolver.getByUsername(gpAcquier), | ||||
|             gpUuid); | ||||
| 
 | ||||
|         System.out.println("New GameBoard UUID "+newGameBoardId); | ||||
|         System.out.println("New GameBoard UUID "+gbState); | ||||
| 
 | ||||
|         List<GameBoard> gbListIssuer = cordaClient.gameBoardList( | ||||
|             holdingIdentityResolver.getByUsername(gpIssuer)); | ||||
| 
 | ||||
|         GameBoard gbAlice = findByUuid(gbListIssuer, newGameBoardId); | ||||
|         GameBoard gbAlice = findByUuid(gbListIssuer, gbState.id()); | ||||
|         assertThat(gbAlice).isNotNull(); | ||||
|         assertThat(gbAlice.opponentName()).isEqualToIgnoringCase(gpAcquier); | ||||
|         assertThat(gbAlice.opponentColor()).isEqualByComparingTo(gpAcquierColor); | ||||
| @ -162,7 +162,7 @@ public class CordaClientTest { | ||||
|         List<GameBoard> gbListAcquier = cordaClient.gameBoardList( | ||||
|         holdingIdentityResolver.getByUsername(gpAcquier)); | ||||
| 
 | ||||
|         GameBoard bgBob = findByUuid(gbListAcquier, newGameBoardId); | ||||
|         GameBoard bgBob = findByUuid(gbListAcquier, gbState.id()); | ||||
|         assertThat(bgBob).isNotNull(); | ||||
|         assertThat(bgBob.opponentName()).isEqualToIgnoringCase(gpIssuer); | ||||
|         assertThat(bgBob.opponentColor()).isEqualByComparingTo(Piece.Color.BLACK); | ||||
| @ -196,14 +196,14 @@ public class CordaClientTest { | ||||
| 
 | ||||
|         System.out.println("New GameProposal UUID "+ gpUuid); | ||||
| 
 | ||||
|         final UUID newGameBoardId = cordaClient.gameProposalAccept( | ||||
|         final GameBoard gbState = cordaClient.gameProposalAccept( | ||||
|             hiBob, gpUuid | ||||
|         ); | ||||
| 
 | ||||
|         System.out.println("New GameBoard UUID "+ newGameBoardId); | ||||
|         System.out.println("New GameBoard UUID "+ gbState.id()); | ||||
| 
 | ||||
|         GameBoard gbSurrender = cordaClient.gameBoardCommand( | ||||
|             hiBob, newGameBoardId,  | ||||
|         final GameBoard gbSurrender = cordaClient.gameBoardCommand( | ||||
|             hiBob, gbState.id(),  | ||||
|             new GameBoardCommand(GameBoardCommand.Type.SURRENDER) | ||||
|             ); | ||||
| 
 | ||||
|  | ||||
| @ -2,10 +2,14 @@ package djmil.cordacheckers.contracts; | ||||
| 
 | ||||
| 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.ledger.utxo.Command; | ||||
| 
 | ||||
| public class GameBoardCommand implements Command { | ||||
| 
 | ||||
|     @CordaSerializable | ||||
|     public static enum Type { | ||||
|         MOVE, | ||||
|         SURRENDER, | ||||
| @ -23,6 +27,12 @@ public class GameBoardCommand implements Command { | ||||
|         this.move = null; | ||||
|     } | ||||
| 
 | ||||
|     @ConstructorForDeserialization | ||||
|     public GameBoardCommand(Type type, List<Integer> move) { | ||||
|         this.type = type; | ||||
|         this.move = move; | ||||
|     } | ||||
| 
 | ||||
|     public GameBoardCommand(Type type) { | ||||
|         if (type == Type.MOVE) | ||||
|             throw new CordaRuntimeException (BAD_ACTIONMOVE_CONSTRUCTOR); | ||||
|  | ||||
| @ -67,9 +67,7 @@ public class ListFlow implements ClientStartableFlow { | ||||
|         final UtxoLedgerTransaction utxoGameBoard = utxoLedgerService | ||||
|             .findLedgerTransaction(trxId); | ||||
| 
 | ||||
|         var newGbView = new GameBoardView(myName, utxoGameBoard); | ||||
| 
 | ||||
|         return newGbView; | ||||
|         return new GameBoardView(myName, utxoGameBoard); | ||||
|     } | ||||
|      | ||||
| } | ||||
|  | ||||
| @ -6,7 +6,9 @@ import org.slf4j.Logger; | ||||
| import org.slf4j.LoggerFactory; | ||||
| 
 | ||||
| import djmil.cordacheckers.FlowResult; | ||||
| import djmil.cordacheckers.contracts.GameBoardCommand; | ||||
| import djmil.cordacheckers.contracts.GameProposalCommand; | ||||
| import djmil.cordacheckers.gameboard.GameBoardView; | ||||
| import djmil.cordacheckers.states.GameBoardState; | ||||
| import djmil.cordacheckers.states.GameProposalState; | ||||
| import net.corda.v5.application.flows.ClientRequestBody; | ||||
| @ -14,10 +16,13 @@ import net.corda.v5.application.flows.ClientStartableFlow; | ||||
| import net.corda.v5.application.flows.CordaInject; | ||||
| import net.corda.v5.application.flows.FlowEngine; | ||||
| 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.types.MemberX500Name; | ||||
| import net.corda.v5.crypto.SecureHash; | ||||
| import net.corda.v5.ledger.utxo.StateAndRef; | ||||
| 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.UtxoTransactionBuilder; | ||||
| 
 | ||||
| @ -32,11 +37,14 @@ public class CommandFlow implements ClientStartableFlow { | ||||
|     public JsonMarshallingService jsonMarshallingService; | ||||
| 
 | ||||
|     @CordaInject | ||||
|     public UtxoLedgerService ledgerService; | ||||
|     public UtxoLedgerService utxoLedgerService; | ||||
| 
 | ||||
|     @CordaInject | ||||
|     public FlowEngine flowEngine; | ||||
| 
 | ||||
|     @CordaInject | ||||
|     public MemberLookup memberLookup;     | ||||
| 
 | ||||
|     @Override | ||||
|     @Suspendable | ||||
|     public String call(ClientRequestBody requestBody) { | ||||
| @ -44,17 +52,17 @@ public class CommandFlow implements ClientStartableFlow { | ||||
|             final CommandFlowArgs args = requestBody.getRequestBodyAs(jsonMarshallingService, CommandFlowArgs.class); | ||||
|             final GameProposalCommand command = args.getCommand(); | ||||
| 
 | ||||
|             final StateAndRef<GameProposalState> utxoGameProposal = findUnconsumedGameProposalState(args.getGameProposalUuid()); | ||||
|             final StateAndRef<GameProposalState> gpStateAndRef = findUnconsumedGameProposalState(args.getGameProposalUuid()); | ||||
| 
 | ||||
|             final UtxoSignedTransaction trx = prepareSignedTransaction(command, utxoGameProposal); | ||||
|             final UtxoSignedTransaction trxCandidate = prepareSignedTransaction(command, gpStateAndRef); | ||||
| 
 | ||||
|             final SecureHash trxId = this.flowEngine | ||||
|                 .subFlow( new CommitSubFlow(trx, command.getRespondent(utxoGameProposal)) ); | ||||
|                 .subFlow( new CommitSubFlow(trxCandidate, command.getRespondent(gpStateAndRef)) ); | ||||
| 
 | ||||
|             if (command == GameProposalCommand.ACCEPT) { | ||||
|                 GameBoardState newGb = (GameBoardState)trx.getOutputStateAndRefs().get(0).getState().getContractState(); | ||||
|                 final GameBoardView gbView = prepareGameBoardView(trxId); | ||||
| 
 | ||||
|                 return new FlowResult(newGb.getId(), trxId)  | ||||
|                 return new FlowResult(gbView, trxId)  | ||||
|                     .toJsonEncodedString(jsonMarshallingService); | ||||
|             } | ||||
| 
 | ||||
| @ -69,16 +77,16 @@ public class CommandFlow implements ClientStartableFlow { | ||||
|     } | ||||
| 
 | ||||
|     @Suspendable | ||||
|     private StateAndRef<GameProposalState> findUnconsumedGameProposalState (UUID gameProposalUuid) { | ||||
|     private StateAndRef<GameProposalState> findUnconsumedGameProposalState (UUID gpUuid) { | ||||
|         /* | ||||
|          * 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 | ||||
|          * number of 'active' GameProposals exists in storage. | ||||
|          */ | ||||
|         return this.ledgerService | ||||
|         return this.utxoLedgerService | ||||
|             .findUnconsumedStatesByType(GameProposalState.class) | ||||
|             .stream() | ||||
|             .filter(sar -> sar.getState().getContractState().getId().equals(gameProposalUuid)) | ||||
|             .filter(sar -> sar.getState().getContractState().getId().equals(gpUuid)) | ||||
|             .reduce((a, b) -> {throw new IllegalStateException("Multiple states: " +a +", " +b);}) | ||||
|             .get(); | ||||
|     } | ||||
| @ -86,18 +94,18 @@ public class CommandFlow implements ClientStartableFlow { | ||||
|     @Suspendable | ||||
|     private UtxoSignedTransaction prepareSignedTransaction( | ||||
|         GameProposalCommand command, | ||||
|         StateAndRef<GameProposalState> utxoGameProposal | ||||
|         StateAndRef<GameProposalState> gpStateAndRef | ||||
|     ) { | ||||
|         UtxoTransactionBuilder trxBuilder = ledgerService.createTransactionBuilder() | ||||
|             .setNotary(utxoGameProposal.getState().getNotaryName()) | ||||
|         UtxoTransactionBuilder trxBuilder = utxoLedgerService.createTransactionBuilder() | ||||
|             .setNotary(gpStateAndRef.getState().getNotaryName()) | ||||
|             .setTimeWindowBetween(Instant.now(), Instant.now().plusMillis(Duration.ofDays(1).toMillis())) | ||||
|             .addInputState(utxoGameProposal.getRef()) | ||||
|             .addInputState(gpStateAndRef.getRef()) | ||||
|             .addCommand(command) | ||||
|             .addSignatories(utxoGameProposal.getState().getContractState().getParticipants()); | ||||
|             .addSignatories(gpStateAndRef.getState().getContractState().getParticipants()); | ||||
| 
 | ||||
|         if (command == GameProposalCommand.ACCEPT) { | ||||
|             trxBuilder = trxBuilder | ||||
|                 .addOutputState(new GameBoardState(utxoGameProposal)); | ||||
|                 .addOutputState(new GameBoardState(gpStateAndRef)); | ||||
|                 //A state cannot be both an input and a reference input in the same transaction | ||||
|                 //.addReferenceState(utxoGameProposal.getRef()); | ||||
|         } | ||||
| @ -105,4 +113,14 @@ public class CommandFlow implements ClientStartableFlow { | ||||
|         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