What warrants an account deletion on the NEAR Protocol - methods

Runtime Specification listed here: https://nomicon.io/RuntimeSpec/Scenarios/FinancialTransaction#transaction-to-receipt states within the verify_and_charge_transaction method, one of the operations is supposedly to:
Checks whether after all these operations account has enough balance
to passively pay for the rent for the next several blocks (an
economical constant defined by Near Protocol). Otherwise account will
be open for an immediate deletion...
Is this referring to an attempt to overspend from an account? Just curious on what warrants an account deletion in this case?

Yes, this is checking that the account does not overspend. The account balance afterwards has to be above the threshold required for storage staking.
The check gets called here, at which point the tokens have already been subtracted locally: https://github.com/near/nearcore/blob/aad3bf2adc1b07df9dd6321d8e1faefbe50afe9c/runtime/runtime/src/verifier.rs#L160-L172
And the source code for the check itself: https://github.com/near/nearcore/blob/aad3bf2adc1b07df9dd6321d8e1faefbe50afe9c/core/primitives/src/runtime/mod.rs#L14-L42
Regarding account deletion, this is a just a hypothetical. If somehow there was not enough balance left to store the account's state, it would have to be deleted immediately. Deletion here means removing all its state from the chain's state. That includes all access keys, hence you would no longer be able to use that account. (You or someone else could claim it again, though.)
But to be very clear, there is no circumstance where this actually happens. Overspending is always prevented and can never lead to an automatic deletion.

Related

Why there is no include link between create and delete use cases

I have seen on the internet many examples of use cases diagrams (in UML) as this one:
What I see is that the delete use case does not include the create use case. Even though I can't imagine deleting a user without creating it.
I wonder why it is still right to not use the include ? And I wonder when should I use it and when to not use it ?
If there is Delete-User - - <<include>> - -> Create-User that means during the execution of the UC Delete-User the UC Create-User is also executed, and of course that has no sense.
The expected behavior can be :
Delete-User has the prerequisite Create-User was successfully executed for the same user and Delete-User was not already executed successfully for the same user (after the last Create-User then)
or Delete-User can be executed without prerequisite but if the user does not exist (Create-User was not executed successfully for the same user, or Delete-User was already executed for the same user after the last creation or the user) this is an error case
Bruno's excellent answer already explains why it's not a good idea to include Create into Delete, and what alternatives may be used to express the relation that you explained between the two use-cases.
But in case it helps, here another angle:
A use-case diagram does not represent a logical sequence of activities.
A use-case only represents a goal for an actor that motivates his/her interaction with the system independently of the other use-cases and the system's history. So, the simple fact that a sysAdmin may want at a moment in time to delete a User is sufficient for the use-case Delete to exist on its own.
include shows that a goal may include some other goals of interest for the user. Inclusion is not for functional decomposition where you'd break down what needs to be done in all the details. It's not either to show the sequential dependency. So for Delete, you shall not include what happens before, because happens-before is sequentiality. Inclusion only highlight some relevant sub-goals that are meaningful for the user and that the user always want to achieve when aiming at the larger goal.
finally, a use-case Delete may have perfect sense even if the use-case Create was never performed by any actor, for example because:
the new system took over a legacy database with all its past account, and the first thing that the SysAdmin will do in the new system, will be to clean-up the already existing old unused accounts before creating new ones.
the SysAdmin wants to Delete an account but finds out only during the interaction that the account didn't exist, was misspelled, or was already deleted. These possibilities are all be alternate flows that you would describe in the narrative of the the same use-case.
or if not Create use-case would be foreseen, because the user creation would be done automatically in the background (e.g. based on an SSO), without the actors being involved at all.

Making sure you don't add same person data twice using EventSourcing

