private void UpdateBalance(LedgerPostState state, Address address, Currency currency, Amount amount) { var account = state.GetOrCreateMutableAccount(address); var balance = account.GetBalance(currency); Debug.Assert(LiveService.IssuerManager.IsIssuer(currency, address) || balance + amount >= 0); state.SetBalance(account, currency, balance + amount); }
// we finalize the ledger and create a new immutable ledger state private void Finalize(SignedLedger signed, LedgerPostState state) { var ledgerState = state.Finalize(HasherFactory.CreateHasher(signed.GetVersion())); if (!CheckMerkleRoot(ledgerState, signed)) { throw new Exception("Merkle root is not valid"); } LiveService.PersistenceManager.Save(new SignedLedgerState(signed, state.GetLedgerStateChange())); LedgerState = ledgerState; LastLedger = signed; OnNewLedger(LastLedger); }
// we create a new ledger state based on the current state and the new ledger private LedgerPostState CreateLedgerState(SignedLedger signedLedger) { var state = new LedgerPostState(LedgerState, signedLedger.GetHeight()) { AccountCreated = account => LiveService.AccountManager.AddAccount(account.Address, new ExtendedAccount(account)) }; byte index = 0; foreach (var signed in signedLedger.Ledger.Block.Transactions) { // TODO make a better validation // Debug.Assert(signed.Transaction.Expire > signedLedger.Ledger.LedgerLight.BeginTime); Debug.Assert(signedLedger.Ledger.Block.FeeTransactionIndex == index++ || LiveService.TransactionManager.TransactionValidator.ValidateBalance(state, signed.Transaction.GetInputs())); LedgerService.SignedTransactionManager.Execute(state, signed.Transaction); } return(state); }
private void ApplyDeclaration(LedgerPostState state, TxDeclaration declaration) { if (declaration.Type == DeclarationType.MultiSignature) { var multisig = (MultiSignature)declaration; state.DeclareAccount(multisig); } else if (declaration.Type == DeclarationType.HashLock) { var hashLock = (HashLock)declaration; state.DeclareAccount(hashLock); } else if (declaration.Type == DeclarationType.TimeLock) { var timeLock = (TimeLock)declaration; state.DeclareAccount(timeLock); } else if (declaration.Type == DeclarationType.VendingMachine) { var machine = (VendingMachine)declaration; state.DeclareAccount(machine); } }
public void Execute(LedgerPostState state, Transaction transaction) { // TODO declarations foreach (var declaration in transaction.Declarations) { ApplyDeclaration(state, declaration); } // update balances foreach (var input in transaction.Inputs) { UpdateBalance(state, input.Address, input.Currency, -input.Amount); } foreach (var input in transaction.Outputs) { UpdateBalance(state, input.Address, input.Currency, input.Amount); } if (transaction.Fees != null) { UpdateBalance(state, transaction.Fees.Address, transaction.Fees.Currency, -transaction.Fees.Amount); } }
public PostStateHolder(LedgerStateFinal previous, long height) { PostState = new LedgerPostState(previous, height); Injector.Inject(this); }