public static NotificationMessage CreateSignedNewLedgerNotification(SignedLedger ledger) { return(CreateNotification(new API.Notifications.SignedNewLedger { Ledger = ByteStreamConverter.ToBase64 <ByteStream>(stream => { stream.Write(new SignedNewLedger(ledger)); }) })); }
// call from command public void SetNextLedger(SignedLedger signed, Action onFinish) { if (!ValidateSignedLedgerInternal(signed)) { return; } if (!ValidateSignatures(signed)) { return; } try { // wait for other thread LedgerService.State.SetAndWait(LedgerStatus.Updating); // TODO really call from here? SetNextLedger(signed); onFinish.Call(); } finally { // wait for other thread LedgerService.State.SetAndWait(LedgerStatus.Updated); // TODO really call from here? } }
private SignedLedger GetLedger() { var light = new LedgerLight( ledgerService.LedgerManager.GetNextHeight(), DateTime.Now.ToUnixTimestamp() + 1, // TODO ? ledgerService.LedgerManager.GetLedgerBeginTime() + 10, ledgerService.LedgerManager.GetLastLedgerHash(), ProtocolVersion.CURRENT_VERSION); var block = Block.CreateBlock(light.Height, pendingTransactions); var poststate = new PostStateHolder(ledgerService.LedgerManager.LedgerState, ledgerService.LedgerManager.GetNextHeight()); foreach (var transaction in pendingTransactions) { if (!poststate.ProcessTransaction(transaction)) { return(null); } } var finalized = poststate.Finalize(light.Version); var ledger = new Ledger(light, block, ledgerService.LedgerManager.GetMerkleRootHash(finalized, light.Version)); var signed = new SignedLedger(ledger); validator.SignLedger(signed, NodeConfiguration.GetNetwork()); return(signed); }
public static GetSignedLedgerResponse CreateGetSignedLedgerResponse(SignedLedger signed = null) { return(new GetSignedLedgerResponse { Ledger = signed == null ? null : ToBase64 <ByteStream>(stream => { stream.Write(signed); }) }); }
private byte[] GetSignedLedgerBytes(SignedLedger signedLedger) { using (var stream = new ByteStream()) { stream.Write(signedLedger); return(Zipper.Zip(stream.GetBytes())); } }
private void BroadcastNewLedger(SignedLedger signedLedger) { var message = NotificationHelper.CreateSignedNewLedgerNotification(signedLedger); // broadcast the hash of the new ledger with the signature. BlockchainChannel.Broadcast(message); Logger.Log("Broadcast Signed New Ledger"); }
private bool ValidateSignedLedgerInternal(SignedLedger signed) { if (needSetInitialLedger) { return(true); } return(ValidateSignedLedger(signed)); }
public static void SaveLedger(SignedLedger signed, string path) { using (var stream = new ByteStream()) { stream.Write(signed); var bytes = stream.GetBytes(); File.WriteAllBytes(path, bytes); } }
public void Notify(SignedLedger ledger) { foreach (var subscriptor in subscriptors) { foreach (var notification in GetNotifications(subscriptor.Value, ledger)) { Send(subscriptor.Key, new NotificationMessage(notification)); } } }
public void Initialize(SignedLedger lastLedger, bool needToSetInitial) { Injector.Inject(this); needSetInitialLedger = needToSetInitial; var validatorManager = LiveService.ValidatorManager; SignedLedgerValidator = new SignedLedgerValidator(validatorManager.GetValidators(), validatorManager.Quorum, Network); InitializeLedger(lastLedger); }
public void Notify(SignedLedger ledger) { foreach (var subscriptor in subscriptors) { if (!TryUpdateFunds()) { continue; } SendNotification(subscriptor, ledger.Ledger.LedgerLight.Height); } }
private void SetNextLedger(SignedLedger signed) { Debug.Assert(ValidateSignedLedgerInternal(signed)); Debug.Assert(ValidateSignatures(signed)); Finalize(signed, CreateLedgerState(signed)); needSetInitialLedger = false; var time = TimeFormat.ToDateTime(signed.GetTimestamp()); Console.WriteLine($"Ledger Finalized. Height : {signed.Ledger.LedgerLight.Height} Timestamp : {time} Transactions : {signed.Ledger.Block.Transactions.Count()} "); }
public static Internals.Ledger GetLedger(SignedLedger ledger) { if (ledger == null) { return(null); } var light = ledger.Ledger.LedgerLight; var txs = ledger.Ledger.Block.Transactions; var transactions = txs.Select(GetTransactionHeader).ToList(); return(new Internals.Ledger(light.Height, ledger.Hash.ToBase64(), light.Timestamp, light.Lastledger.ToBase64(), light.Version.VersionNumber, ledger.Ledger.Block.FeeTransactionIndex, transactions)); }
public static bool TryReadSignedLedger(GetSignedLedgerResponse response, out SignedLedger signed) { try { signed = LedgerCompressionEngine.ReadZippedLedger(Convert.FromBase64String(response.Ledger)); } catch { signed = null; return(false); } return(true); }
public void Notify(SignedLedger ledger) { foreach (var manager in managers) { try { manager.Notify(ledger); } catch (Exception e) { logger.Log("SubscriptionManager", e); } } }
private SignedLedger CreateSignedLedger() { var account1 = PrivateKeyNotWallet.FromBase64("AKiWI3xivi2tsMz1Sh/v+0WrJaM60t/3h/qcEfu6r1pH"); var block = Block.CreateBlock(1, new List <SignedTransaction> { CreateSignedTransaction() }); var merkle = new LedgerMerkleRoot(new List <Account>(), new List <TxDeclaration>(), new FakeLogger(), new Hasher()).Hash; var ledger = new Ledger(new LedgerLight(1, DateTime.UtcNow.ToUnixTimestamp(), new LedgerHash(Hash256.Zero.Bytes), new ProtocolVersion(0x1)), block, merkle); var signed = new SignedLedger(ledger); var hash = signed.Hash; signed.AddSignature(account1.CreateSignature(hash, Network)); return(signed); }
public void Notify(SignedLedger ledger) { foreach (var subscriptor in subscriptors) { var notification = new LedgerNotification() { Hash = ledger.Hash.ToBase64(), Height = ledger.GetHeight(), Timestamp = ledger.GetTimestamp(), Transactions = ledger.Ledger.Block.Transactions.Count() }; Send(subscriptor, new NotificationMessage(notification)); } }
public void Notify(SignedLedger ledger) { foreach (var subscriptor in subscriptors) { var notification = new ConfirmationNotification() { Hash = ledger.Hash.ToBase64(), Height = ledger.GetHeight(), Timestamp = ledger.GetTimestamp(), Transactions = GetTransactions(subscriptor.Value, ledger) }; Send(subscriptor.Key, new NotificationMessage(notification)); } }
public bool ValidateSignedLedger(SignedLedger signed) { if (signed.Ledger.LedgerLight.Height != GetNextHeight()) { return(false); } if (!signed.Ledger.LedgerLight.Lastledger.Equals(GetLastLedgerHash())) { return(false); } return(true); }
public void ProcessNewLedger(SignedLedger ledger) { var accountsToUpdate = GetChangedAccounts(ledger); var changes = UpdateOrderbook(accountsToUpdate); foreach (var change in changes) { if (change.Value) { TryGetOrderBook(change.Key, out var orderbook); OrderBookUpdated(change.Key, orderbook); } } }
// 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); }
public bool ValidateSignatures(SignedLedger signedLedger) { // TODO check that fee transaction = total fees // TODO is this correct? var status = SignedLedgerValidator.Validate(signedLedger); if (status == LedgerValidationStatus.Ok) { return(true); } logger.Log($"LedgerManager : SignedLedger signature validation Failed! {status}"); return(false); }
public static bool TryReadSignedLedger(GetSignedLedgerResponse response, out SignedLedger signed) { try { using (var stream = new ByteStream(Convert.FromBase64String(response.Ledger))) { signed = stream.ReadSignedLedger(); } } catch { signed = null; return(false); } return(true); }
private TransactionDeclarationContext CreateDeclarationContext(SignedLedger signed, List <TransactionDeclarationEntity> declarations) { var context = new TransactionDeclarationContext(); foreach (var transaction in signed.Ledger.Block.Transactions) { var index = 0; foreach (var declaration in transaction.Transaction.Declarations) { if (!MatchInContext(context, declarations, declaration, transaction.Hash, index++)) { throw new NotImplementedException("It should match"); } } } return(context); }
// 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 Dictionary <Address, Account> GetChangedAccounts(SignedLedger ledger) { var accountsToUpdate = new Dictionary <Address, Account>(); foreach (var transaction in ledger.Ledger.Block.Transactions) { foreach (var input in transaction.Transaction.Inputs) { if (accountsToUpdate.ContainsKey(input.Address)) { continue; } if (LedgerService.LedgerManager.LedgerState.TryGetAccount(input.Address, out var account)) { if (account.Address.Type == AddressType.VendingMachine) { accountsToUpdate.Add(account.Address, account); } } } foreach (var input in transaction.Transaction.Outputs) { if (accountsToUpdate.ContainsKey(input.Address)) { continue; } if (LedgerService.LedgerManager.LedgerState.TryGetAccount(input.Address, out var account)) { if (account.Address.Type == AddressType.VendingMachine) { accountsToUpdate.Add(account.Address, account); } } } } return(accountsToUpdate); }
private void InitializeLedger(SignedLedger lastLedger) { var accounts = new Trie <Account>(Address.RAW_SIZE); foreach (var account in LiveService.AccountManager.GetAccounts()) { accounts.CreateOrUpdate(account.Key.ToRawBytes(), old => { if (old != null) { throw new Exception("The ledger's account states are duplicated !"); } return(account.Value); }); } // TODO compute hash accounts.ComputeHash(HasherFactory.CreateHasher(lastLedger.GetVersion())); LedgerState = new LedgerStateFinal(accounts); LastLedger = lastLedger; // Debug.Assert(SignedLedgerValidator.Validate(this.lastLedger) == LedgerValidationStatus.Ok, "Last Ledger is not valid"); // Most likely not enough signatures (see quorum) }
internal void OnLedgerUpdated(SignedLedger signed) { Console.WriteLine($"Ledger Updated ! Height {signed.Ledger.LedgerLight.Height}"); foreach (var transaction in signed.Ledger.Block.Transactions) { foreach (var input in transaction.Transaction.Inputs) { if (addresses.ContainsKey(input.Address.Encoded)) { WalletUpdated.Call(input); } } foreach (var output in transaction.Transaction.Outputs) { if (addresses.ContainsKey(output.Address.Encoded)) { WalletUpdated.Call(output); } } } }
public static LedgerValidationStatus CheckSignatures(this SignedLedger ledger, LedgerRequiredValidatorsFactory factory, Network network) { var hash = ledger.Hash; // get required signatures var required = factory.GetRequiredValidators(); // verify signatures foreach (var signature in ledger.Signatures) { if (!signature.PublicKey.Verify(hash, signature.SignatureByte, network)) { return(LedgerValidationStatus.InvalidPublicKey); } required.OnValidSignature(signature.PublicKey); } // check required signatures are set if (!required.IsValid()) { return(LedgerValidationStatus.NotEnoughSignatures); } return(LedgerValidationStatus.Ok); }
private List <JSON.API.Internals.Transaction> GetTransactions(SessionSubscriptor subscriptor, SignedLedger ledger) { return(ledger.Ledger.Block.Transactions .Where(transaction => subscriptor.IsSubscribed(transaction, true)) .Select(signed => TransactionConverter.GetTransaction(signed.Transaction)).ToList()); }