Corda: UtxoLedgerTransactionUtil helper class

This commit is contained in:
djmil 2023-09-12 18:56:07 +02:00
parent fdfcd711a7
commit fee93a2b10
5 changed files with 75 additions and 40 deletions

View File

@ -46,7 +46,7 @@ public class CordaClientTest {
}
@Test
void testGemeProposalCreate() throws JsonMappingException, JsonProcessingException {
void testGameProposalCreate() throws JsonMappingException, JsonProcessingException {
final String gpIssuer = "alice";
final String gpAcquier = "bob";
final Piece.Color gpAcquierColor = Piece.Color.WHITE;
@ -77,7 +77,7 @@ public class CordaClientTest {
}
@Test
void testGemeProposalReject() throws JsonMappingException, JsonProcessingException {
void testGameProposalReject() throws JsonMappingException, JsonProcessingException {
final String gpIssuer = "alice";
final String gpAcquier = "bob";
final Piece.Color gpReceiverColor = Piece.Color.WHITE;
@ -124,7 +124,7 @@ public class CordaClientTest {
}
@Test
void testGemeProposalAccept() throws JsonMappingException, JsonProcessingException {
void testGameProposalAccept() throws JsonMappingException, JsonProcessingException {
final String gpIssuer = "alice";
final String gpAcquier = "bob";
final Piece.Color gpAcquierColor = Piece.Color.WHITE;
@ -179,7 +179,7 @@ public class CordaClientTest {
}
@Test
void testGemeProposalList() throws JsonMappingException, JsonProcessingException {
void testGameBoardList() throws JsonMappingException, JsonProcessingException {
List <GameBoard> gbList = cordaClient.gameBoardList(
holdingIdentityResolver.getByUsername("bob"));

View File

@ -0,0 +1,43 @@
package djmil.cordacheckers;
import net.corda.v5.ledger.utxo.Command;
import net.corda.v5.ledger.utxo.ContractState;
import net.corda.v5.ledger.utxo.transaction.UtxoLedgerTransaction;
public class UtxoLedgerTransactionUtil {
private final UtxoLedgerTransaction trx;
public UtxoLedgerTransactionUtil(UtxoLedgerTransaction trx) {
this.trx = trx;
}
public <T extends Command> T getSingleCommand(Class<T> clazz) {
return trx.getCommands(clazz)
.stream()
.reduce( (a, b) -> {throw new IllegalStateException(trx.getId() +EXPECTED_SINGLE_CLAZZ +clazz);} )
.get();
}
public <T extends ContractState> T getSingleReferenceState(Class<T> clazz) {
return trx.getReferenceStates(clazz)
.stream()
.reduce( (a, b) -> {throw new IllegalStateException(trx.getId() +EXPECTED_SINGLE_CLAZZ +clazz);} )
.get();
}
public <T extends ContractState> T getSingleInputState(Class<T> clazz) {
return trx.getInputStates(clazz)
.stream()
.reduce( (a, b) -> {throw new IllegalStateException(trx.getId() +EXPECTED_SINGLE_CLAZZ +clazz);} )
.get();
}
public <T extends ContractState> T getSingleOutputState(Class<T> clazz) {
return trx.getOutputStates(clazz)
.stream()
.reduce( (a, b) -> {throw new IllegalStateException(trx.getId() +EXPECTED_SINGLE_CLAZZ +clazz);} )
.get();
}
private static String EXPECTED_SINGLE_CLAZZ = ": expected single ";
}

View File

@ -1,10 +1,9 @@
package djmil.cordacheckers.contracts;
import java.util.List;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import djmil.cordacheckers.UtxoLedgerTransactionUtil;
import djmil.cordacheckers.states.GameProposalState;
import net.corda.v5.base.annotations.Suspendable;
import net.corda.v5.base.exceptions.CordaRuntimeException;
@ -17,12 +16,10 @@ public class GameBoardContract implements net.corda.v5.ledger.utxo.Contract {
@Override
public void verify(UtxoLedgerTransaction trx) {
log.info("GameBoardContract.verify()");
log.info("GameBoardContract.verify() called");
final List<Command> commandList = trx.getCommands();
requireThat(commandList.size() == 1, REQUIRE_SINGLE_COMMAND);
final Command command = commandList.get(0);
final UtxoLedgerTransactionUtil trxUtil = new UtxoLedgerTransactionUtil(trx);
final Command command = trxUtil.getSingleCommand(Command.class);
if (command instanceof GameProposalCommand) {
log.info("GameBoardContract.verify() as GameProposalCommand "+(GameProposalCommand)command);
@ -39,26 +36,21 @@ public class GameBoardContract implements net.corda.v5.ledger.utxo.Contract {
case MOVE:
break;
}
} else {
throw new CordaRuntimeException(UNKNOWN_COMMAND);
}
}
@Suspendable
public static GameProposalState getReferanceGameProposalState(UtxoLedgerTransaction trx) {
final List<Command> commandList = trx.getCommands();
requireThat(commandList.size() == 1, REQUIRE_SINGLE_COMMAND);
final UtxoLedgerTransactionUtil trxUtil = new UtxoLedgerTransactionUtil(trx);
final Command command = trxUtil.getSingleCommand(Command.class);
final Command command = commandList.get(0);
if (command instanceof GameProposalCommand && (GameProposalCommand)command == GameProposalCommand.ACCEPT) {
return trx.getInputStates(GameProposalState.class)
.stream()
.reduce( (a, b) -> {throw new IllegalStateException(SINGLE_STATE_EXPECTED);} )
.get();
return trxUtil.getSingleInputState(GameProposalState.class);
} else
if (command instanceof GameBoardCommand) {
return trx.getReferenceStates(GameProposalState.class)
.stream()
.reduce( (a, b) -> {throw new IllegalStateException(SINGLE_STATE_EXPECTED);} )
.get();
return trxUtil.getSingleReferenceState(GameProposalState.class);
}
throw new IllegalStateException(NO_REFERANCE_GAMEPROPOSAL_STATE_FOR_TRXID +trx.getId());

View File

@ -3,6 +3,7 @@ package djmil.cordacheckers.contracts;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import djmil.cordacheckers.UtxoLedgerTransactionUtil;
import djmil.cordacheckers.states.GameBoardState;
import djmil.cordacheckers.states.GameProposalState;
import net.corda.v5.base.exceptions.CordaRuntimeException;
@ -16,42 +17,41 @@ public class GameProposalContract implements net.corda.v5.ledger.utxo.Contract {
public void verify(UtxoLedgerTransaction trx) {
log.info("GameProposalContract.verify() called");
requireThat(trx.getCommands().size() == 1, REQUIRE_SINGLE_COMMAND);
final UtxoLedgerTransactionUtil trxUtil = new UtxoLedgerTransactionUtil(trx);
final GameProposalCommand command = trxUtil.getSingleCommand(GameProposalCommand.class);
switch ((trx.getCommands(GameProposalCommand.class).get(0))) {
switch (command) {
case CREATE: {
requireThat(trx.getInputContractStates().isEmpty(), CREATE_INPUT_STATE);
requireThat(trx.getOutputContractStates().size() == 1, CREATE_OUTPUT_STATE);
GameProposalState outputState = trx.getOutputStates(GameProposalState.class).get(0);
requireThat(outputState != null, CREATE_OUTPUT_STATE);
GameProposalState outputState = trxUtil.getSingleOutputState(GameProposalState.class);
requireThat(outputState.getAcquierColor() != null, NON_NULL_RECIPIENT_COLOR);
break; }
case ACCEPT:
case ACCEPT: {
requireThat(trx.getInputContractStates().size() == 1, ACCEPT_INPUT_STATE);
requireThat(trx.getOutputContractStates().size() == 1, ACCEPT_OUTPUT_STATE);
GameProposalState inGameProposal = trx.getInputStates(GameProposalState.class).get(0);
requireThat(inGameProposal != null, ACCEPT_INPUT_STATE);
GameBoardState outGameBoard = trx.getOutputStates(GameBoardState.class).get(0);
requireThat(outGameBoard != null, ACCEPT_INPUT_STATE);
GameProposalState inGameProposal = trxUtil.getSingleInputState(GameProposalState.class);
GameBoardState outGameBoard = trxUtil.getSingleOutputState(GameBoardState.class);
requireThat(outGameBoard.getParticipants().containsAll(inGameProposal.getParticipants()), ACCEPT_PARTICIPANTS);
break;
break; }
case REJECT:
case REJECT: {
requireThat(trx.getInputContractStates().size() == 1, REJECT_INPUT_STATE);
requireThat(trx.getOutputContractStates().isEmpty(), REJECT_OUTPUT_STATE);
requireThat(trx.getInputStates(GameProposalState.class).get(0) != null, REJECT_INPUT_STATE);
break;
trxUtil.getSingleInputState(GameProposalState.class);
break; }
case CANCEL:
requireThat(trx.getInputContractStates().size() == 1, CANCEL_INPUT_STATE);
requireThat(trx.getOutputContractStates().isEmpty(), CANCEL_OUTPUT_STATE);
requireThat(trx.getInputStates(GameProposalState.class).get(0) != null, CANCEL_INPUT_STATE);
trxUtil.getSingleInputState(GameProposalState.class);
break;
default:
@ -60,7 +60,7 @@ public class GameProposalContract implements net.corda.v5.ledger.utxo.Contract {
}
private void requireThat(boolean asserted, String errorMessage) {
if(!asserted) {
if (!asserted) {
throw new CordaRuntimeException("Failed requirement: " + errorMessage);
}
}

View File

@ -5,7 +5,7 @@ import net.corda.v5.crypto.SecureHash;
public class FlowResult {
public final Object successStatus;
public final String transactionId;
public final SecureHash transactionId;
public final String failureStatus;
public FlowResult(Object success) {
@ -16,7 +16,7 @@ public class FlowResult {
public FlowResult(Object success, SecureHash transactionId) {
this.successStatus = success;
this.transactionId = transactionId.toString();
this.transactionId = transactionId;
this.failureStatus = null;
}