I am wondering how you make sure you are not adding the same person twice in your EventStore?
lets say that on you application you add person data but you want to make sure that the same person name and birthday is not added twice in different streams.
Do you ask you ReadModels or do you do it within your Evenstore?
I am wondering how you make sure you are not adding the same person twice in your EventStore?
The generalized form of the problem that you are trying to solve is set validation.
Step #1 is to push back really hard on the requirement to ensure that the data is always unique - if it doesn't have to be unique always, then you can use a detect and correct approach. See Memories, Guesses, and Apologies by Pat Helland. Roughly translated, you do the best you can with the information you have, and back up if it turns out you have to revert an error.
If a uniqueness violation would expose you to unacceptable risk (for instance, getting sued to bankruptcy because the duplication violated government mandated privacy requirements), then you have to work.
To validate set uniqueness you need to lock the entire set; this lock could be pessimistic or optimistic in implementation. That's relatively straight forward when the entire set is stored in one place (which is to say, under a single lock), but something of a nightmare when the set is distributed (aka multiple databases).
If your set is an aggregate (meaning that the members of the set are being treated as a single whole for purposes of update), then the mechanics of DDD are straightforward. Load the set into memory from the "repository", make changes to the set, persist the changes.
This design is fine with event sourcing where each aggregate has a single stream -- you guard against races by locking "the" stream.
Most people don't want this design, because the members of the set are big, and for most data you need only a tiny slice of that data, so loading/storing the entire set in working memory is wasteful.
So what they do instead is move the responsibility for maintaining the uniqueness property from the domain model to the storage. RDBMS solutions are really good at sets. You define the constraint that maintains the property, and the database ensures that no writes which violate the constraint are permitted.
If your event store is a relational database, you can do the same thing -- the event stream and the table maintaining your set invariant are updated together within the same transaction.
If your event store isn't a relational database? Well, again, you have to look at money -- if the risk is high enough, then you have to discard plumbing that doesn't let you solve the problem with plumbing that does.
In some cases, there is another approach: encoding the information that needs to be unique into the stream identifier. The stream comes to represent "All users named Bob", and then your domain model can make sure that the Bob stream contains at most one active user at a time.
Then you start needing to think about whether the name Bob is stable, and which trade-offs you are willing to make when an unstable name changes.
Names of people is a particularly miserable problem, because none of the things we believe about names are true. So you get all of the usual problems with uniqueness, dialed up to eleven.
If you are going to validate this kind of thing then it should be done in the aggregate itself IMO, and you'd have to use use read models for that like you say. But you end up infrastructure code/dependencies being sent into your aggregates/passed into your methods.
In this case I'd suggest creating a read model of Person.Id, Person.Name, Person.Birthday and then instead of creating a Person directly, create some service which uses the read model table to look up whether or not a row exists and either give you that aggregate back or create a new one and give that back. Then you won't need to validate at all, so long as all Person-creation is done via this service.

Does Hyperledger remove asset actually remove anything?

I'm trying Hyperledger Composer and I'm just wondering what happen when we remove an asset. Is it possible to remove / delete anything from the blockchain?
Or we simply mark an asset as removed, but actually all the transaction records of that asset still exist in the blockchain?
When I removed an asset I still see the block number increasing. So I have a feeling that maybe the asset is not removed (as in deleted from existence) but just marked that the current state is removed.
I have tried to create an asset with the same ID and it works though. I can delete and recreate as many times I want yet block number always increases.
Following the above, is restarting the entire Hyperledger Network (e.g. reloading Docker image from all computers in the network) the only true way of deleting the blockchain from existence?
Thank you in advance.
It sounds like you've got it right. No, data on a blockchain won't ever be deleted. A deletion is just another transaction saying certain data is deleted, so that the world state database (the DB with the non-deleted info) can remove that data.
Since a blockchain is a Merkle Tree in the background (or maybe a Hashgraph...), it plays by those rules and is immutable. Data will always be there unless the ledger and transactions are removed from the machines, such as restarting the network and removing all the information from the peers. That's basically a wipe of every machine that was used for the network structure holding the ledger. For Bitcoin that's everyone, for permissioned blockchains that may only be a few machines and could reasonably happen.
However, that's in theory, and it gets a little complicated with different implementations of a blockchain. It sounds like you're using Hyperledger Fabric, so let's take that as an example. If you're upgrading the Business Network Definition for your network dynamically and your asset definitions changed and won't support existing assets in the registry, are they actually deleted? I'm not sure, but I know they won't show up in a query, which might be effectively the same. Similarly, if you set an ACL rule or use encryption, then a marked asset might as well be deleted, since there will be many barriers (see the docs on Security and Access control) for a random participant to view that data. So depending on how sensitive your data is, it may not really matter.

