WIP commit pre Dan's suggestions

This commit is contained in:
Chris Barratt 2023-01-17 17:52:33 +00:00
parent 3195235b36
commit d475cb19d7
9 changed files with 150 additions and 37 deletions

View File

@ -1,6 +1,8 @@
package com.r3.developers.csdetemplate.utxoexample.states;
import com.r3.developers.csdetemplate.utxoexample.contracts.ChatContract;
import net.corda.v5.base.annotations.ConstructorForDeserialization;
import net.corda.v5.base.annotations.CordaSerializable;
import net.corda.v5.base.types.MemberX500Name;
import net.corda.v5.ledger.utxo.BelongsToContract;
import net.corda.v5.ledger.utxo.ContractState;
@ -20,14 +22,15 @@ data class ChatState(
fun updateMessage(messageFrom: MemberX500Name, message: String) = copy(messageFrom = messageFrom, message = message)
}
*/
@CordaSerializable
@BelongsToContract(ChatContract.class)
public class ChatState implements ContractState {
public ChatState() {
}
@ConstructorForDeserialization
public ChatState(UUID id,
String chatName,
MemberX500Name messageFrom,
@ -81,6 +84,10 @@ public class ChatState implements ContractState {
return message;
}
public void setMessage(String message) {
this.message = message;
}
@NotNull
@Override
public List<PublicKey> getParticipants() {
@ -91,13 +98,23 @@ public class ChatState implements ContractState {
this.participants = participants;
}
private UUID id;
private String chatName;
private MemberX500Name messageFrom;
private String message;
List<PublicKey> participants;
public UUID id;
public String chatName;
public MemberX500Name messageFrom;
public String message;
public List<PublicKey> participants;
public ChatState updateMessage(MemberX500Name name, String message) {
return new ChatState(chatName, name, message, participants);
}
@Override
public String toString() {
return ChatState.class.getName() +
"(id=" + id +
", chatName=" + chatName +
", messageFrom=" + messageFrom +
", participants=" + participants +
")";
}
}

View File

@ -5,9 +5,13 @@ import net.corda.v5.application.flows.CordaInject;
import net.corda.v5.application.flows.InitiatedBy;
import net.corda.v5.application.flows.ResponderFlow;
import net.corda.v5.application.messaging.FlowSession;
import net.corda.v5.base.annotations.ConstructorForDeserialization;
import net.corda.v5.base.annotations.CordaSerializable;
import net.corda.v5.base.annotations.Suspendable;
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.UtxoTransactionValidator;
import org.jetbrains.annotations.NotNull;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -23,18 +27,36 @@ private final Logger log = LoggerFactory.getLogger(AppendChatResponderFlow.class
@CordaInject
public UtxoLedgerService utxoLedgerService;
@Suspendable
@CordaSerializable
static public class TxValidator implements UtxoTransactionValidator {
private final Logger log = LoggerFactory.getLogger(AppendChatResponderFlow.class);
@ConstructorForDeserialization
public TxValidator(FlowSession session) {
this.session = session;
}
@Override
public void call(@NotNull FlowSession session) {
try {
UtxoSignedTransaction finalizedSignedTransaction = utxoLedgerService.receiveFinality(session, ledgerTransaction ->
{
public void checkTransaction(@NotNull UtxoLedgerTransaction ledgerTransaction) {
ChatState state = (ChatState) ledgerTransaction.getInputContractStates().get(0);
if (checkForBannedWords(state.getMessage()) || !checkMessageFromMatchesCounterparty(state, session.getCounterparty())) {
throw new IllegalStateException("Failed verification");
}
log.info("Verified the transaction - " + ledgerTransaction.getId());
});
}
private FlowSession session;
}
@Suspendable
@Override
public void call(@NotNull FlowSession session) {
try {
TxValidator txValidator = new TxValidator(session);
// This is not a problem.
UtxoSignedTransaction finalizedSignedTransaction = utxoLedgerService.receiveFinality(session, txValidator);
log.info("Finished responder flow - " + finalizedSignedTransaction.getId());
}
catch(Exception e)

View File

@ -4,8 +4,11 @@ import com.r3.developers.csdetemplate.utxoexample.states.ChatState;
import net.corda.v5.application.flows.*;
import net.corda.v5.application.messaging.FlowMessaging;
import net.corda.v5.application.messaging.FlowSession;
import net.corda.v5.base.annotations.ConstructorForDeserialization;
import net.corda.v5.base.annotations.CordaSerializable;
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.UtxoLedgerService;
import net.corda.v5.ledger.utxo.transaction.UtxoSignedTransaction;
import org.slf4j.Logger;
@ -17,13 +20,12 @@ import java.util.List;
@InitiatingFlow(protocol = "append-chat-protocol")
public class AppendChatSubFlow implements SubFlow<String> {
public AppendChatSubFlow() {}
public AppendChatSubFlow(UtxoSignedTransaction signedTransaction, MemberX500Name otherMember) {
this.signedTransaction = signedTransaction;
this.otherMember = otherMember;
}
private final Logger log = LoggerFactory.getLogger(AppendChatSubFlow.class);
private final static Logger log = LoggerFactory.getLogger(AppendChatSubFlow.class);
@CordaInject
public UtxoLedgerService ledgerService;
@ -36,24 +38,46 @@ public class AppendChatSubFlow implements SubFlow<String> {
public String call() {
log.info("AppendChatFlow.call() called");
log.info("otherMember = " + otherMember);
FlowSession session = flowMessaging.initiateFlow(otherMember);
String retVal;
try {
List<FlowSession> sessionsList = Arrays.asList(session);
log.info("sessionList.size()=" + sessionsList.size());
UtxoSignedTransaction finalizedSignedTransaction = ledgerService.finalize(
signedTransaction,
List.of(session)
sessionsList
);
retVal = finalizedSignedTransaction.getId().toString();
//retVal = "The returned";
log.info("Success! Response: " + retVal);
} catch (Exception e) {
log.warn("Finality failed", e);
retVal = "Finality failed, " + e.getMessage();
}
log.info("AppendChatSubFlow call returns=" + retVal);
return retVal;
}
private UtxoSignedTransaction signedTransaction;
private MemberX500Name otherMember;
public UtxoSignedTransaction getSignedTransaction() {
return signedTransaction;
}
public void setSignedTransaction(UtxoSignedTransaction signedTransaction) {
this.signedTransaction = signedTransaction;
}
public MemberX500Name getOtherMember() {
return otherMember;
}
public void setOtherMember(MemberX500Name otherMember) {
this.otherMember = otherMember;
}
public UtxoSignedTransaction signedTransaction;
public MemberX500Name otherMember;
}

View File

@ -1,9 +1,15 @@
package com.r3.developers.csdetemplate.utxoexample.workflows;
import net.corda.v5.base.annotations.ConstructorForDeserialization;
import net.corda.v5.base.annotations.CordaSerializable;
import java.util.UUID;
@CordaSerializable
public class ChatStateResults {
public ChatStateResults() {}
@ConstructorForDeserialization
public ChatStateResults(UUID id, String chatName, String messageFromName, String message) {
this.id = id;
this.chatName = chatName;
@ -43,9 +49,9 @@ public class ChatStateResults {
this.message = message;
}
private UUID id;
private String chatName;
private String messageFromName;
private String message;
public UUID id;
public String chatName;
public String messageFromName;
public String message;
}

View File

@ -75,6 +75,10 @@ public class CreateNewChatFlow implements RPCStartableFlow {
);
NotaryInfo notary = notaryLookup.getNotaryServices().iterator().next();
/*
// Lambda have problems see https://r3-cev.atlassian.net/browse/CORE-8983
// Lambda here.
Predicate<MemberInfo> myPred = memberInfo -> Objects.equals(
memberInfo.getMemberProvidedContext().get("corda.notary.service.name"),
notary.getName().toString()
@ -84,6 +88,23 @@ public class CreateNewChatFlow implements RPCStartableFlow {
MemberInfo thing = lmi.stream().filter(myPred).iterator().next();
PublicKey notaryKey = thing.getLedgerKeys().get(0);
*/
PublicKey notaryKey = null;
for(MemberInfo info: memberLookup.lookup()){
if(Objects.equals(info.getMemberProvidedContext().get("corda.notary.service.name"), notary.getName().toString()) ) {
notaryKey = info.getLedgerKeys().get(0);
break;
}
}
if(notary == null) {
throw new NullPointerException("No notary found");
}
log.info("notary.getName()=" + notary.getName());
log.info("chatState = " + chatState);
log.info("chatState.getParticipants().size() = " + chatState.getParticipants().size());
UtxoTransactionBuilder txBuilder = ledgerService.getTransactionBuilder()
.setNotary(new Party(notary.getName(), notaryKey))
.setTimeWindowBetween(Instant.now(), Instant.now().plusMillis(Duration.ofDays(1).toMillis()))
@ -91,9 +112,13 @@ public class CreateNewChatFlow implements RPCStartableFlow {
.addCommand(new ChatContract.Create())
.addSignatories(chatState.getParticipants());
log.info("Before UtxoSignedTransaction signedTransaction = txBuilder.toSignedTransaction(myInfo.getLedgerKeys().get(0));");
log.info("myInfo.getLedgerKeys().size() = " + myInfo.getLedgerKeys().size());
log.info("myInfo.getLedgerKeys().get(0) = " + myInfo.getLedgerKeys().get(0));
@SuppressWarnings("DEPRECATION")
UtxoSignedTransaction signedTransaction = txBuilder.toSignedTransaction(myInfo.getLedgerKeys().get(0));
log.info("After UtxoSignedTransaction signedTransaction = txBuilder.toSignedTransaction(myInfo.getLedgerKeys().get(0));");
return flowEngine.subFlow(new AppendChatSubFlow(signedTransaction, otherMember.getName()));
}
catch (Exception e) {

View File

@ -1,8 +1,14 @@
package com.r3.developers.csdetemplate.utxoexample.workflows;
import net.corda.v5.base.annotations.ConstructorForDeserialization;
import net.corda.v5.base.annotations.CordaSerializable;
@CordaSerializable
public class CreateNewChatFlowArgs{
public CreateNewChatFlowArgs() {}
@ConstructorForDeserialization
public CreateNewChatFlowArgs(String chatName, String message, String otherMember) {
this.chatName = chatName;
this.message = message;
@ -33,9 +39,7 @@ public class CreateNewChatFlowArgs{
this.otherMember = otherMember;
}
private String chatName;
private String message;
private String otherMember;
public String chatName;
public String message;
public String otherMember;
}

View File

@ -1,10 +1,15 @@
package com.r3.developers.csdetemplate.utxoexample.workflows;
import net.corda.v5.base.annotations.ConstructorForDeserialization;
import net.corda.v5.base.annotations.CordaSerializable;
import java.util.UUID;
@CordaSerializable
public class GetChatFlowArgs {
public GetChatFlowArgs() {}
@ConstructorForDeserialization
public GetChatFlowArgs(UUID id, int numberOfRecords ) {
this.id = id;
this.numberOfRecords = numberOfRecords;
@ -27,6 +32,6 @@ public class GetChatFlowArgs {
this.numberOfRecords = numberOfRecords;
}
private UUID id;
private int numberOfRecords;
public UUID id;
public int numberOfRecords;
}

View File

@ -1,7 +1,13 @@
package com.r3.developers.csdetemplate.utxoexample.workflows;
import net.corda.v5.base.annotations.ConstructorForDeserialization;
import net.corda.v5.base.annotations.CordaSerializable;
@CordaSerializable
public class GetChatResponse {
public GetChatResponse() {}
@ConstructorForDeserialization
public GetChatResponse(String messageFrom, String message) {
this.messageFrom = messageFrom;
this.message = message;
@ -23,6 +29,6 @@ public class GetChatResponse {
this.message = message;
}
private String messageFrom;
private String message;
public String messageFrom;
public String message;
}

View File

@ -1,10 +1,14 @@
package com.r3.developers.csdetemplate.utxoexample.workflows;
import java.util.UUID;
import net.corda.v5.base.annotations.ConstructorForDeserialization;
import net.corda.v5.base.annotations.CordaSerializable;
import java.util.UUID;
@CordaSerializable
public class UpdateChatFlowArgs {
public UpdateChatFlowArgs() {}
@ConstructorForDeserialization
public UpdateChatFlowArgs(UUID id, String message) {
this.id = id;
this.message = message;
@ -26,7 +30,7 @@ public class UpdateChatFlowArgs {
this.message = message;
}
private UUID id;
private String message;
public UUID id;
public String message;
}