Using the Corda account-based model, can I ascertain whether a transaction signer matches an account persisted on the state? - corda

I am experimenting with Hash Time-Lock Contracts in Corda, using the Corda account-based model. It seems to me that, to transact with an account, you must always obtain an Anonymous Party to serve as its public key, via subflow RequestKeyForAccount. And it seems that you will always obtain a different key each time you RequestKeyForAccount, even for the same account.
Assuming the above statements are correct, I am finding it impossible to implement the contract, as the contract must be able to identify whether the public key invoking it belongs to the "locker" or the "lockee" party. The Anonymous Party will always be different, and will never match either the "locker" or the "lockee," because it will be different every time I invoke RequestKeyForAccount.
I have also tried tackling the problem in a different way, by storing "locker" account and "lockee" account in my persisted state - but, the contract does not have access to the account that is invoking it. It has access to the signers - which are AbstractParties. The account invoking the transaction does not seem obtainable.
Bottom line, I cannot implement a contract that tries to ascertain whether the account invoking it matches a particular account stored within the associated state, due to the random anonymized values returned by RequestKeyForAccount; and due to the inaccessibility of account when all I can access are the signers of the transaction, i.e. AbstractParties. I'd appreciate if somebody can tell me if I am off-base in any of my statements.

Always remember that Accounts in Corda are only logical entities. They do not sign transactions and they do not invoke flows in the cordapp. It's their hosting node that does it on behalf of the accounts they own.
So, as also stated in training.corda.net, if you want to restrict access to certain states to a particular account, you have to manage it outside of Corda (for example, create a RPC user that is linked to an account at application level, with the needed restrictions):
Data access restrictions, i.e. restricting users (i.e. Corda accounts) to interact only with states that they own, is the CorDapp developer's responsibility as implementing them is outside of Corda’s scope.

Related

Microservices without synchronous communication possible?

I know this question was already asked in a lot of ways and flavors, I wanted to add another way and a concrete example.
Basically I know the we should avoid synchronous communication, I was just wondering if there are some patterns to really avoid all of it. Let me give you a short example for a situation in which I wouldn't know how to make it asynchronous:
I have a service that is managing e.g. users, basically a DB that hast users saved and their configuration etc.
Now another service that is the API Gates provides the Endpoint to register the user. And this is the point where the communication becomes a problem: if the register endpoint is called we somehow have to call synchronously the user service because we e.g. need the userId of the newly create user. So this is a very abstract example and needing the userId might not be needed in a lot of cases, but in generell I am curious about this patter:
A services needs to call another service in order to create a new resource but needs some kind of data of the newly created resource either to return it to it's caller or create locally some kind of connection between it's entities and the other services entities.
Is there some pattern for this or is this just a place where synchronous communication needs to happen?
What you are describing is the Orchestration vs Choreography patterns:
In the Orchestration pattern a microservice invokes its dependencies directly, just like in your example, a microservice invokes another to register the user and then uses the userId from the response.
On the other hand, we can have the Choreography pattern where we use need a message queue system, e.g., Kafka, RabbitMq, to decouple the microservices. The same example would work as following:
Your User-Manager microservice will publish an event (command) of type RegisterUser to the message queue, containing the user information.
The API Gates subscribes to the events of type RegisterUser and whenever it gets an event of that type it will create the user normally.
Now, the API Gates must let everyone know that the user was created, so it will publish another event of type UserCreated containing the user information, e.g., the userId.
Finally, the User Manager must also subscribe the UserCreated events, so it can proceed with the flow.
With this approach the two microservices do not know each other, they are decoupled, and you can have any number of dependencies subscribing the events, i.e., you can add new dependencies without needing to change the code.

Can an Anonymous User Access the Blockchain?

Do you have to be a known party on the network to make a transaction?
Can an anonymous user off the network interact with the blockchain?
When joining the network, a node needs to obtain a network certificate provided by the network's doorman. This certificate ties the node to a specific real-world identity. When messaging other nodes, a node must use this certificate to allow the receiving nodes to verify who they are transacting with.
However, suppose a node is working with other nodes to build a transaction. Although the node must reveal its identity to the other nodes they are building the transaction with, it can choose to identify itself in the transaction being built using an anonymous one-time public key, rather than a real-world identity.
This means that the node's identity is not stored on the ledger for all to see, and is only known to the nodes with whom the transaction was originally built.
You can also imagine scenarios where even though the node's identity is well-known, the identity of the actual user is not. For example, a node representing an auction house may place a bid on the behalf of an anonymous user.

In Corda, how can nodes be assigned public roles?