How to understand the memory protection scheme of IBM/370?

I was confused when I met a problem while reading "Operating System Concepts"(7th edition) which is :
In the IBM/370, memory protection is provided through the use of keys. A key is a 4-bit quantity. Each 2K block of memory has a key (the storage key) associated with it. The CPU also has a key (the protection key) associated with it. A store operation is allowed only if both keys are equal, or if either is zero. Which of the following memory-management schemes could be used successfully with this hardware?
a. Bare machine
b. Single-user system
c. Multiprogramming with a fixed number of processes
d. Multiprogramming with a variable number of processes
e. Paging
f. Segmentation
I have some problems about that: How were such keys calculated? Why it provided another way of "either is zero" while the first way was already seemingly secure?(I mean what is "either is zero" used for and under what circumstance "either is zero" is efficient instead of matching two keys to see if they are the same.)
Disclaimer: this is not an informed answer, just an opinion
The "either is zero" seems to enable scenarios
CPU currently holds the zero protection key so it runs without restrictions in the god/root/kernel mode
memory block guarded by the zero key means that anyone can access it without any bureaucracy, it's covered by "public domain license"
Answer for "how were such keys calculated" by the Operating System would require some archaeology work. Starting point:
IBM Systems Reference Library, IBM System/360 Principles of Operation
Page 17
System Structure → Protection Features
...When the store-protection feature is installed, attempts to modify storage are monitored...
Two instructions - SET STORAGE KEY and INSERT STORAGE KEY - are provided for assigning and inspecting the code in a key. The same code may be used in many keys.
A user's right of access to storage is identified by a four-bit protection key. For references caused by the CPU, the protection key in the current PSW is used; access by channels are controlled by the protection key assigned to the associated I/O operation...
See also:
Wikipedia: IBM System/360
Wikipedia: IBM System/370

Design a share, re-share functionality for a website, avoiding duplication

This is an interesting interview question that I found somewhere. To elaborate more:
You are expected to design classes and data structures for some website such as facebook or linkedin where your activity can be shared and re-shared. Design should be such that it avoids redundancy and duplication.
While thinking of this problem I was stuck on "link vs copy" problem as discussed here
But since the problem states that duplication should be avoided I decided to go "link" way. This makes sharing/re-sharing easier but deleting very difficult. i.e. if the original user deletes their post all the shares should be deleted. (programmatically speaking all the objects on the pointing to the particular activity should be made null. And this is the difficult part here, i.e. to find all the pointing objects)
Wouldn't it be better to keep the shares? The original user deletes
their post, fine, it's gone. But everyone who has linked to it should
not suddenly have it disappear on them.
This could be done the way Unix handles hard links. "Deleting" just
means removing one link to an object -- an inode, in Unix terms. You
don't remove the object itself until the link count is zero.
It's not obvious from the original specification that deletion should work as you describe. It might be desired that when the original user deletes the item, it is not deleted elsewhere; in that case you don't necessarily need to track all references, just keep a reference count on each post, and remove it from the database only when the count hits zero.
If you do want the behavior you describe, it may be achievable by simply removing broken links as and when you encounter them, again relieving you of the need to track each reference. The cost of tracking and updating every reference to every post is replaced with the comparable cost of one failed lookup for each referring page. The latter case is simpler to implement, though, and the cost doesn't hit your server all at once.
In real life, I would implement all references as bidirectional anyway, because it's likely to be needed sooner or later as you add features. For example, a "like" counter seems pretty simple, but to prevent duplicate votes you need to keep track of who has liked each item, and then if you want to remove their "like" when they delete their profile, you need to keep a list of each user's outbound "likes" too.
It takes a lot of database activity to implement something like Facebook...

Resources