Skip to content

Instantly share code, notes, and snippets.

@tgrospic
Last active Sep 30, 2020
Embed
What would you like to do?

Example of block merging

Block DAG

We are creating block B3 with merging blocks B1 and B2. B0 post-state hash is the starting state.

     B3
     / \   
    B1 B2  
     \ /   
     B0    

Block B0

Store
Produce(@1, 42)

Block B1

Store
Produce(@1, 42)
Produce(@2, 0)

We are assuming B0 and B1 with some state in the store (written on disc).

Block B2

B2 contains deploy with some intermediate COMM event and state that is not written to the store. Channel x is consumed immediately which is visible in the event log but not in the store.

for (@y <- @1) {
  new x in {
    x!([1, 2]) |
    for (@[a, b] <- x) { @1!(a + y) }
  }
}
Event log
Consume( hash(@1), hash(new x in x!([1, 2]) ...) )
COMM( Produce(hash(@1), hash(42)), Consume(hash(@1), hash(new x in x!([1, 2]) ...)) )
Produce(hash(@x), hash([1,2]))
Consume(hash(@x), hash(@1!(a + y)))
COMM(Produce(hash(@x), hash([1,2])), Consume(hash(@x), hash(@1!(a + y))) )
Produce( hash(@1), hash(43) )
Store
Produce(@1, 43)

Block B3 - merging B1 and B2

B1 is the main parent. This means we start with the state of B1 and apply event log from B2.

Event log
Only from deploys created in B3
Store
Produce(@2, 0)
Produce(@1, 43)
@zsluedem
Copy link

zsluedem commented Sep 30, 2020

I want to say that from rholang and rspace perspective, no matter which kind of merging situations they should work in both ways ->

  1. B1 is the main parent to merge B2
  2. B2 is the main parent to merge B1

I am not sure what B3 event log looks like. But in rchain/rchain#3150, I think we discuss something about adding the rejectDeploy field in merging block message. We should discuss on this more. We can consider that the merging-block should contain all the non-reject deploy eventlogs in the merging-block pre-state. The eventLogs in B3 should only deploys in B3.

=========================================================

Back to example above.

The event logs in B2 should be

Event log
Consume( hash(@1), hash(new x in x!([1, 2]) ...) )
COMM( Produce(hash(@1), hash(42)), Consume(hash(@1), hash(new x in x!([1, 2]) ...)) )
Produce(hash(@x), hash([1,2]))
Comsume(hash(@x), hash(@1!(a + y)))
COMM(Produce(hash(@x), hash([1,2])), Comsume(hash(@x), hash(@1!(a + y))) )
Produce( hash(@1), hash(43) )

Then B1 applies the changes above.

@tgrospic
Copy link
Author

tgrospic commented Sep 30, 2020

@zsluedem you are correct for B2 event log, it should have or produces and consumes. I updated the example.

I agree. Whatever main parent is chosen B1 or B2, merging should get the same result. Maybe from Casper perspective main parent have different meaning which don't have to be connected to main parent for merging. This would mean separate rules how to choose main parent for merging.

We can consider that the merging-block should contain all the non-reject deploy eventlogs in the merging-block pre-state. The eventLogs in B3 should only deploys in B3.

Applied event log in merge block will not be replayed so it makes sense to be a separate (merged) event log from block's own deploys. as you said for block B3.
But maybe we don't need to store it in the block at all. The question is what operation we need to execute on the store.
It seems that we can annihilate produces and consumes that are part of intermediate COMM events so from the store perspective they don't exist. Other produces/consumes in COMM (not referenced in the event log) should be removed and what's left should be added to the store.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment