Skip to content

Latest commit

 

History

History
2049 lines (1854 loc) · 104 KB

CHANGES.md

File metadata and controls

2049 lines (1854 loc) · 104 KB

Libplanet changelog

Version 0.10.0

Released on October 27, 2020.

Backward-incompatible API changes

  • Extracted rendering methods from IAction to IRenderer<T>, which is introduced in this version. From now on, rendering logic needs to be injected from outside through BlockChain<T>.Renderers, rather than IActions knowing how to render themselves. IRenderer<T> also unified BlockChain<T>.TipChanged event, and introduced new events like IActionRenderer<T>.RenderActionError(), IActionRenderer<T>.RenderBlockEnd(), IRenderer<T>.RenderReorg(), and IRenderer<T>.RenderReorgEnd(). [#860, #875, #959, #963]
    • Removed IAction.Render() method, which was replaced by IActionRenderer<T>.RenderAction().
    • Removed IAction.Unrender() method, which was replaced by IActionRenderer<T>.UnrenderAction().
    • Removed BlockChain<T>.TipChanged event, which was replaced by IRenderer<T>.RenderBlock().
    • Removed PolymorphicAction<T>.Render() and Unrender() methods.
    • Removed BlockChain<T>.TipChangedEventArgs class.
  • Added methods related fungible asset states to IAccountStateDelta: [#861, #900, #954]
    • UpdatedFungibleAssetsAccounts property
    • MintAsset(Address, Currency, BigInteger) method
    • TransferAsset(Address, Address, Currency, BigInteger) method
    • BurnAsset(Address, Currency, BigInteger) method
    • GetBalance(Address, Currency) method
  • Added IAccountStateDelta.StateUpdatedAddresses property in order to distinguish state updates from asset states. [#861, #900]
  • Added an optional parameter AccountBalanceGetter accountBalanceGetter to Block<T>.EvaluateActionsPerTx() method. [#861, #900]
  • BlockChain<T>.StageTransaction() became to throw InvalidTxGenesisHashException when it takes a Transaction<T> from a heterogeneous BlockChain<T> with a different genesis block. [#796, #878]
  • Added renderers optional parameter to BlockChain<T>() constructor. [#883, #959, #963]
  • Added BigInteger-typed totalDifficulty parameter to Block<T>() constructor. [#666, #917]
  • Added BigInteger-typed previousTotalDifficulty parameter to Block<T>.Mine() static method. [#666, #917]
  • Added options optional parameter to Swarm<T>() constructor. [#926]
  • ICryptoBackend became to ICryptoBackend<T>. [#932]
  • ICryptoBackend.Verify(HashDigest<SHA256>, byte[], PublicKey) became to ICryptoBackend<T>.Verify(HashDigest<T>, byte[], PublicKey) [#932]
  • Added ICryptoBackend<T>.Sign(HashDigest<T>, PrivateKey) method. [#932]
  • DefaultCryptoBackend became to DefaultCryptoBackend<T>. [#932]
  • Added ImmutableArray<byte>-typed preEvaluationHash parameter to BlockHeader constructor. [#931, #935]
  • Added HashDigest<SHA256>-typed preEvaluationHash parameter to Block<T>() constructor. [#931, #935]
  • Replaced SerializationInfoExtensions.GetValueOrDefault<T>() to SerializationInfoExtensions.TryGetValue<T>(). [#940]
  • Added bool append = true option to both BlockChain<T>.MineBlock() overloaded methods. Although this breaks ABI-level backward compatibility (i.e., you need to rebuild your assemblies), still is backward-compatible at API-level as the option is turned on by default. [#946]
  • Added int? maxTransactions option to both BlockChain<T>.MineBlock() overloaded methods. Although this breaks ABI-level backward compatibility (i.e., you need to rebuild your assemblies), still is backward-compatible at API-level as the option is turned on by default. [#1037, #1039, #1050]
  • Added StateCompleterSet<T>? stateCompleters option to two BlockChain<T>.Append() overloaded methods. Although this breaks ABI-level backward compatibility (i.e., you need to rebuild your assemblies), still is backward-compatible at API-level as the option has the default value (StateCompleterSet<T>.Recalculate). [#946]
  • Added CancellationToken cancellationToken = default(CancellationToken) option to BlockChain<T>.MineBlock(Address miner) overloaded method. Although this breaks ABI-level backward compatibility (i.e., you need to rebuild your assemblies), still is backward-compatible at API-level as the option has the default value. [#946]
  • Added IImmutableSet<Address> trustedStateValidators = null option to both Swarm<T>.StartAsync() overloaded methods. Although this breaks ABI-level backward compatibility (i.e., you need to rebuild your assemblies), still is backward-compatible at API-level as the option is turned on by default. [#946]
  • Removed Peer.AppProtocolVersion property. [#949]
  • Removed Peer.IsCompatibleWith() method. [#949]
  • Replaced Peer(PublicKey, AppProtocolVersion) constructor with Peer(PublicKey) constructor. [#949]
  • Replaced BoundPeer(PublicKey, DnsEndPoint, AppProtocolVersion) constructor with Peer(PublicKey, DnsEndPoint) constructor. [#949]
  • Extracted IStore's some methods dedicated to block states into IBlockStatesStore. [#950]
    • ListStateKeys() method.
    • ListAllStateReferences() method.
    • LookupStateReference() method.
    • IterateStateReferences() method.
    • StoreStateReference() method.
    • ForkStateReferences() method.
    • GetBlockStates() method.
    • SetBlockStates() method.
    • PruneBlockStates() method.
  • The signature of IStore.LookupStateReference<T>(Guid, string, Block<T>) method was changed to LookupStateReference(Guid, string, long). [#950]
  • Added IStateStore-typed stateStore to BlockChain<T> constructor. [#950]
  • Replaced Swarm<T>.FindSpecificPeerAsync(Address, Address, int, BoundPeer, TimeSpan?, CancellationToken) method with Swarm<T>.FindSpecificPeerAsync(Address, int, TimeSpan?, CancellationToken). [#981]
  • Added IActionContext.GetUnconsumedContext() method. [#980]
  • Added ImmutableArray<byte>-typed stateRootHash parameter to BlockHeader constructor. [#986]
  • Added HashDigest<SHA256>-typed stateRootHash parameter to Block<T>() constructor. [#986]
  • Added IBlockPolicy<T>.MaxTransactionsPerBlock property. [#1037, #1050]
  • Added IBlockPolicy<T>.GetMaxBlockBytes() method. [#201, #1050]
  • IBlockPolicy<T>.DoesTransactionFollowPolicy() method became to take additional BlockChain<T> parameter as its context. [#1012]
  • Methods in BlockPolicy<T> class became virtual. [#1010]
  • Added int maxTransactionsPerBlock option to both BlockPolicy<T>() overloaded constructors. [#1037, #1050]
  • Added int maxBlockBytes and int maxGenesisBytes options to both BlockPolicy<T>() overloaded constructors. [#201, #1050]
  • BlockPolicy<T>() constructor's doesTransactionFollowPolicy parameter became Func<Transaction<T>, BlockChain<T>, bool> on . [#1012]
  • Added cacheSize optional parameter to BlockSet<T>() constructor. [#1013]
  • Removed Address(SerializationInfo, StreamingContext) constructor. [#1022]
  • Removed constructors from InvalidMessageException class. [#1021]

Backward-incompatible network protocol changes

  • The message field RecentStates.StateReferences became to IImmutableDictionary<string, IImmutableList<HashDigest<SHA256>>> from IImmutableDictionary<Address, IImmutableList<HashDigest<SHA256>>>. [#912]
  • The existing RecentStates message type (with the type number 0x0f) was replaced by a new RecentStates message type (with the type number 0x13). [#912]
  • Added BlockHeader.TotalDifficulty property. [#666, #917]
  • The existing Pong message type (with the type number 0x02) was replaced by a new Pong message type (with the type number 0x14). [#459, #919, #920, #930]
  • The TimestampThreshold between Block<T>s was changed from 15 minutes to 15 seconds. [#922, #925]
  • Swarm<T> became to have 5 more message types:
  • Every message now contains app protocol version in its header. [#949]
  • The existing BlockHeaderMessage message type (with the type number 0x0d) was replaced by a new BlockHeaderMessage message type (with the type number 0x0c). [#1003, #1004]
  • Removed PreloadBlockDownloadFailEventArgs class. [#1002]
  • Removed blockDownloadFailed parameter from Swarm<T>.PreloadAsync() method. Use SwarmOptions.BlockDownloadTimeout instead. [#1002]

Backward-incompatible storage format changes

  • Added RawTransaction<T>.GenesisHash property. [#796, #878]
  • Added BlockHeader.TotalDifficulty property. [#666, #917]

Added APIs

  • Added Currency struct. [#861, #900, #954]
  • Added FungibleAssetValue struct. [#861, #944, #954]
  • Added AccountBalanceGetter delegate. [#861, #900, #954]
  • Added TurnClient.BindProxies() method. [#756, #868]
  • Added ActionEvaluation.Exception property. [#860, [#875]]
  • Added InvalidTxGenesisHashException class. [#796, #878]
  • Added InvalidBlockBytesLengthException class. [#201, #1050]
  • Added CurrencyPermissionException class. [#861, #900]
  • Added InsufficientBalanceException class. [#861, #900, #954]
  • Added BlockChain<T>.GetBalance() method. [#861, #900]
  • Added Block<T>.TotalDifficulty property. [#666, #917]
  • Added Block<T>.BytesLength property. [#201, #1050]
  • Added SwarmOptions class. [#926]
  • Added PeerChainState struct. [#936]
  • Added Swarm<T>.GetPeerChainStateAsync() method. [#936]
  • Added Swarm<T>.LastMessageTimestamp property. [#964]
  • Added Block<T>.PreEvaluationHash property. [#931, #935]
  • Added BlockHeader.PreEvaluationHash property. [#931, #935]
  • Added Transaction<T>.BytesLength property. [#201, #1050]
  • Added HashDigest(ImmutableArray<byte>) constructor. [#931, #935]
  • Incomplete block states became able to be handled in more flexible way. [#929, #934, #946, #954]
    • Replaced BlockChain<T>.GetState(Address, HashDigest<SHA256>?, bool) method with GetState(Address, HashDigest<SHA256>?, StateCompleter<T>) method. Specifying completeStates: true and false can be replaced by stateCompleter: StateCompleters<T>.Recalculate and StateCompleters<T>.Reject, respectively.
    • Replaced BlockChain<T>.GetBalance(Address, Currency, HashDigest<SHA256>?, bool) method with GetState(Address, Currency, HashDigest<SHA256>?, StateCompleter<T>) method. Specifying completeStates: true and false can be replaced by stateCompleter: FungibleAssetStateCompleters<T>.Recalculate and FungibleAssetStateCompleters<T>.Reject, respectively.
    • Added StateCompleter<T> delegate.
    • Added FungibleAssetStateCompleter<T> delegate.
    • Added StateCompleterSet<T> struct.
    • Added StateCompleters<T> static class.
    • Added FungibleAssetStateCompleters<T> static class.
    • Added Swarm<T>.GetTrustedStateCompleterAsync() method.
  • Added IRenderer<T> interface. [#959, #963]
  • Added IActionRenderer<T> interface. [#959, #967, #970]
  • Added AnonymousRenderer<T> class. [#959, #963]
  • Added AnonymousActionRenderer<T> interface. [#959, #967, #970]
  • Added DelayedRenderer<T> class. [#980, #1029]
  • Added DelayedActionRenderer<T> class. [#980, #1029]
  • Added LoggedRenderer<T> class. [#959, #963]
  • Added LoggedActionRenderer<T> interface. [#959, #967, #970]
  • Added BlockChain<T>.Renderers property. [#945, #959, #963]
  • Added BlockChain<T>.ActionRenderers property. [#959, #967, #970]
  • Added Swarm<T>.AppProtocolVersion property. [#949]
  • DefaultStore became to implement IBlockStatesStore. [#950]
  • Added IStateStore interface. [#950]
  • Added IBlockStatesStore interface. [#950]
  • Added TrieStateStore class. [#939]
  • Added ITrie interface. [#939, #1023]
  • Added MerkleTrie class. [#939, #1023]
  • Added IKeyValueStore interface. [#939]
  • Added DefaultKeyValueStore class. [#939]
  • Added CacheableKeyValueStore class. [#939]
  • (Libplanet.RocksDBStore) RocksDBStore became to implement IBlockStatesStore. [#950]
  • (Libplanet.RocksDBStore) Added RocksDBKeyValueStore. [#939]
  • Added InvalidBlockStateRootHashException class. [#986]
  • Added Block<T>.StateRootHash property. [#986]
  • Added BlockHeader.StateRootHash property. [#986]
  • Added MerkleTrieExtensions static class. [#1023]
  • Added IAccountStateDelta.PreviousStateRootHash property to calculate states until previous action as state root hash. [#1030]
  • Added UnexpectedlyTerminatedActionException.PreviousStateRootHash property. [#1032]

Behavioral changes

  • Improved performance of Swarm<T>.
    • Multiplexed response and broadcast. [#858, #859]
    • Reduced internal delays. [#871, #879]
  • Transaction<T>.Create(), Transaction<T>.EvaluateActions() and Transaction<T>.EvaluateActionsGradually() no longer throw UnexpectedlyTerminatedActionException directly. Instead, it records an exception to ActionEvaluations. [#860, #875]
  • Added Transaction<T>.GenesisHash property. [#796, #878]
  • Added IAccountStateDelta.UpdatedAddresses property contains asset updates besides state updates. [#861, #900]
  • BlockChain<T>.Append() method became to throw InvalidBlockBytesLengthException if the given block's serialized bytes is longer than the limitation configured by IBlockPolicy.GetMaxBlockBytes(). [#201, #1050]
  • BlockChain<T>.MineBlock() method became to cut off transactions to include to fit into the limitation configured by IBlockPolicy.GetMaxBlockBytes(). [#201, #1050]
  • Swarm<T> became to ignore received transaction with different genesis hash. [#796, #878]
  • Swarm<T> became to ignore invalid BlockHeaders immediately. [#898]
  • Swarm<T>.PreloadAsync() became to clean up only temporary chains. [#902]
  • BlockPolicy<T> became to validate Block<T>.TotalDifficulty property of a Block<T>. [#666, #917]
  • Swarm<T> became to preload from peer that has the most difficult chain. [#459, #919]
  • Swarm<T> became to promote the most difficult chain as a canonical chain instead of the longest chain. [#459, #919]
  • Swarm<T>.BootstrapAsync() method became not to throw TimeoutException when it fails to connect to all neighbors. [#933]
  • Swarm<T> became to respond to the messages with different app protocol version. [#949]
  • Swarm<T>.PreloadAsync() became to execute the actions from the branchpoint rather than the genesis block when there is a branch point. [#991]
  • BlockPolicy<T> became to validate Block<T>.StateRootHash property of a Block<T>. [#986]
  • Swarm<T> became not to sync Block<T>s from the peers with different genesis block. [#1003, #1004]
  • Swarm<T> became to ignore BlockHeaderMessage from the peers with different genesis block. [#1003, #1004]
  • BlockChain<T> instead of BlockPolicy<T> became to validate Block<T>s to append so that even if an empty implementation of IBlockPolicy<T> is used Block<T>s are unable to be appended to BlockChain<T>. [#1010]
  • BlockSet<T>[HashDigest<SHA256>] and BlockChain<T>.Genesis became cached so that they become faster to get. [#1013]
  • Swarm<T>.PreloadAsync() became to do not render blocks. [#1029]

Bug fixes

  • Fixed a bug that Swarm<T> had failed to receive a request from TURN relay connections. [#404, #871, #890]
  • Fixed a bug where Swarm<T> had been terminated and never reconnected when it had been once disconnected from TURN (mostly due to sleep mode, etc.). [#909]
  • Fixed a bug in which pre-computed state delivery had failed when a state key is not an Address when preloading. [#912]
  • Fixed a bug where UnexpectedlyTerminatedException hadn't been serialized with BinaryFormatter. [#913]
  • Fixed a bug where TurnClient hadn't applied cancellation token to its connections. [#916]
  • Fixed a bug where BlockChain<T>.GetRawState() had overwritten block states without read lock. [#927]
  • Fixed a bug that Swarm<T> had not respond to GetRecentStates message when the target block does not exist in the chain. [#941]
  • Fixed a bug that Swarm<T>.StartAsync() had not worked after Swarm<T>.StopAsync() was once called. [#965]
  • Fixed a bug that TurnClient had thrown InvalidOperationException when reconnecting. [#957, #972]
  • Fixed a bug that Swarm<T> had not received block headers after failing to receive previous blocks. [#996]
  • Fixed a bug that Swarm<T> had thrown InvalidGenesisBlockException when reorg its chain repeatedly. [#996]
  • Fixed a bug that Swarm<T> had propagated invalid transactions. [#1043]

Static analyzer

  • Introduced the Libplanet.Analyzers package, a Roslyn Analyzer, which checks if code has common mistakes prone to made with Libplanet-powered game apps, e.g., breaking determinism in IAction implementations. [#1034]

CLI tools

  • The planet command became installable using npm. [#923, #982]
  • Fixed a bug that ^H had not removed the rightmost character in passphrase prompts. [#983, #984]
  • Added a new sub-command planet mpt. [#1023, #1026]
  • Introduced a configuration file. It's placed in: [#1023, #1026]
    • Linux/macOS: $XDG_CONFIG_HOME/planetarium/cli.json
    • Windows: %AppData%\planetarium\cli.json

Version 0.9.5

Released on June 12, 2020.

  • Fixed a bug that had not properly received block hashes after the chain had reorged. [#880, #905]

Version 0.9.4

Released on June 2, 2020.

  • (Libplanet.RocksDBStore) Fixed a bug that RocksDBStore.DeleteChainId() method had thrown KeyNotFoundException when there's no such chain ID. [#891]
  • (Libplanet.RocksDBStore) Fixed a bug that RocksDBStore had written logs into the incorrect context DefaultContext, not RocksDBStore the correct one. [#891]

Version 0.9.3

Released on May 29, 2020.

  • Fixed a Swarm<T>.PreloadAsync() method's bug that had hanged in a state downloading block hashes and finally unexpectedly terminated when a peer's chain had gotten reorged. [#880, #884]

Version 0.9.2

Released on May 20, 2020.

  • (Libplanet.RocksDBStore) Fixed a memory leak bug in RocksDBStore. [#870]

Version 0.9.1

Released on May 7, 2020.

  • Fixed a bug where the canonical chain had changed if any actions had thrown an exception during Swarm<T>.PreloadAsync(). [#862]
  • Fixed a Swarm<T>.PreloadAsync() method's bug that it had hung forever and raised InvalidOperationException. [#847, #864]

Version 0.9.0

Released on April 27, 2020.

Backward-incompatible API changes

  • BaseStore class became to implement IDisposable. [#789]
  • Removed IStore.DeleteIndex(Guid, HashDigest<SHA256>) method. [#802]
  • Extension classes was renamed. However, it would not be affected if you have called it by using instance method syntax. [#803]
    • Renamed StunAddressExtension class to StunAddressExtensions.
    • Renamed BytesConvertExtension class to BytesConvertExtensions.
    • Renamed RandomExtension class to RandomExtensions.
    • Renamed AddressExtension class to AddressExtensions.
    • Renamed HashDigestExtension class to HashDigestExtensions.
    • Renamed NetMQFrameExtension class to NetMQFrameExtensions.
    • Renamed NetMQSocketExtension class to NetMQSocketExtensions.
    • Renamed SerializationInfoExtension class to SerializationInfoExtensions.
    • Renamed StoreExtension class to StoreExtensions.
  • All parameters, fields, property, and method return values that had been represented as an Int32 became retyped to AppProtocolVersion. [#266, #815]
    • Swarm() constructor's parameter appProtocolVersion became AppProtocolVersion (was Int32).
    • Peer() and BoundPeer() constructors' parameter appProtocolVersion became AppProtocolVersion (was Int32).
    • Peer.AppProtocolVersion property became AppProtocolVersion (was Int32).
    • DifferentProtocolVersionEventArgs.ExpectedVersion and DifferentProtocolVersionEventArgs.ActualVersion properties became AppProtocolVersion (was Int32).
    • Removed DifferentAppProtocolVersionException class.
  • Swarm() constructor's EventHandler<DifferentProtocolVersionEventArgs> differentVersionPeerEncountered = null parameter became replaced by DifferentAppProtocolVersionEncountered differentAppProtocolVersionEncountered = null parameter. [#266, #815]
  • Added IEnumerable<PublicKey> trustedAppProtocolVersionSigners = null parameter to Swarm() constructor. [#266, #815]
  • Removed DifferentProtocolVersionEventArgs class. [#266, #815]
  • Removed createdAt parameter from Swarm() constructor. [#838]
  • Replaced BlockChain<T>.StageTransactions() with .StageTransaction() that receives only one transaction. [#820]
  • Replaced BlockChain<T>.UnstageTransactions() with .UnstageTransaction() that receives only one transaction. [#820]
  • Added IBlockPolicy.DoesTransactionFollowPolicy() method which is a method to determine if a transaction follows the block policy. [#827]

Backward-incompatible network protocol changes

  • The existing BlockHashes message type (with the type number 0x05) was replaced by a new BlockHashes message type (with type number 0x0e) in order to include an offset block index besides block hashes so that a receiver is able to determine their block indices too. [#707, #798]
  • Peer became to have 3 more fields to represent the whole fields of AppProtocolVersion, which is newly introduced. [#266, #815]
  • The existing RecentStates message type (with the type number 0x0c) was replaced by a new RecentStates message type (with type number 0x0f) in order to compress its states. [#700, #850]

Added APIs

  • Added AddressExtensions.ToAddress(this PrivateKey) overloaded extension method. [#825]
  • Added BlockHashDownloadState class, a subclass of PreloadState. [#707, #798]
  • Added BlockVerificationState class, a subclass of PreloadState. [#798]
  • Added AppProtocolVersion struct. [#266, #815]
  • Added IKeyStore interface. [#831]
  • Added Web3KeyStore class. [#831]
  • Added BlockDigest struct. [#785]
  • Added BlockHeader struct. [#785]
  • Added IStore.GetBlockDigest(HashDigest<SHA256>) method. [#785]
  • Added Block<T>.ToBlockDigest() method. [#785]
  • Added ByteArrayExtensions class. [#803]
  • Added IStore.PruneBlockStates<T>(Guid, Block<T>) method. [#790]
  • Added DifferentAppProtocolVersionEncountered delegate. [#266, #815]
  • Added Swarm<T>.TrustedAppProtocolVersionSigners property. [#266, #815]
  • Added Peer.IsCompatibleWith() method. [#266, #815]
  • Added TxViolatingBlockPolicyException class. [#827]
  • Added KeyStoreException class. [#831]
  • Added NoKeyException class. [#831]

Behavioral changes

  • BlockChain.MineBlock() method became to ignore transactions having lower nonce than the expected nonce in the chain. [#791]
  • Swarm<T>.PreloadAsync() and Swarm<T>.StartAsync() became to download only a list of block hashes first and then download blocks from simultaneously multiple peers. [#707, #798]
  • Improved performance of Swarm<T> by preventing unnecessary task creation. [#817, #837]
  • Improved performance of Swarm<T>.PreloadAsync() by parallelizing connections. [#846]
  • Improved response throughput of Swarm<T>. [#849]

Bug fixes

  • Swarm<T> became not to sync the same Block<T>s or Transaction<T>s multiple times. [#784]
  • Fixed a Swarm<T>'s bug that had broadcasted a message to its source peer when the number of peers is not enough (less than the minimum number). [#788]
  • Fixed a bug where BlockChain.MineBlock() had produced an invalid block when there is any staged transaction which has lower nonce than the expected nonce, that means, shares an already taken nonce by the same signer. [#791]
  • Fixed a Swarm<T>.PreloadAsync() method's bug that temporary chain IDs in the store had been completely cleaned up in some corner cases if cancellationToken was requested. [#798]
  • Fixed a bug where Swarm<T> had crashed if it received invalid Transaction<T> from the nodes. [#820]
  • Fixed a bug where Swarm<T> hadn't reported IProgress<PreloadState>s correctly.[#839]
  • Fixed a Swarm<T>.PreloadAsync() method's bug that it had hung forever when a block failed to be fetched due to an unexpected inner exception. [#839]
  • Fixed a bug where actions had been evaluated twice when receiving blocks. [#843, #844]
  • Fixed OverflowException being thrown when a passphrase containing any non-ASCII characters was passed to Pbkdf2.Derive() method or ProtectedPrivateKey.Protect() method. [#845]

CLI tools

  • Added the planet command and its alias dotnet planet.

Version 0.8.0

Released on February 4, 2020.

Backward-incompatible API changes

  • The internal representation for state keys became string (was Address). [#368, #774]
    • The return type of IStore.GetBlockStates() method became IImmutableDictionary<string, IValue> (was AddressStateMap, which was removed too). [#368, #774]
    • The type of the second parameter of IStore.SetBlockStates() method became IImmutableDictionary<string, IValue> (was AddressStateMap, which was removed too). [#368, #774]
    • The second parameter of IStore.IterateStateReferences() method became string key (was Address address). [#368, #774]
    • The second parameter of IStore.StoreStateReference() method became IImmutableSet<string> keys (was IImmutableSet<Address> addresses). [#368, #774]
    • IStore.ListAddresses() method was replaced by IStore.ListStateKeys() method. [#368, #774]
  • Added Swarm<T>.FindSpecificPeer() method to find a specific peer given the address. [#570, #580]
  • Removed LiteDBStore class. Use DefaultStore instead. [#662]
  • Removed BlockChain<T>.Contains(TxId) method. Use IStore.ContainsTransaction(TxId) instead. [#676]
  • Renamed BlockChain<T>.Contains(HashDigest<SHA256>) method to BlockChain<T>.ContainsBlock(HashDigest<SHA256>). [#678]
  • Removed BlockChain<T>.Contains(Block<T>) method. [#678]
  • Changed semantics of BlockChain<T>.ContainsBlock(HashDigest<SHA256>) method and BlockChain<T>[HashDigest<SHA256>] indexer as lookups only the current chain, not entire storage. [#678]
  • Added IStore.ContainsBlock(HashDigest<SHA256>) method. [#678]
  • Removed AddressStateMap class. [#98, #368, #692, #774]
    • The return type of BlockChain<T>.GetState() method became IValue (was AddressStateMap).
    • The return type of IStore.GetBlockStates() method became IImmutableDictionary<string, IValue> (was AddressStateMap).
    • IStore.SetBlockStates() method became to take IImmutableDictionary<string, IValue> instead of AddressStateMap.
  • Swarm<T>.PreloadAsync() method and Swarm<T>.StartAsync() method became to take preloadBlockDownloadFailed event handler as an argument. [#694]
  • Added the genesisBlock parameter to BlockChain<T>() constructor. [#688]
  • Removed StateReferenceDownloadState class. [#703]
  • Removed BlockStateDownloadState class. [#703]
  • Removed TxReceived and BlockReceived AsyncAutoResetEvents from Swarm<T>. [#705, #725]
  • Added workers optional parameter into Swarm<T>() constructor. [#613, #727]
  • Block<T> class became not to implement ISerializable. [#751]
  • Transaction<T> class became not to implement ISerializable. [#751]
  • Block<T>.ToBencodex() became to return Bencodex.Types.Dictionary. [#751]
  • Transaction<T>.ToBencodex() became to return Bencodex.Types.Dictionary. [#751]
  • Removed Block<T>.FromBencodex(byte[]) method. [#751]
  • Removed Transaction<T>.FromBencodex(byte[]) method. [#751]
  • Block<T>.ToBencodex() became to take no arguments. [#749, #757]
  • Removed Swarm<T>.BroadcastBlocks(IEnumerable<Block<T>>) method. [#764]
  • StoreExtension.LookupStateReference<T>() method was replaced by IStore.LookupStateReference<T>() method. [#722, #774]

Backward-incompatible network protocol changes

  • Added long-typed offset parameter to RecentStates and GetRecentStates messages. [#703]
  • Added int-typed iteration parameter to RecentStates message. [#703]
  • Added BlockHeaderMessage message. [#764]

Backward-incompatible storage format changes

  • The introduced DefaultStore is incompatible at the file-level with the LiteDBStore which had existed. DefaultStore became to take a directory instead of a single file, and it consists of multiple subdirectories and a LiteDB file for indices. [#662, #680]

Added APIs

  • Added DefaultStore class to replace LiteDBStore. [#662]
  • Added IStore.ListAllStateReferences<T>() method. [#701, #703]
  • Added IStore.ListStateKeys() method to replace IStore.ListAddresses() method. [#368, #774]
  • Added IStore.LookupStateReference<T>() method to replace StoreExtension.LookupStateReference<T>() method. [#368, #722, #774]
  • Added BlockChain<T>.Genesis property. [#688]
  • Added BlockChain<T>.MakeGenesisBlock() static method. [#688]
  • Added InvalidGenesisBlockException class. [#688]
  • Added StateDownloadState class, a subclass of PreloadState, which reports state preloading iteration progress. [#703]
  • Added PeerDiscoveryException class which inherits SwarmException class. [#604, #726]
  • Added Swarm<T>.Peers property which returns an enumerable of peers in Swarm<T>'s routing table. [#739]
  • Added Block<T>.Serialize() method which returns byte[]. [#751]
  • Added Transaction<T>.Serialize() method which returns byte[]. [#751]
  • Added Block<T>(Bencodex.Types.Dictionary) constructor. [#751]
  • Added Transaction<T>(Bencodex.Types.Dictionary) constructor. [#751]
  • Added Block<T>.Deserialize(byte[]) method. [#751]
  • Added Transaction<T>.Deserialize(byte[]) method. [#751]
  • Added StoreExtension.Copy(this IStore, IStore) extension method. [#753]
  • Added a HashDigest<SHA256>?-typed TxHash property which digests all transactions in the block to Block<T> class. [#749, #757]
  • Added CryptoConfig class. [#758]
  • Added ICryptoBackend class. [#758]
  • Added DefaultCryptoBackend class. [#758]
  • Added Swarm<T>.BroadcastBlock(Block<T>) method. [#764]
  • Added Swarm<T>.PeerStates property. [#772]
  • Added PeerState class which represents a Peers state in the routing table. [#772]
  • Added Swarm<T>.CheckAllPeersAsync() method. [#772]

Behavioral changes

  • Swarm<T> became to compare only peer's addresses instead of public keys to determine if a peer is in routing table or not. [#665]
  • When Swarm<T>.PreloadAsync() method fails to download blocks, Swarm<T> became to call preloadBlockDownloadFailed event handler taken as an argument. If the event handler is not present, Swarm<T> throws SwarmException. [#694]
  • Swarm<T>.PreloadAsync() became not to sync state references and block states at once. [#703]
  • Swarm<T> became to print less logs on debug level during sending states. [#706]
  • Increased Swarm<T>'s network timeout value, in order to be stable a high latency internet connection. [#709]
  • Swarm<T>.BootstrapAsync() became to report PeerDiscoveryException instead of SwarmException directly. [#604, #726]
  • BlockChain<T>.Append() became to unstage the staged Transaction<T>s that have lower nonce than the highest nonce of the same signer's transactions in the same chain, since these virtually never become valid. [#721, #728]
  • Swarm<T> became not to fill blocks if received block hashes are continuous. [#732]
  • Swarm<T> became to can process more requests at once by creating TURN relaying proxy concurrently. [#744]
  • Swarm<T> became to throw InvalidGenesisBlockException when receiving block from the nodes that have a different genesis block. [#746]
  • Swarm<T> became to distinguish the starting stages clearly. In other words, Swarm<T>.StartAsync() became not to call Swarm<T>.PreloadAsync(). [#735, #760]
  • The hash of Block<T> has changed due to the change in the method of serialization. [#762]
  • Swarm<T> became to ignore broadcasted block that has lower index than the current tip. [#764]
  • The way Swarm<T> chose peers to spread messages has changed. [#765, #767]
    • If there are less than 10 peers in the routing table, select all peers.
    • If there are more than 10 peers in the routing table, choose one from each bucket, and if the number is less than 10, then select an additional peers so that the total is 10.

Bug fixes

  • Fixed a bug where the canonical chain could be deleted if Swarm<T> failed to download blocks due to network connection. [#675]
  • Fixed bug that re-download block from scratch in preloading. [#685]
  • Fixed a bug where state references become outdated if a chain is forked and then adding existing blocks into it. [#704]
  • Fixed a bug where Swarm<T> had exhausted all available sockets. [#709]
  • Fixed a bug where Swarm<T> had infinitely repeated failed requests. [#709]
  • Fixed a bug where Swarm<T> hadn't stopped properly. [#709]
  • Fixed a bug where Swarm<T>.BootstrapAsync() had stopped due to trivial (recoverable) TimeoutExceptions. [#715, #716]
  • Fixed a bug where BlockChain<T>.GetNextTxNonce() had returned invalid tx nonce. [#718]
  • Fixed a bug where mined transactions were staged again. [#719]
  • Fixed a bug where Block<T>.Hash property, Block<T>.Mine() method, Block<T>.FromBencodex() method, Block<T>.ToBencodex() method, Transaction<T>.Id property, Transaction<T>.Signature property, Transaction<T>.Create() method, Transaction<T>.FromBencodex() method, and Transaction<T>.ToBencodex() method had been non-deterministic on some CultureInfo.CurrentCulture (e.g., ar_SA, fr_FR, th_TH) so that it had caused network protocol incompatibilities. [#734]
  • Fixed a bug where the states became empty between the tip of the peer to receive the states and the tip of the downloaded block. [#736]
  • Fixed a bug where Swarm<T>.StartAsync() had thrown NullReferenceException when host parameter is present on the outside of NAT. [#744]
  • Fixed a bug where Swarm<T> had failed to request a TURN relay when it has an IPv6 address. [#744]
  • Fixed a bug where DefaultStore had invalid state references cache after fork. [#759]
  • Fixed a bug where BlockChain<T> had rendered and evaluated actions in the genesis block during forking. [#763]
  • Fixed a Swam<T>'s bug that some Transaction<T>s had become excluded from mining Block<T>s after reorg from α to β where a Transaction<T> was once included by a Block<T> (α) and not included by an other Block<T> (β) for the same Index due to the latency gap between nodes. [#775]
  • Fixed a bug where TransactionSet and BlockSet has halt whole process when run Trace.Assert(). [#806, #833]

Version 0.7.0

Released on November 8, 2019.

Backward-incompatible interface changes

  • Renamed minValue/maxValue parameters to lowerBound/upperBound of IRandom.Next() methods. [#555, #558]
  • Renamed IStore.IterateIndex() method to IterateIndexes(). [#462, #560]
  • Swarm<T> class became to implement IDisposable again and should be disposed to clean up its internal resources. [#485]
  • IStore.IterateStateReferences() method became to receive highestIndex, lowestIndex, and limit parameters. [#447, #545]
  • Reworked BlockChain<T>.GetStates() into GetState() which takes only one Address instead of IEnumerable<Address>. [#510, #563]
  • Types of IAction.PlainValue and states became restricted to Bencodex.Types.IValue. [#541, #552]
    • IAction.LoadPlainValue(IImmutableDictionary<string, object>) method became replaced by LoadPlainValue(IValue).
    • AccountStateGetter became to return IValue, not object.
    • Added BencodexExtension static class.
  • Removed BlockChain<T>.Blocks. [#409, #583]
  • Removed BlockChain<T>.Transactions. [#409, #583]
  • Removed the linger parameter from the Swarm<T>() constructor, and added the waitFor parameter to Swarm<T>.StopAsync() method instead. [#581]
  • Removed the dialTimeout parameter from the Swarm<T>() constructor, and added it to Swarm<T>.PreloadAsync() & Swarm<T>.StartAsync() methods. [#581]
  • Removed broadcast parameter from BlockChain<T>.MakeTransaction() method. [#609]
  • BlockChain<T> does not implement IReadOnlyList<T> anymore. [#630]
    • Added BlockChain<T>.Count property. [#630]
    • Removed BlockChain<T>.LongCount() method. [#630]
    • Removed BlockChain<T>.Validate() method. [#630]
    • Removed BlockChain<T>.GetEnumerate() method. [#630]
    • Removed BlockPolicyExtension.ValidateBlocks() method. [#630]
    • IBlockPolicy<T>.GetNextBlockDifficulty() method became to receive BlockChain<T> instead of IReadOnlyList<Block<T>>. [#630]
    • IBlockPolicy<T>.ValidateNextBlock() method became to receive BlockChain<T> instead of IReadOnlyList<Block<T>>. [#630]

Added interfaces

  • Added ProtectedPrivateKey class. [#577, #614]
  • Added IncorrectPassphraseException class. [#577, #614]
  • Added MismatchedAddressException class. [#577, #614]
  • Added KeyJsonException abstract class. [#577, #614]
  • Added InvalidKeyJsonException class. [#577, #614]
  • Added UnsupportedKeyJsonException class. [#577, #614]
  • Added ICipher interface. [#577, #614]
  • Added Aes128Ctr class. [#577, #614]
  • Added IKdf interface. [#577, #614]
  • Added Pbkdf2 class. [#577, #614]
  • Added Scrypt class. [#642, #654]
  • Added BlockChain<T>.LongCount() method. [#575]
  • Added BlockChain<T>[HashDigest<T>] indexer. [#409, #583]
  • Added BlockChain<T>.Contains(HashDigest<T>) method. [#409, #583]
  • Added BlockChain<T>.GetTransaction(TxId) method. [#409, #583]
  • Added BlockChain<T>.Contains(TxId) method. [#409, #583]
  • Added ByteUtil.Hex(ImmutableArray<byte>) overloaded method. [#614]
  • Added BlockChain<T>.Contains(Block<T>) method. [#630]
  • Added BlockDownloadState.SourcePeer property. [#636]

Behavioral changes

  • Changed to send Pong before updating the message sender to the routing table when Ping is received. [#566]
  • Improved performance of StoreExtension.LookupStateReference<T>() method. [#447, #545]
  • Added .NET Core 2.2 as a targeted framework. [#209, #561]
  • TurnClient.AcceptRelayedStreamAsync() became to ignore disconnected connections. [#469]
  • Swarm<T>.PreloadAsync() became to ignore peers with lower tip. [#592]
  • Swarm<T> became to validate only stale peers. [#568, #593]
  • Swarm<T> became not to check cached peers immediately after removing peers from its routing table. Instead, it checks cached peers periodically. [#608]
  • Marked Address and HashDigest as readonly. [#610]
  • IceServer.CreateTurnClient() became to throw ArgumentException when received invalid url. [#622]
  • Swarm<T> became to update peer table when receiving messages that are not related with Kademlia protocol. [#594, #627]
  • Swarm<T> became not to check least recently used peer every time when new peer is fetched. [#627]
  • IAction became guaranteed that the given IActionContext.PreviousStates.GetState() never throws IncompleteBlockStatesException. Instead, now it may calculate the incomplete states from the beginning if necessary. [#645]
  • IStore.PutBlock<T>() became to do nothing when it takes the Block<T> more than once. [#647]
  • Swarm<T>.PreloadAsync() became to try downloading blocks from all neighbor peers, even if any peer among them is unavailable to send blocks. [#636]

Bug fixes

  • Fixed a bug where Swarm<T> had tried to update a peer infinitely when the peer is evicted from its table. [#566]
  • Fixed a bug where Swarm<T>.AppendBlocksAsync() re-requests blocks that already received when blockchain is empty. [#550, #562]
  • Fixed a bug that Swarm<T> had thrown SocketException with a message Operation on non-blocking socket would block. [#405, #485]
  • Fixed a bug that accessed all blocks from the genesis block when a swap occurred. [#575]
  • Fixed a bug that Swarm<T> had thrown InvalidBlockIndexException during synchronizing with other reorganized peer. [#528, #576]
  • Fixed a bug where Swarm<T> does not render actions in blocks which are filled from other peers. [#579]
  • Fixed a bug where Swarm<T> renders actions in same block multiple times when reorg happens. [#579]
  • LiteDBStore became to guarantee atomicity of storing blocks. [#584]
  • Fixed a bug that BlockChain<T> had appended a block even if fails to evaluate. [#591]
  • Fixed a bug where Swarm<T> hadn't removed stale peers. [#568, #593, #602]
  • Fixed a bug that TurnClient had thrown IOException when accepting connection through a TURN relay server. [#453, #599]
  • Fixed a bug that KeyNotFoundException occurred when sending a message through the TurnClient.
  • Fixed a bug where BlockChain<T>.GetNextTxNonce only returned the same nonce when transactions with an old nonce were staged. [#637]
  • Fixed a bug that BlockChain<T> had reset when Swarm<T>.PreloadAsync() fails. [#644]
  • Fixed bug that whole processes could halt when received an invalid type of message. [#628, #641]
  • Fixed a bug that received blocks could not be processed if a branch point is a stale block. [#655]

Version 0.6.0

Released on October 1, 2019.

Backward-incompatible interface changes

  • BlockChain<T>.MineBlock() is now async and became to throw OperationCanceledException if BlockChain<T>'s tip index is changed while mining. [#460, #517]
  • Users became able to give a cancellation token to Block<T>.Mine() and Hashcash.Answer() to cancel the operation. [#460, #517]
  • Replaced UnexpectedlyTerminatedTxRehearsalException with UnexpectedlyTerminatedActionException. [#498]
  • The following methods became to throw UnexpectedlyTerminatedActionException with having its InnerException during actions being evaluated if any action of them throws an exception: [#498]
    • Transaction<T>.EvaluateActions()
    • Transaction<T>.EvaluateActionsGradually()
    • Block<T>.EvaluateActionsPerTx()
    • Block<T>.Evaluate()
    • BlockChain<T>.GetStates(completeStates: true)
  • The concept of "namespaces" in IStore was replaced by "chain IDs" to be consistent with BlockChain<T>. [#483, #486]
    • Renamed IStore.ListNamespaces() method to ListChainIds().
    • Renamed IStore.DeleteNamespace() method to DeleteChainId().
    • Renamed IStore.GetCanonicalNamespace() method to GetCanonicalChainId().
    • Renamed IStore.SetCanonicalNamespace(string) method to SetCanonicalChainId(Guid).
    • Replaced namespace/sourceNamespace/destinationNamespace parameters taking string of methods in IStore and StoreExtension with chainId/sourceChainId/destinationChainId taking Guid.
    • Renamed NamespaceNotFoundException to ChainIdNotFoundException.
    • Replaced NamespaceNotFoundException(string, string) constructor with ChainIdNotFoundException(Guid, string) constructor.
    • Replaced NamespaceNotFoundException.Namespace property with ChainIdNotFoundException.ChainId property.
  • IStore.StoreStateReference<T>(string, IImmutableSet<Address>, Block<T>) method became replaced by StoreStateReference(Guid, IImmutableSet<Address>, HashDigest<SHA256>, long) method so that it takes hash and index of a block instead of an entire block. [#420]
  • Added IStore.ForkBlockIndexes() method. [#420]
  • Removed addressesToStrip parameter from IStore.ForkStateReferences<T>() method. [#454, #467, #509, #522]
  • Removed the concept of "staged transactions that should not be broadcasted," because its primary usage had been to make a transaction of a reward action for a candidate for block miner, and the case became achieved through IBlockPolicy<T>.BlockAction property which was introduced at 0.5.0. All staged transactions became broadcasted. [#319, #470]
    • BlockChain<T>.StageTransactions(IDictionary<Transaction<T>, bool>) method became replaced by StageTransactions(IImmutableSet<Transaction<T>>).
    • Removed toBroadcast parameter from IStore.IterateStagedTransactionIds(bool) method.
    • IStore.StageTransactionIds(IDictionary<TxId, bool>) method became replaced by StageTransactionIds(IImmutableSet<TxId>().
  • Removed Swarm<T>.AddPeersAsync() method. To connect with seed peers, use Swarm<T>.BootstrapAsync() method instead. [#353]
  • Peer with endpoints should be typed as BoundPeer which is inherited from Peer. [#353]
  • Removed IActionContext.NewGuid() method. To get a randomly generated Guid, use RandomExtension.GenerateRandomGuid() which implements RFC 4122 instead. [#508]

Added interfaces

  • Added BlockChain<T>.TipChanged event which is invoked with an argument of BlockChain<T>.TipChangedEventArgs when BlockChain<T>.Tip is changed. [#517, #526]
  • Added BlockChain<T>.TipChangedEventArgs class. [#526]
  • Added Swarm<T>.BootstrapAsync() method to connect with seed peers. [#353]
  • Added RandomExtension static class. [#508]
  • TxId class became to implement IComparable<TxId> and IComparable interfaces. [#244, #511]

Behavioral changes

  • Swarm<T> now broadcasts transactions as soon as new transactions are received. [#463, #496]
  • Swarm<T> now ignores block hashes which already exists. [#461, #484]
  • Swarm<T>.PreloadAsync() method became to download precalculated states of blocks from a likely branchpoint instead of a genesis block from a trusted peer (i.e., trustedStateValidators) where there are branches between peers. [#465, #481]
  • Swarm<T>'s internal GetRecentStates message became to take BlockLocator, an internal data type to approximates a path of a chain of blocks for heuristics to search a likely branchpoint, instead of HashDigest<SHA256>. [#465, #481]
  • NetMQ instances are now initialized at Swarm<T>.StartAsync() instead of Swarm<T>(). [#353]
  • Peers now connected via Kademlia protocol. Peers are now selectively connected to each peer. [#353]
  • TxIds and Blocks are now broadcasted to selected peers from routing table of the host peer. [#353]
  • PolymorphicAction<T>.ToString() method became to show the runtime type of its InnerAction for the sake of easier debugging. [#512]
  • The order of Block<T>.Transactions became to be determined by both a Block<T>.Hash and a Transaction<T>.Id, so that signers cannot predict the order of transactions in a block before it's mined. If there are multiple transactions signed by the same signer in a block these transactions become grouped together and the order is determined by a Block<T>.Hash and a fingerprint derived from all these transactions, and transactions in each group (per signer) are ordered by Transaction<T>.Nonce. [#244, #355, #511, #520]
  • LiteDBStore() became to create the database in memory if the path parameter is null. [#521]

Bug fixes

  • Fixed a bug that Swarm<T> hadn't released its TURN related resources on Swarm<T>.StopAsync(). [#450]
  • Fixed a bug that IActionContext.Random had been possible to generated equivalent results between actions of different transactions in a Block<T>. [#519]
  • Fixed a bug where a forked chain would not be deleted when an exception occurred during fetching block from other peers. [#527, #537, #540]

Version 0.5.3

Released on September 9, 2019.

Bug fixes

  • Fix bug where IAccountStateDelta.GetState() hadn't returned proper state when the block action is evaluated. [#500]

Version 0.5.2

Released on August 29, 2019.

Bug fixes

  • Fixed a bug that Swarm<T>.PreloadAsync() method had thrown LiteException (or other exception depending on IStore), which indicates a state reference is duplicate, where trustedStateValidators is present and a miner tries to download precalculated states from a trusted peer. [#465, #474]
  • Fixed a bug tag Swarm<T>.StartAsync() sometimes had thrown an exception from IStore (e.g., NullReferenceException) during broadcasting transactions. [#352, #476]

Version 0.5.1

Released on August 28, 2019.

Bug fixes

  • Fixed a bug that ArgumentNullException had been thrown when a blockchain, which consists of incomplete states (i.e., precalculated states downloaded from trusted peers), encounters a new branch so that reorg is made. [#454, #466]
  • Fixed a bug that unnecessarily received all blocks in multiple miner situations. [#457, #468]

Version 0.5.0

Released on August 22, 2019.

Backward-incompatible interface changes

  • Added IStore.GetBlockIndex() method. [#385]
  • StoreExtension.LookupStateReference<T>() method became to return Tuple<HashDigest<SHA256>, long> which is a nullable tuple of Block<T>.Hash and Block<T>.Index. [#350]
  • Added IBlockPolicy<T>.BlockAction property. [#319, #367]
  • Removed the type parameter of ActionEvaluation. [#319, #367]
  • ActionEvaluation.Action became to IAction type. [#319, #367]
  • LiteDBStore() constructor became to have a new option named flush and turned on by default. [#387, LiteDB #1268]
  • LiteDBStore() constructor became to have a new option named readOnly and turned off by default. [#434]
  • BaseIndex.ContainsKey() method became abstract. [#390]
  • BlockDownloadState.TotalBlockCount and BlockDownloadState.ReceivedBlockCount became to Int64 type. [#396, #399]
  • IStore.IterateIndex() method became to receive offset and limit parameters. [[#425]]
  • Added IStore.GetCanonicalNamespace() method. [#426]
  • Added IStore.SetCanonicalNamespace() method. [#426]
  • Removed IRandom.NextDouble() method, because floating-point arithmetics, which is underspecified, likely introduce indeterminism. [#410, #419]
  • Added IActionContext.NewGuId() method. [#371, #439]
  • Address(byte[]) became to throw ArgumentNullException instead of NullReferenceException. [#443]
  • Removed FileStore class. [#446]

Added interfaces

  • Added trustedStateValidators option to Swarm<T>.PreloadAsync() method. If any peer in this set is reachable and there is no built up blockchain in a current node, Swarm<T> receives the latest states of the major blockchain from that trusted peer, which is also calculated by that peer, instead of autonomously calculating the states from scratch. Note that this option is intended to be exposed to end users through a feasible user interface so that they can decide whom to trust for themselves. [#272, #343]
  • Added StoreExtension.ListAllStateReferences(this IStore, string, HashDigest<SHA256>?, HashDigest<SHA256>?) extension method. [#363, #384, #385]
  • Address class became to implement IComparable<Address> and IComparable interfaces. [#363]
  • Added BlockChain<T>.BlockHashes property. [#389]
  • Swarm<T>.PreloadAsync(IProgress<PreloadState>, IImmutableSet<Address>, CancellationToken) became to report progress for all phases. [#397, #400]
  • Added PreloadState, ActionExecutionState, StateReferenceDownloadState, and BlockStateDownloadState classes to cover all phases in the entire preloading process. [#397, #400]
  • Added Address(ImmutableArray<byte>) constructor. [#442, #443]

Behavioral changes

  • BlockChain<T>.PreloadAsync() method became to omit rendering of IActions in the preloaded behind blocks. [#272, #343]
  • Swarm<T> became to have two more message types: GetRecentStates (0x0b) and RecentStates (0x0c). [#272, #343]
  • BlockChain<T>.MineBlock() and BlockChain<T>.GetNextTxNonce() methods became to ignore transactions that didn't follow Transaction<T>.Nonce sequentially and treat them as pendings. [#365]
  • BlockChain<T> became to evaluate IBlockPolicy<T>.BlockAction and set the state when a block is appended to the chain. [#319, #367]
  • BlockSet<T>.ContainsKey() and TransactionSet<T>.ContainsKey() methods became O(1) time complexity through omitting iteration and relying own retrieve implementations. [#390]
  • The way LiteDBStore stores state references became efficient, but the file-level backward compatibility was also broken. [#395, #398]
  • Swarm<T>.PreloadAsync() method became to report a block downloading progress with the total number of blocks to download in the entire batch, instead of the window size of a chunk (i.e., 500). [#396, #399]
  • Swarm<T>.PreloadAsync() became to get the first parameter, progress, which accepts IProgress<PreloadState>. [#397, #400]
  • BlockHashes messages became to contain one more higher hash. [#408, #445]
  • Swarm<T>.PreloadAsync() became safe from data corruption even if a preloading process suddenly gets shutdown. [#417]
  • FileStore and LiteDBStore became to guarantee atomicity of storing transactions. [#413]
  • IStore.PutTransaction<T>() became to do nothing when it takes the Transaction<T> more than once. [#413]
  • BlockChain<T>.Swap() became to omit common block finding when render is false. [#423]
  • PrivateKey(byte[]) constructor became to check validity. [#438]

Bug fixes

  • Fixed a bug where the LiteDBStore.IterateStagedTransactionIds() returns duplicated transaction ids. [#366]
  • Fixed a bug that NullReferenceException occurred when serializing default Address. [#369]
  • Removed unnecessary mutex in Swarm<T> to avoid continuous delays in peer registration in some situations. [#375]
  • Fixed a bug that TurnClient had thrown KeyNotFoundException and IOException on startup. [#377, #378]
  • Fixed a LiteDBStore bug that blocks or transactions had got corrupted sometimes. Instead, LiteDBStore.GetTransaction() became possible to return null even for already stored transactions, and for that case, a warning will be logged through Serilog. [#386, #387, LiteDB #1268]
  • Fixed a bug that NetworkStreamProxy.StartAsync() hadn't stopped properly when the connection had reset by a remote peer. [#414]
  • Fixed a bug that Swarm<T> had hung forever after a remote peer had disconnected while receiving. [#416]
  • Fixed a bug that Swarm<T>.PreloadAsync() had been processed even if there is no appropriate peer. [#418]
  • Fixed a bug that TURN-related tasks hadn't restarted automatically when an exception occurred. [#422]
  • Fixed a bug that TURN relay connection had disconnected when preloading took a long time. [#424]

Version 0.4.1

Released on July 11, 2019.

Bug fixes

  • Fixed a bug where the BlockChain<T>.GetStates() method had not returned the latest state when there are multiple addresses. [#346]

Version 0.4.0

Released on July 8, 2019.

Backward-incompatible interface changes

  • Peer.AppProtocolVersion became nullable to represent Peer whose version is unknown. [#280]
  • Added IStore.ListAddresses() method. [#272, #285]
  • Added IStore.ListTxNonces() method. [#272, #309, #310]
  • Removed BlockChain<T>.GetNonce() method. [#294]
  • BlockChain<T>.StageTransactions became to receive IDictionary<Transaction<T>, bool> instead of ISet<Transaction<T>>. [#274, #297]
  • IStore.StageTransactionIds() method became to receive IDictionary<TxId, bool> instead of ISet<TxId>. [#274, #297]
  • IStore.IterateStagedTransactionIds() method became to receive bool toBroadcast which is whether to iterate only the TxId set to broadcast. [#274, #297]
  • Swarm<T>.StartAsync() method became to receive broadcastTxInterval (or millisecondsBroadcastTxInterval) parameter. [#274, #297]
  • IStore became to treat a "tx nonce" mere a long integer instead of a stack of block hashes. [#272, #307, #309, #310]
    • IStore.IncreaseTxNonce<T>(string, Block<T>) method was replaced by IStore.IncreaseTxNonce(string, Address, long) method.
    • Removed IStore.ForkTxNonce() method.
    • FileStore became to occupy fewer bytes for storing tx nonces. This change broke file-level backward compatibility.
  • IStore became possible to look up multiple state references in a stack. [#272, #307]
    • Removed IStore.LookupStateReference<T>() method. Instead, a newly added static class StoreExtension provides an extension method of the same name.
    • Added IStore.IterateStateReferences() method.
  • Swarm became to have type parameter T to represent an action type as like as BlockChain<T>. [#324]
  • Swarm<T> constructor became to receive BlockChain<T>. [#324]
  • Methods in Swarm<T> that had taken a parameter of BlockChain<T> type became to neither longer take BlockChain<T> nor a generic method. Because the Swarm<T> constructor takes it instead. [#324]
  • Swarm<T> does not implement ICollection<Peer> anymore. [#326]
  • Added IStore.DeleteNamespace() method. [#329]
  • Removed the id parameter from the BlockChain<T> constructor, and it became to automatically detect an appropriate BlockChain<T>.Id. [#279, #332]

Added interfaces

  • Added LiteDBStore backend that uses LiteDB under the hood. [#269]
  • All *Async() methods belonging to TurnClient class became to have cancellationToken option. [#287]
  • Added a Peer constructor omitting appProtocolVersion parameter to create a Peer whose version is unknown. [#280]
  • Added IncompleteBlockStatesException class. [#272, #285]
  • Added completeStates option to BlockChain<T>.GetStates() method. [#272, #285]
  • Added BlockChain<T>.MakeTransaction(PrivateKey, IEnumerable<T>, IImmutableSet<Address>, DateTimeOffset?) method. [#294]
  • Added BlockChain<T>.GetNextTxNonce() method which counts staged transactions too during nonce computation. [#270, #294]
  • Added StoreExtension static class. [#272, #307]
  • Added Swarm<T>.BlockChain property. [#272, #343]

Behavioral changes

  • BlockChain<T>.GetStates() method became to throw IncompleteBlockStatesException if its Store lacks the states of a block that a requested address lastly updated. [#272, #285]
  • A message Swarm<T> makes became to have multiple blocks within it, which means round trips on the network are now much reduced. [#273, #276]
  • Message.Block has been replaced by Message.Blocks and the magic number has been changed to 0x0a. [#276]
  • Improved performance of Swarm<T>'s response time to GetBlockHashes request messages. [#277]
  • Added IPv6 support to Libplanet.Stun.StunAddress. [#267, #271]
  • IStore.GetBlockStates() became able to return null to represent an absence of states (i.e., incomplete states). [#272, #285]
  • Swarm<T> became to broadcast staged Transactions periodically so that game apps no more need to maintain their own thread to broadcast staged transactions. [#274, #297]
  • Previously, Swarm<T> had sent an empty GetTxs message when it receives an empty TxIds from peers, and it had made the network waste bandwidth for unnecessary messages. Swam<T> became to no more send such empty GetTxs. [#297]
  • BlockChain<T>.Swap() became to delete an index, tx nonces, and state references in the replaced chain. [#329]
  • Reduced the memory footprint of BlockChain<T>.FindBranchPoint() method under the circumstances that the height of the BlockChain<T> object is high. [#282, #299]

Bug fixes

  • Fixed a bug that Swarm<T> reported TaskCanceledException as an unknown exception while stopping. [#275]
  • Fixed a bug that Swarm<T> didn't stop properly during Swarm<T>.PreloadAsync(). [#275]
  • Fixed a bug where the oldest TxNonce of an address is not invalidated when forking using FileStore.ForkTxNonce() method. [#281]
  • Fixed a bug where LiteDBStore.GetTxNonce() method throws a System.IO.IOException after forking. [#281]
  • Fixed a bug that TurnClient had not stopped properly. [#287]
  • Fixed a bug that TurnClient had been trying to use an already closed connection. [#303, #308]
  • Fixed a bug that KeyNotFoundException had been thrown instead of ArgumentOutOfRangeException when Blockchain<T>[int] called while the index of a block that does not exist locally. [#208, #317]
  • Fixed a bug that Swarm<T> had not dial to other peer after Swarm<T>.PreloadAsync(). [#311]
  • Fixed an issue where unknown exceptions occurred when Swarm<T> receiving a message. [#321, #327]

Version 0.3.0

Released on May 31, 2019.

Backward-incompatible interface changes

  • Added IAction.Render(IActionContext, IAccountStateDelta) method. [#31, #212]
  • Added IAction.Unrender(IActionContext, IAccountStateDelta) method. [#31, #212]
  • BlockChain<T>.Validate() method became to receive IReadOnlyList<Block<T>> instead of IEnumerable<Block<T>>. [#205]
  • IBlockPolicy<T>.GetNextBlockDifficulty() method became to receive IReadOnlyList<Block<T>> instead of IEnumerable<Block<T>>. [#205]
  • Added IBlockPolicy<T>.ValidateNextBlock(IReadOnlyList<Block<T>>, Block<T>) method. [#210]
  • Removed IBlockPolicy<T>.ValidateBlocks() method. [#210]
  • BlockChain<T>[int] became to throw ArgumentOutOfRangeException instead of IndexOutOfRangeException. [#210]
  • Removed KeyEquals() methods from all classes and structs. [#216]
  • Swarm class now does not implement IEquatable<Swarm> anymore and its Equals(object) method and GetHashCode() method became to have default behavior of object class. [#216]
  • Also, Swarm class now does not implement IDisposable too. Thus Swarm.Dispose() was removed too. [#218]
  • Swarm became to use a queue to maintain internal messages. [#218]
    • The broadcasting methods are no more async, so they are renamed as below.
      • Swarm.BroadcastBlocksAsync()Swarm.BroadcastBlocks()
      • Swarm.BroadcastTxsAsync()Swarm.BroadcastTxs()
  • The type of Block<T>.Difficulty is changed to long instead of int, and related classes method parameters and field types have changed accordingly.
  • Removed HashDigest.HasLeadingZeroBits() method. [#213]
  • The signature of IStore.PutBlock<T>(Block<T>) method was changed to PutBlock<T>(Block<T>, Address). [#189, #197]
  • Block<T>.Hash is no longer calculated using the full data of the Transaction<T>, but is calculated using only the Transaction<T>.Id. [#234]
  • Added IStore.LookupStateReference<T>(string, Address, Block<T>) method. [#232]
  • Added IStore.StoreStateReference<T>(string, Block<T>) method. [#232]
  • Added IStore.ForkStateReferences<T>(string, string, Block<T>, IImmutableSet<Address> method. [#232]
  • Removed Block<T>.Validate() and Block<T>.EvaluateActions() method. [#243]
  • Added Transaction<T>.Nonce and RawTransaction.Nonce properties. [#246]
  • Added IStore.GetTxNonce(string, Address) method. [#246]
  • Added IStore.IncreaseTxNonce<T>(string, Block<T>) method. [#246]
  • Added IStore.ForkTxNonce<T>(string, string, Block<T>, IImmutableSet<Address> method. [#246]

Added interfaces

  • BlockChain<T> became to implement IReadOnlyList<Block<T>>. [#205]
  • Added Swarm.DifferentVersionPeerEncountered event handler that can handle events when a different version of a peer is discovered. [#167], [#185]
  • Added Peer.AppProtocolVersion property. [#185]
  • Added Swarm.PreloadAsync() method to explicitly and preemptively download initial blocks before Swarm.StartAsync<T>() being called. [#204], [#206]
  • Added BlockDownloadState class to represent a block downloading state. [#204], [#206]
  • Added BlockPolicyExtension.ValidateBlocks<T>(IBlockPolicy<T>, IReadOnlyList<Block<T>>, DateTimeOffset) method. [#210]
  • Added Transaction<T>.EvaluateActionsGradually(HashDigest<SHA256>, long, IAccountStateDelta, Address, bool) method. [#31, #212]
  • Added Block<T>.EvaluateActionsPerTx(AccountStateGetter) method. [#31, #212]
  • Added HashDigest.Satisfies() method. [#213]
  • BlockPolicy<T> constructor became to receive the minimumDifficulty and the mining difficultyBoundDivisor. [#213]
  • Added BlockChain<T>.UnstageTransactions() method. [#223]
  • Swarm constructor became to receive a linger (or millisecondsLinger) parameter. This purposes to determine how long to wait for pending messages when a Swarm instance is requested to terminate.
  • Added NamespaceNotFoundException class. [#232]
  • Added Block<T>.Evaluate() method. [#243]
  • Made InvalidBlockTimestampException class public so that it can be caught. [#133, #251]
  • Added InvalidTxNonceException class. [#246]

Behavioral changes

  • Swarm.StartAsync() now receives the height of blocks (tip Index) from other known peers and synchronizes the blocks if necessary before propagating/receiving pinpointed recent blocks to prevent inefficient round-trips. [#187, #190]
  • The calculation algorithm of BlockPolicy<T>.GetNextBlockDifficulty() method was changed to the Ethereum Homestead algorithm except for the difficulty bomb. [#213]
  • The difficulty was changed from representing the number of leading zeros of target number to representing a divisor to obtain the target number. [#213]
  • BlockSet<T>[int] changed so as not to validate a block. [#231]
  • Improved read performance of Block<T>.Hash and Transaction<T>.Id. [#228, #234]
  • Swarm.StartAsync() now does not call Swarm.StopAsync() anymore, therefore Swarm.StopAsync() should be explicitly called. [#236]
  • Transaction<T>.EvaluateActionsGradually() became to record IAccountStateDelta.SetState() calls even if its argument is the same to the previous state. [#241]
  • Block<T>.Validate() and Block<T>.EvaluateActions() are integrated into Block<T>.Evaluate(). [#243]
  • BlockChain<T>.Append() became to execute Action.Execute() only once per action in the Block<T>. [#243]
  • BlockChain<T>.Append() method became to throw InvalidTxNonceException when the Transaction<T>.Nonce does not correspond to its Signer's current nonce. [#246]
  • Swarm became to enforce ForceDotNet.Force() in AsyncIO while it's running on Mono runtime. [#247]

Bug fixes

  • Fixed a bug that TURN relay had been disconnected when being connected for longer than 5 minutes. [#198]
  • Fixed a bug that Swarm had attempted to use TURN relay even if the host argument was given. [#198]
  • Improved the read throughput of BlockChain<T>.Append().
  • Improved overall read throughput of BlockChain<T> while blocks are being mined by BlockChain<T>.MineBlock(). [#191]
  • Fixed a bug that TurnClientException had been thrown by Swarm when a STUN nonce is stale. [#193]
  • Fixed BlockChain<T>.GetStates() had descended to the bottom (i.e., the genesis block) where a given Address refers to a nonexistent account (i.e., never used before). [#189, #192]
  • Fixed a bug that a TURN connection had turned unavailable after it once failed to parse a message (due to a corrupted packet). [#215]
  • Instead of validating the entire blocks, BlockChain<T>.Append() method became to validate only the next block to be appended. [#210]
  • Improved BlockChain<T>.Fork() performance by avoiding double validation of already validated blocks. [#215]
  • Removed unnecessary writer locks on BlockChain<T>.StageTransactions(). [#217]
  • Improved concurrency of BlockChain<T>.Append() method by removing unnecessary race conditions. [#217]
  • Fixed a bug that Swarm could not properly communicate with Peer behind NAT. [#240]
  • Fixed a bug that BlockChain<T>.FindNextHashes() throws ArgumentOutOfRangeException when chain is empty.
  • Fixed a bug that TurnClient.AcceptRelayedStreamAsync()didn't handle concurrent connections correctly. [#256]

Version 0.2.2

Released on April 12, 2019.

  • Fixed a bug that BlockChain<T>.GetStates() had returned slower than necessary for many addresses. [#189, #192]

Version 0.2.1

Released on April 7, 2019.

This version purposes to entirely replace 0.2.0, because a wrong .nupkg file was uploaded to 0.2.0 on NuGet Gallery. Note that 0.2.0 on NuGet Gallery was unlisted.

Version 0.2.0

Released on April 5, 2019.

  • PrivateKey.Decrypt() now throws an InvalidCiphertextException instead of returning null when cipherText is invalid. [#140]

  • Transaction<T>'s SenderRecipient model was replaced by SignerUpdatedAddresses model. Unlike cryptocurrencies, transactions in games are not necessarily a transfer of assets, so it is difficult to determine what type of assert is transferred or who will receives the asset. A more useful perspective is, like what kind of transformation is performed, or what states are changed. To be close to this perspective, we decided to get rid of Transaction<T>.Recipient (which is singular) and have Transaction<T>.UpdatedAddresses (which is plural) instead. As there is no more asset to transfer, the term Sender was also renamed to Signer, which fits more to the new perspective. [#121]

    • Renamed Transaction<T>.Sender, RawTransaction.Signer, and IActionContext.From properties to Signer. The corresponding parameter names on constructors and methods were also renamed too.
    • Old Transaction<T>.Make() factory method is replaced by new Transaction<T>.Create() factory method. The timestamp parameter became optional, and the new optional updatedAddresses parameter was added.
    • Removed IActionContext.To property.
    • Transaction<T>.Recipient and RawTransaction.Recipient properties were replaced by Transaction<T>.UpdatedAddresses and RawTransaction.UpdatedAddresses properties. The corresponding parameter names on constructors and methods were replaced too.
    • Since the schema of RawTransaction class was changed, the serialization format of transactions and blocks were also changed. It affects to the way to generate Transaction<T>.Signature, Transaction<T>.Id, and Block.Hash values as well.
    • Added InvalidTxUpdatedAddressesException exception class.
    • A nullary overload of Block<T>.Validate() method was gone so that the block validation API is always time-wise. Instead, Block<T>.Validate() method now has only one overload: Validate(DateTimeOffset, AccountStateGetter) returning IAccountStateDelta.
    • Block<T>.Validate() and BlockChain<T>.Validate() methods now can throw an InvalidTxUpdateAddressesException.
  • The Addresses IAction tries to update no more need to be manually coded using IAction.RequestStates() method. That method was removed at all, and updated Addresses became automatically determined (for the most cases) by track "dirties" on rehearsal mode. This mode dry-runs IActions with empty IActionContext.PreviousStates. [#121]

    • Added AccountStateGetter delegate to provide a read-only view to account states.
    • Added IAccountStateDelta interface to replace AddressStateMap. The interface purposes to provide a read-write view to account states with maintaining UpdatedAddresses (so-called "dirty"). [#98]
    • The type of IActionContext.PreviousStates property was changed from AddressStateMap to IAccountStateDelta.
    • Added IActionContext.Rehearsal property. [#131, #135]
    • Added UnexpectedlyTerminatedTxRehearsalException class. [#132, #136]
    • The return type of IAction.Execute() method was changed from AddressStateMap to IAccountStateDelta.
    • Removed IAction.RequestStates() method because there is no need for it and thus it is not used anymore.
    • Added Transaction<T>.EvaluateActions() method.
    • Added Block<T>.EvaluateActions() generator method.
  • The built-in subtype polymorphism of IAction and Transaction<T> was moved to a separated new PolymorphicAction<T> abstract class. Polymorphic actions now should be wrapped by PolymorphicAction<T>. For example, the following code:

    public abstract class AbstractAction : IAction { ... }
    
    [ActionType("attack")]
    public sealed class Attack : AbstractAction { ... }
    
    [ActionType("sleep")]
    public sealed class Sleep : AbstractAction { ... }
    var tx = Transaction<AbstractAction>.Create(
        ...,
        actions: new[] { new Attack(...), ... }
    );

    should be changed to like:

    var tx = Transaction<PolymorphicAction<AbstractAction>>.Create(
        ...,
        actions: new[] {
            new PolymorphicAction<AbstractAction>(new Attack(...)),
            ...
        }
    );

    It can be simpler by implicit casting:

    var tx = Transaction<PolymorphicAction<AbstractAction>>.Create(
        ...,
        actions: new PolymorphicAction<AbstractAction>[] { new Attack(...), }
    );

    [#169]

    • The type parameter T of Transaction<T>, Block<T>, and BlockChain<T> became to require having a public parameterless constructor (i.e., new()) besides implementing IAction interface. This means an abstract class or an interface no more can be passed to T, but only a concrete class or a struct can be passed.
  • Fixed a bug that mutating a collection of IActions passed to constructors or factory methods of Transaction<T> had affected made instances as well. The type of Transaction<T>.Actions property was changed from IList<T> to IImmutableList<T>. The corresponding parameters on constructors and factory methods also were changed to take IEnumerable<T> instead of IList<T>.

  • Address and TxId are now serializable. [#99, #124 by Qria]

  • InvalidTxException and its subclasses became to have TxId property and the corresponding constructor parameter. This can be useful when multiple Transaction<T> objects are validated at once.

  • Added Address.Size constant, which is fixed to the Int32 20.

  • Fixed a bug that Block<T>.Validate() had not thrown InvalidTxException even if there is any integrity error on its Transactions.

  • Improved the write throughput of BlockChain<T> while polling BlockChain<T>.GetStates()

  • Swarm.AddPeersAsync() was fixed so that unreachable Peers are ignored. [#128]

  • Swarm became able to relay their connection via TURN (RFC 5766) to NAT traversal. To enable this, its constructor (Swarm()) takes the newly added IceServers as configuration.

  • Since we decided to depend on TURN (RFC 5766) and STUN (RFC 5389) to work around NAT so that Peer's endpoints don't have to be multiple, Peer.Urls was renamed to Peer.EndPoint and its type also was changed from IImmutableList<Uri> to DnsEndPoint. [#120, #123 by Yang Chun Ung, #126, #127, #165, #166]

  • Swarm became to ignore tip blocks of the same height (Index) that it already has and deal with only longer (higher) blocks.

  • Fixed a bug that occurred when Swarm was handling multiple responses at the same time.

  • Fixed a bug that the Swarm constructor had hanged in certain runtimes like Unity engine.

  • Removed AddressTransactionSet which handles handle Address to IEnumerable<TxId> indices, and the following methods in IStore:

    • IStore.IterateAddresses()
    • IStore.GetAddressTransactionIds()
    • IStore.AppendAddressTransactionId()
    • IStore.CountAddresses()
  • Added IStore.ListNamespaces() method.

  • IStore.CountBlocks() and IStore.CountTransactions() became to return long.

  • Block/tx-related methods in IStore and BaseIndex<T> no longer accepts @namespace parameter. It means that even if a forking occurs, the same block/tx files are shared.

  • Fixed a bug that made unnecessary fork when receiving blocks from other peer.

  • Action classes that implement IAction but lack ActionTypeAttribute became reported by PolymorphicAction<T> throwing MissingActionTypeException at runtime. [#28, #144, #169]

  • Turn into parameter in BlockPolicy's constructor to milliseconds. [#151]

  • BencodexFormatter became able to serialize BigInteger. [#159]

  • Made Swarm possible to configure its network appProtocolVersion and, to ignore peers if their version is different. [#167], [#170]

  • Added DifferentAppProtocolVersionException class. [#167, #170]

  • Added IActionContext.Miner property. [#173], [#174]

  • Renamed Block<T>.RewardBeneficiary to Block<T>.Miner. [#174]

  • Added BlockChain<T>.Blocks property. [#176]

  • Added BlockChain<T>.Transactions property. [#176]

Version 0.1.1

Released on March 5, 2019.

  • Improved stability of Swarm and SwarmTest.

Version 0.1.0

Initial release. Released on February 26, 2019.