# GoShimmer Ledger State Logic overview: Value message attachment/storing: + Value Tangle attach to message Tangle solid event + UTXO attach to Value object solid event + From the solid payload we store the transaction inside the payload via its ID + if new we link the inputs of the tx to the tx ID + store reference of the outputs + if tx is new we store it --- Solidification + we submit it to the solidifier (`solidifyTransactionWorker`) + the tx is solid if either has been marked as solid or if the outputs that belongs to the inputs are solid and then check that the inputs are correctly consuming + balance check + check outputs validity + balance, color check + we sum up the unspent coins and check that the outputs spend all the consumed funds + we set the transaction metadata as solid + if its newly solid we need to book attachment --- **Branch inheritance rules:** A transaction inherits all the branch ids of its consumed inputs, by the following rules: * If there are multiple branches, the transaction either inherits its branch id from the most specialized branch (deepest common decendent) or it creates a new aggregated branch if there is more than one deepest common decendent. **Branch forking rules:** * If a transaction is not conflicting by any of its inputs, it inherits simply the parent branches of all of its inputs. * If the transaction is conflicting it creates a new branch, who's parent is determined by inheriting the branches of all of its inputs. If the transaction is creating a new conflict set for the first time, it also creates a branch for the first transaction which consumes the given shared input. **Booking:** + bookTransaction + we check that we are the first (or successive) consumer of a given input of the transaction. If we are the second consumer of a given input, we need to fork (create two branches, original first spend and second one). If we are the third or later we need to fork by creating only one additional branch for the current transaction. + we potentially aggregate multiple branches to compute our target aggregated branch or just a conflict branch (if it only refs. one parent branch). + if there are conflicts we fork by creating a new branch + we book the transaction and outputs to the target branch + we fork + abort if transaction was already finalized + update/create target branch identified by the conflicting transaction ID + abort if the branch existed already + move transactions to new branch + trigger event and return forked = true + onFork: load tx metadata and branch and if solidificationTime is older than averageNetorkDelay we like (set initial opinion) the first conflicting branch (FCoB rule) + onTransactionBooked: + if the transaction is conflicting we vote otherwise we use the fcob rule --- **Voting** Everytime a conflict set is created or expanded, the given branch of the transaction which created/expanded the conflict set, is automatically voted on. Subsequent transactions besides the first one, are voted on with a `disliked` initial opinion. (`onBookedTransaction()`) If a conflict set emerges and the first transaction is not finalized, then we will vote on it with either an initial `liked` opinion, if it has been unconflicting for more than the adverage network delay (6 seconds) otherwise with an initial `disliked` opinion. (`onForkOfFirstConsumer()`) When a vote is finalized, we set the `preferred state` of a given branch to that finalized opinion. If we set a branch to be not preferred, the un-preferred state propagates to the children of the branch. If a branch is set to be preferred, all other conflicting branches are un-preferred. --- Branch manager unit test: + should not accept a value message attaching on two conflicting value messages + check if branches are conflicting Value Tangle unit tests: + check that value messages are being stored + check that missing messages are being requested and solidified UTXO unit test: + check solidity + check validity (checkTransactionInputs) + checkTransactionOutputs + bookTransaction checks if we are branching off correctly and we are adding the conflicting inputs to the conflict sets (conflictingInputsOfFirstConsumer) + new non conflicting spend = no branch + first double spend = two branches + second or more double spend = new branch + check that `Fork` forks correctly + check that we are moving transactions to target branch correctly (`moveTransactionToBranch`) Other notes: + every balance has a color and a value + an input is a list of balances (check [UTXO spec](https://github.com/hmoog/protocol-rfcs/blob/master/text/0011-utxo-model/0011-utxo-model.md)) + aggregated branch can have multiple entry points ![](https://i.imgur.com/s7GuMAz.png) + moving transaction to branch: + an aggregated branch has multiple entry points + Tip selector + multiple lists of tips for each branch + getBalance is still missing: + you need all the ouputs of that address ## Flags + liked: all of its ancestor until master branch are liked, ==not finalized== + prefered: the first txn you see within conflict set + finalized: clean up all branches, to master branch