IStore
and BlockChain<T>
specification
#2617
Replies: 2 comments
-
DiscussionThe usual warning is that this is heavily biased towards my own opinion. 😗 Based on today's discussion, I think it is apt to ask the following questions:
DiagramsIn below diagrams, subgraphs transactions and blocks correspond to orphaned transactions and orphaned blocks, i.e. not part of a chain. Multiple Network Storageflowchart
subgraph Store
direction BT
subgraph Network 1
direction BT
subgraph Chain 1
direction TB
b1,0 --> b1,1
b1,1 --> b1,2
b1,2 --> b1,3
b1,2 --> b'1,3
b1,3 --> b1,4
end
subgraph Transactions 1
direction LR
to1,1
to1,2
to1,3
end
end
subgraph Network 2
direction BT
subgraph Chain 2
direction TB
b2,0 --> b2,1
b2,1 --> b2,2
b2,2 --> b2,3
b2,2 --> b'2,3
b2,3 --> b2,4
end
subgraph Transactions 2
direction LR
to2,1
to2,2
to2,3
end
end
subgraph Blocks
direction RL
bo1
bo2
bo3
bo4
end
end
Single Network Storageflowchart
subgraph Store
direction BT
subgraph Chain
direction TB
b0 --> b1
b1 --> b2
b2 --> b3
b2 --> b'3
b3 --> b4
end
subgraph Transactions
direction LR
to1
to2
to3
end
subgraph Blocks
direction LR
bo1
bo2
bo3
bo4
end
end
Footnotes
|
Beta Was this translation helpful? Give feedback.
-
Redesign and ConstraintsOn even further thought, seems like the crux of the problem is treating network and/or local "metainfo" the same as other rudimentary entities such as
FormulationStore State
|
Beta Was this translation helpful? Give feedback.
-
As per usual, I blame my lack of writing skills for this seeming like a rant. Also keep in mind, I have absolutely no experience dealing with database. 😗
Case Study
Interface
IStore
suggests, and is also capable of, storing different chain id's and genesis blocks. I understand this is a design decision to keep business logic out ofIStore
as much as possible, but my belief is that this might be a case of too much abstraction.Let's assume
BlockChain<T>
objects and developers responsible for handlingIStore
are diligent enough to have a canonical chain id set forIStore
whenever at least one genesis block (anyBlock<T>
with index 0) is inserted toIStore
1234.When creating a$S$ and genesis $g$ and some chain id $id$ . Consider the following cases:
BlockChain<T>
object, let the constructor take inIStore
Block<T>
BlockChain<T>
is loaded normally.inFork
flag is set totrue
, this simply addsinFork
flag is set tofalse
, then this actually tries to appendBlockChain<T>
normally.inFork
flag is set totrue
, theninFork
flag is set tofalse
, theninFork
flag whether to simply append indexOn top of all this, the end result may also differ depending on whether$S$ had $id_{0}$ set in the first place with $g_{id_{0}}$ or not.
Issues
Perhaps I'm too dumb to be sure to know where to even start untangling this (or maybe I just lack the understanding to see that everything is actually just peachy), but I still see several issues:
IStore
should be a multi-network-chain or not. If the former, then in my opinion, canonical chain ids should be tied to genesis hashes (that is, there should be a dictionary mapping from genesis hashes to canonical chain ids). Arbitrary decision to set canonical chain ids insideBlockChain<T>
's code, notably inBlockChain<T>()
andBlockChain<T>.Swap()
are problematic. This allowsBlockChain<T>
to "hijack" other network's canonical chain id.BlockChain<T>
object depends on too many things.BlockChain<T>
object is that it has a chain id and some genesis block inside anIStore
, possibly newly created or possibly loaded.8 We'd pretty much need a table to explain when and how aBlockChain<T>
object can be created and what it did toIStore
(and/orIStateStore
) with given arguments.IStore
. I have talked a bit on this subject with @longfin, but I'm still on the side of adding some constraints onIStore
methods.IStore
should be managed bySwarm<T>
andBlockChain<T>
. I understand the argument for keeping things abstract and free of constraints for extensibility down the line, but assume nothing and deal with everything cannot be the answer just because "we might need it someday" or "we can't control everything".BlockChain<T>
tries too many different things. On the conceptual level, as a network selection argument,Closing Thoughts and Suggestions
Some thoughts and ideas:
IStore
during load and make sure it satisfies certain properties.IStore
,Swarm<T>
, orBlockChain<T>
level. All have pros and cons.IStore
to make sure none are empty. Although using only provided methods forIStore
interface does not allow this to happen, whether to allow underlying database to have empty chain ids is a different issue.BlockChain<T>
and chain id handling more explicit.BlockChain<T>
only load validBlockChain<T>
creation (creating a brand newBlockChain<T>
using an "empty"IStore
), there is only one place where chain id creation is needed, namelyFork()
.Fork()
method can prepair in advance for the forkedBlockChain<T>
.IStore.GetCanonicalChainId()
to take a genesisBlock<T>
as an argument. This would require some migration. Similarly,IStore.SetCanonicalChainId()
should take a genesisBlock<T>
as an argument. On the other hand,IStore.GetCanonicalGenesisBlock()
should probably be removed.Footnotes
Note that we only assume the canonical chain id to be set if some genesis $g$ is introduced to $S$. This does not assume that $S$ will have $id_{0}$ and $g_{id_{0}}$ by default. ↩
I have no way of actually knowing the intention as this is all handled by business logic, which is only implicitly known by the code for
BlockChain<T>
's constructor. ↩Although seemingly reasonable, at least for me, this is a rather strong assumption, as
IStore
does not signal much intention for its use. ↩This is partly due to the fact
IStore
does not provide a method to unset an already set canonical chain id. ↩The error message currently in
BlockChain<T>
's constructor is not worded properly. Theexception
can be raised simply due to a mismatch between $id$ and $g$ and has nothing to do with "the network's genesis".BlockChain<T>
should not be concerned with whatever network expects. ↩Since there is no data integrity enforcement mechanism and as
BlockChain<T>
has seemingly no opinion about it, it tries to deal with it anyway. In my opinion, this should simply result in failure as existance of $id$ in $S$ without $g$. ↩Then again, we need to consider this case "just in case" because we want to allow "empty" chains. ↩
I still can't confidently say even this seemingly simple fact is true for all possible combinations of arguments after a rather long deliberation. I've probably made atleast a mistake or two laying out the cases. ↩
Sarcastic quote taken from too much abstraction page. ↩
Beta Was this translation helpful? Give feedback.
All reactions