State management sends the state from the Ethereum chain to the Bor chain. It is called state-sync.
State transfer from Ethereum to Bor happens through system call.
For example, a user deposits USDC to the deposit manager on Ethereum, validators listen to those events and validates and store them in Heimdall state. Bor gets the latest state-sync records and updates the Bor state (mints equal amount of USDC on Bor) using a system call.
To sync state, the contract calls following method state sender contract on Ethereum chain.
receiver contract must be present on the child chain, which receives state
data once the process is complete.
StateSynced event on Ethereum, which is the following:
StateSynced event emitted on the
stateSender contract on the Ethereum chain, Heimdall listens to those events and adds to the Heimdall state after 2/3+ validators agree on the.
After every sprint (currently 64 blocks on Bor), Bor fetches new state-sync record and updates the state using a
system call. Here is the code for the same: https://github.com/maticnetwork/bor/blob/6f0f08daecaebbff44cf18bee558fc3796d41832/consensus/bor/genesis_contracts_client.go#L51
commitState, Bor executes
data as args, on target contract.
State receiver interface on Bor
receiver contract on Bor chain must implement following interface.
StateReceiver.sol, must be allowed to call
onStateReceive function on target contract.
Only system address,
2^160-2, allows making a system call. Bor calls it internally with the system address as
msg.sender. It changes the contract state and updates the state root for a particular block. Inspired from https://github.com/ethereum/EIPs/blob/master/EIPS/eip-210.md and https://wiki.parity.io/Validator-Set#contracts
System call is helpful to change state to contract without making any transaction.
State-sync logs and Bor Block Receipt
Events emitted by system calls are handled in a different way than normal logs. Here is code: https://github.com/maticnetwork/bor/pull/90
Bor produces a new tx/receipt just for the client and includes all logs for state-sync in it. Tx hash is derived from block number and block hash (last block at that sprint):
This doesn't change any consensus logic, only client changes.
eth_getLogs include state-sync logs with derived. Note that the bloom filter on the block doesn't include inclusion for state-sync logs. It also doesn't include derived tx in