Compare commits

..

No commits in common. "d7b6ce1f25ded2fce4b40037c78c868f6658a718" and "4c2569810a95735e6a4b5fad310f35db8d004caf" have entirely different histories.

10 changed files with 89 additions and 146 deletions

View File

@ -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
) { ) {

View File

@ -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) {
} }

View File

@ -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)
); );

View File

@ -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);

View File

@ -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 {

View File

@ -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";
} }

View File

@ -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";
} }

View File

@ -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()

View File

@ -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;
} }
} }

View File

@ -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);
}
} }