I have written a CorDapp where I want to treat counterparty nodes differently based on their "role".
For example, I may want to check that a counterparty node has the "cash issuer" role before requesting cash issuance from them.
What's the best way to define public node roles in this way?
As of Corda 3, there isn't built-in support for this feature. Support is expected to be added in a future release.
In the meantime, there are several workarounds:
Using an oracle, as Kid101 mentions above. The oracle would store role information that could be queried by nodes
The roles could be retrieved via a HTTP call within the flow - see the Flow HTTP sample
The roles could be stored in the node's database and retrieved within the flow - see the Flow DB sample
Each node could have a flow pair that returns the node's role
The roles could be hardcoded in a configuration file installed on each node - see How to provide a CorDapp with custom config in Corda?
The roles could be hardcoded in the CorDapp's flows

What's the recommended way to handle microservice processing bugs new insights?

Before I get to my question, let me sketch out a sample set of microservices to illustrate my dilemma.
Scenario outline
Suppose I have 4 microservices:
An activation service where features supplied to our customers are (de)activated. A registration service where members can be added and changed. A secured key service that is able to generate secure keys (in a multi step process) for members to be used when communicating with them with the outside world. And a communication service that is used to communicate about our members with external vendors.
The secured key service may however only request secured keys if this is a feature that is activated. Additionally, the communication service may only communicate about members that have a secured key AND if the communication feature itself is activated.
Because they are microservices, each of the services has it's own datastore and is completely self sufficient. That is, any data that is required from the other microservices is duplicated locally and kept in sync by means of asynchronous messages from the other microservices.
The dilemma
I'm actually facing two main dilemma's. The first is (pretty obviously) data synchronization. When there are multiple data stores that need to be kept in sync you have to account for messages getting lost or processed out of order. But there are plenty of out of the box solutions for this and when all fails you could even fall back to some kind of ETL process to keep things in sync.
The main issue I'm facing however is the actions that need to be performed. In the above example the secured key service must perform an action when it either
Receives a message from the registration service for a new member when it already knows that the secured keys feature is active in the activation service
Receives a message from the activation service that the secured keys feature is now active when it already knows about members from the registration service
In both cases this means that a message from the external system must lead to both an update in the local copy of the data as well as some logic that needs to be processed.
The question
Now to the actual question :)
What is the recommended way to cope with either bugs or new insights when it comes to handling those messages? Suppose there is a bug in the message handler from the activation service. The handler does update the internal data structure, but it fails to detect that there are already registered members and thus never starts the secure key generation process. Alternatively it could be that there's no bug, but we decide that there is something else we want the handler to do.
The system will have no reason to resubmit or reprocess messages (as the message didn't fail), but there's no real way for us to re-trigger the behavior that's behind the message.
I hope it's clear what I'm asking (and I do apologize if it should be posted on any of the other 170 Stack... sites, I only really know of StackOverflow)
I don't know what is the recommended way, I know how this is done in DDD and maybe this can help you as DDD and microservices are friends.
What you have is a long-running/multi-step process that involves information from multiple microservices. In DDD this can be implemented using a Saga/Process manager. The Saga maintains a local state by subscribing to events from both the registration service and the activation service. As the events come, the Saga check to see if it has all the information it needs to generate secure keys by submitting a CreateSecureKey command. The events may come in any order and even can be duplicated but this is not a problem as the Saga can compensate for this.
In case of bugs or new features, you could create special scripts or other processes that search for a particular situation and handle it by submitting specific compensating commands, without reprocessing all the past events.
In case of new features you may even have to process old events that now are interesting for your business process. You do this in the same way, by querying the events source for the newly interesting old events and send them to the newly updated Saga. After that import process, you subscribe the Saga to these newly interesting events and the Saga continues to function as usual.

service granularity

What is the best way to manage domain specific services? For eg: In a Financial domain, Should I have a global service "AccountCreation" or "CheckingAccountCreation", "CreditcardAccountreation" etc.
I am struggling whether to keep them at global level or keep them at the product level. what is the best approach?
You should probably focus in the data first: what data is there, and what data needs to stay consistent. Then focus on what the behaviours around that data are.
In a Financial domain, Should I have a global service "AccountCreation" or "CheckingAccountCreation", "CreditcardAccountreation" etc.
In this example, I would say that you have an "account" service, because you clearly have some accounts - and you probably have to ensure that, eg, you don't duplicate account numbers, apply anti-fraud rules, manage the workflow of creation, etc.
Your examples identify some behaviours: create a checking account, create a credit card account. Those would appropriately be commands that you send to the service, because they result in mutation of the data that the service owns.
If you add a "customer" service, though, that would be distinct from the accounts service: it doesn't have to be consistent with the account service, just to have a reference from accounts to customers by ID.
You also generally don't have shared behaviour that touches both parts - updating data about a customer shouldn't touch the details of their accounts (directly), and updating an account doesn't change the details of a customer.
You might have business rules in one service that change another, such as the account service listening for "a customer became a student" announced by the customer service, and then doing some internal processing.

Resources