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; package com.r3.developers.csdetemplate.utxoexample.states;
import com.r3.developers.csdetemplate.utxoexample.contracts.ChatContract; 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.base.types.MemberX500Name;
import net.corda.v5.ledger.utxo.BelongsToContract; import net.corda.v5.ledger.utxo.BelongsToContract;
import net.corda.v5.ledger.utxo.ContractState; 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) fun updateMessage(messageFrom: MemberX500Name, message: String) = copy(messageFrom = messageFrom, message = message)
} }
*/ */
@CordaSerializable
@BelongsToContract(ChatContract.class) @BelongsToContract(ChatContract.class)
public class ChatState implements ContractState { public class ChatState implements ContractState {
public ChatState() { public ChatState() {
} }
@ConstructorForDeserialization
public ChatState(UUID id, public ChatState(UUID id,
String chatName, String chatName,
MemberX500Name messageFrom, MemberX500Name messageFrom,
@ -81,6 +84,10 @@ public class ChatState implements ContractState {
return message; return message;
} }
public void setMessage(String message) {
this.message = message;
}
@NotNull @NotNull
@Override @Override
public List<PublicKey> getParticipants() { public List<PublicKey> getParticipants() {
@ -91,13 +98,23 @@ public class ChatState implements ContractState {
this.participants = participants; this.participants = participants;
} }
private UUID id; public UUID id;
private String chatName; public String chatName;
private MemberX500Name messageFrom; public MemberX500Name messageFrom;
private String message; public String message;
List<PublicKey> participants; public List<PublicKey> participants;
public ChatState updateMessage(MemberX500Name name, String message) { public ChatState updateMessage(MemberX500Name name, String message) {
return new ChatState(chatName, name, message, participants); 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.InitiatedBy;
import net.corda.v5.application.flows.ResponderFlow; import net.corda.v5.application.flows.ResponderFlow;
import net.corda.v5.application.messaging.FlowSession; 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.annotations.Suspendable;
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.UtxoTransactionValidator;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@ -23,18 +27,36 @@ private final Logger log = LoggerFactory.getLogger(AppendChatResponderFlow.class
@CordaInject @CordaInject
public UtxoLedgerService utxoLedgerService; public UtxoLedgerService utxoLedgerService;
@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 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 @Suspendable
@Override @Override
public void call(@NotNull FlowSession session) { public void call(@NotNull FlowSession session) {
try { try {
UtxoSignedTransaction finalizedSignedTransaction = utxoLedgerService.receiveFinality(session, ledgerTransaction -> TxValidator txValidator = new TxValidator(session);
{
ChatState state = (ChatState) ledgerTransaction.getInputContractStates().get(0); // This is not a problem.
if (checkForBannedWords(state.getMessage()) || !checkMessageFromMatchesCounterparty(state, session.getCounterparty())) { UtxoSignedTransaction finalizedSignedTransaction = utxoLedgerService.receiveFinality(session, txValidator);
throw new IllegalStateException("Failed verification");
}
log.info("Verified the transaction - " + ledgerTransaction.getId());
});
log.info("Finished responder flow - " + finalizedSignedTransaction.getId()); log.info("Finished responder flow - " + finalizedSignedTransaction.getId());
} }
catch(Exception e) 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.flows.*;
import net.corda.v5.application.messaging.FlowMessaging; import net.corda.v5.application.messaging.FlowMessaging;
import net.corda.v5.application.messaging.FlowSession; 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.annotations.Suspendable;
import net.corda.v5.base.types.MemberX500Name; 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.UtxoLedgerService;
import net.corda.v5.ledger.utxo.transaction.UtxoSignedTransaction; import net.corda.v5.ledger.utxo.transaction.UtxoSignedTransaction;
import org.slf4j.Logger; import org.slf4j.Logger;
@ -17,13 +20,12 @@ import java.util.List;
@InitiatingFlow(protocol = "append-chat-protocol") @InitiatingFlow(protocol = "append-chat-protocol")
public class AppendChatSubFlow implements SubFlow<String> { public class AppendChatSubFlow implements SubFlow<String> {
public AppendChatSubFlow() {}
public AppendChatSubFlow(UtxoSignedTransaction signedTransaction, MemberX500Name otherMember) { public AppendChatSubFlow(UtxoSignedTransaction signedTransaction, MemberX500Name otherMember) {
this.signedTransaction = signedTransaction; this.signedTransaction = signedTransaction;
this.otherMember = otherMember; this.otherMember = otherMember;
} }
private final Logger log = LoggerFactory.getLogger(AppendChatSubFlow.class); private final static Logger log = LoggerFactory.getLogger(AppendChatSubFlow.class);
@CordaInject @CordaInject
public UtxoLedgerService ledgerService; public UtxoLedgerService ledgerService;
@ -36,24 +38,46 @@ public class AppendChatSubFlow implements SubFlow<String> {
public String call() { public String call() {
log.info("AppendChatFlow.call() called"); log.info("AppendChatFlow.call() called");
log.info("otherMember = " + otherMember);
FlowSession session = flowMessaging.initiateFlow(otherMember); FlowSession session = flowMessaging.initiateFlow(otherMember);
String retVal; String retVal;
try { try {
List<FlowSession> sessionsList = Arrays.asList(session);
log.info("sessionList.size()=" + sessionsList.size());
UtxoSignedTransaction finalizedSignedTransaction = ledgerService.finalize( UtxoSignedTransaction finalizedSignedTransaction = ledgerService.finalize(
signedTransaction, signedTransaction,
List.of(session) sessionsList
); );
retVal = finalizedSignedTransaction.getId().toString(); retVal = finalizedSignedTransaction.getId().toString();
//retVal = "The returned";
log.info("Success! Response: " + retVal); log.info("Success! Response: " + retVal);
} catch (Exception e) { } catch (Exception e) {
log.warn("Finality failed", e); log.warn("Finality failed", e);
retVal = "Finality failed, " + e.getMessage(); retVal = "Finality failed, " + e.getMessage();
} }
log.info("AppendChatSubFlow call returns=" + retVal);
return retVal; return retVal;
} }
private UtxoSignedTransaction signedTransaction; public UtxoSignedTransaction getSignedTransaction() {
private MemberX500Name otherMember; 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; 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; import java.util.UUID;
@CordaSerializable
public class ChatStateResults { public class ChatStateResults {
public ChatStateResults() {} public ChatStateResults() {}
@ConstructorForDeserialization
public ChatStateResults(UUID id, String chatName, String messageFromName, String message) { public ChatStateResults(UUID id, String chatName, String messageFromName, String message) {
this.id = id; this.id = id;
this.chatName = chatName; this.chatName = chatName;
@ -43,9 +49,9 @@ public class ChatStateResults {
this.message = message; this.message = message;
} }
private UUID id; public UUID id;
private String chatName; public String chatName;
private String messageFromName; public String messageFromName;
private String message; public String message;
} }

View File

@ -75,6 +75,10 @@ public class CreateNewChatFlow implements RPCStartableFlow {
); );
NotaryInfo notary = notaryLookup.getNotaryServices().iterator().next(); 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( Predicate<MemberInfo> myPred = memberInfo -> Objects.equals(
memberInfo.getMemberProvidedContext().get("corda.notary.service.name"), memberInfo.getMemberProvidedContext().get("corda.notary.service.name"),
notary.getName().toString() notary.getName().toString()
@ -84,6 +88,23 @@ public class CreateNewChatFlow implements RPCStartableFlow {
MemberInfo thing = lmi.stream().filter(myPred).iterator().next(); MemberInfo thing = lmi.stream().filter(myPred).iterator().next();
PublicKey notaryKey = thing.getLedgerKeys().get(0); 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() UtxoTransactionBuilder txBuilder = ledgerService.getTransactionBuilder()
.setNotary(new Party(notary.getName(), notaryKey)) .setNotary(new Party(notary.getName(), notaryKey))
.setTimeWindowBetween(Instant.now(), Instant.now().plusMillis(Duration.ofDays(1).toMillis())) .setTimeWindowBetween(Instant.now(), Instant.now().plusMillis(Duration.ofDays(1).toMillis()))
@ -91,9 +112,13 @@ public class CreateNewChatFlow implements RPCStartableFlow {
.addCommand(new ChatContract.Create()) .addCommand(new ChatContract.Create())
.addSignatories(chatState.getParticipants()); .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") @SuppressWarnings("DEPRECATION")
UtxoSignedTransaction signedTransaction = txBuilder.toSignedTransaction(myInfo.getLedgerKeys().get(0)); 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())); return flowEngine.subFlow(new AppendChatSubFlow(signedTransaction, otherMember.getName()));
} }
catch (Exception e) { catch (Exception e) {

View File

@ -1,8 +1,14 @@
package com.r3.developers.csdetemplate.utxoexample.workflows; 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 class CreateNewChatFlowArgs{
public CreateNewChatFlowArgs() {} public CreateNewChatFlowArgs() {}
@ConstructorForDeserialization
public CreateNewChatFlowArgs(String chatName, String message, String otherMember) { public CreateNewChatFlowArgs(String chatName, String message, String otherMember) {
this.chatName = chatName; this.chatName = chatName;
this.message = message; this.message = message;
@ -33,9 +39,7 @@ public class CreateNewChatFlowArgs{
this.otherMember = otherMember; this.otherMember = otherMember;
} }
private String chatName; public String chatName;
private String message; public String message;
public String otherMember;
private String otherMember;
} }

View File

@ -1,10 +1,15 @@
package com.r3.developers.csdetemplate.utxoexample.workflows; 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; import java.util.UUID;
@CordaSerializable
public class GetChatFlowArgs { public class GetChatFlowArgs {
public GetChatFlowArgs() {} public GetChatFlowArgs() {}
@ConstructorForDeserialization
public GetChatFlowArgs(UUID id, int numberOfRecords ) { public GetChatFlowArgs(UUID id, int numberOfRecords ) {
this.id = id; this.id = id;
this.numberOfRecords = numberOfRecords; this.numberOfRecords = numberOfRecords;
@ -27,6 +32,6 @@ public class GetChatFlowArgs {
this.numberOfRecords = numberOfRecords; this.numberOfRecords = numberOfRecords;
} }
private UUID id; public UUID id;
private int numberOfRecords; public int numberOfRecords;
} }

View File

@ -1,7 +1,13 @@
package com.r3.developers.csdetemplate.utxoexample.workflows; 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 class GetChatResponse {
public GetChatResponse() {} public GetChatResponse() {}
@ConstructorForDeserialization
public GetChatResponse(String messageFrom, String message) { public GetChatResponse(String messageFrom, String message) {
this.messageFrom = messageFrom; this.messageFrom = messageFrom;
this.message = message; this.message = message;
@ -23,6 +29,6 @@ public class GetChatResponse {
this.message = message; this.message = message;
} }
private String messageFrom; public String messageFrom;
private String message; public String message;
} }

View File

@ -1,10 +1,14 @@
package com.r3.developers.csdetemplate.utxoexample.workflows; 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 class UpdateChatFlowArgs {
public UpdateChatFlowArgs() {} public UpdateChatFlowArgs() {}
@ConstructorForDeserialization
public UpdateChatFlowArgs(UUID id, String message) { public UpdateChatFlowArgs(UUID id, String message) {
this.id = id; this.id = id;
this.message = message; this.message = message;
@ -26,7 +30,7 @@ public class UpdateChatFlowArgs {
this.message = message; this.message = message;
} }
private UUID id; public UUID id;
private String message; public String message;
} }