Nyzo techRelease notesNyzo 603: Micropay support

Nyzo 603: Micropay support

Nyzo version 603 (commit on GitHub) adds Micropay support to the client and documentation server.

This version primarily affects the client and documentation server. Some changes may affect other run modes in minor ways. This version is part of the delivery to fulfill NTTP-5.

To make support of Micropay as easy as possible for web servers, the client was updated to provide more substantial feedback on the /api/forwardTransaction endpoint. Also, basic Micropay support was added, as a demonstration, to the documentation server.

In BalanceListManager, the frozenEdgeBalanceMap was added to eliminate the need to derive a balance map from the frozen-edge balance list on demand.

RN_603 code 0

In BalanceManager.makeBalanceMap(), the balance map is now a ConcurrentHashMap.

RN_603 code 1

In Transaction.performInitialValidation(), the pre-calculated frozenEdgeBalanceMap is now used.

RN_603 code 2

In TransactionForwardCommand, a map now stores transactions that have recently been forwarded. Some additional fields are used for maintenance of this map.

RN_603 code 3

The TransactionForwardCommand now accepts a supplementalTransaction parameter. This parameter, only necessary for Micropay, allows an old transaction to be forwarded while proving ownership of the key used to sign the old transaction. This is necessary to allow reuse of old transactions for reauthorizing Micropay purchases while protecting against theft of Micropay content by those who watch the blockchain to find transactions that authorize content they want to acquire.

RN_603 code 4

The TransactionForwardCommand.run() method now performs periodic maintenance, cleaning the recently forwarded transactions map every 10 executions.

RN_603 code 5

The result of TransactionForwardCommand.run() returns several new fields to assist a web server in determining whether to deliver Micropay content.

RN_603 code 6

The core logic of the TransactionForwardCommand.run() has changed substantially. The behavior with a single transaction is basically the same as it was before, but considerations for recently forwarded transactions and handling of supplemental transactions are now intermingled in this logic.

RN_603 code 7

The new logic begins by decoding the transaction. If the transaction is under the frozen edge, it is removed from the recently forwarded transactions map, because this is no longer relevant information for a block that has been frozen. A check is then performed to see if the transaction was already forwarded, and another check is performed to see if the transaction is already in the blockchain.

RN_603 code 8

If the transaction needs to be forwarded to the cycle, it is validated and forwarded.

RN_603 code 9

If the supplemental transaction is present, it is validated, also. The supplemental transaction is only valid if it is within the replay interval and if it is from the same sender as the transaction. Performing this validation on the client substantially reduces the complexity of the web server.

RN_603 code 10

The result now includes the new fields. An error is now returned in the JSON response if a transaction is not provided. This would have previously caused an exception.

RN_603 code 11

The old result is shown as completely removed due to indentation changes.

RN_603 code 12

The TransactionForwardCommand.performMaintenance() method first removes all transactions behind the frozen edge. If the map is still too large, it then removes arbitrary transactions. The only potential ill effect of premature transaction removal would be an inability to revalidate a Micropay transaction in the time between its initial submission and its incorporation in the blockchain.

RN_603 code 13

DocumentationController.buildEndpointMap() now processes files with the htm and txt extensions.

RN_603 code 14

The DocumentationEndpoint class contains 3 new fields to demonstrate Micropay functionality: micropayPrice, micropayReceiverIdentifier, and micropaySenderData.

RN_603 code 15

In the DocumentationEndpoint constructor, the loadMicropayParameters() method is now called to load the new parameters.

RN_603 code 16

To specify Micropay content, a Micropay file is placed alongside the content file, with the same filename as the content followed by the .micropay extension. This is a standard configuration file. Price is specified in nyzos with the key price. Receiver identifier is specified as a Nyzo string with the key receiver_identifier. Sender data, optional but recommended, is specified either as a normalized sender-data string or a text string. The key for sender data is sender_data.

RN_603 code 17

The DocumentationEndpointType enumeration now includes types for HtmlFragment and Text. The HtmlFragment type is used for files that should be delivered without modification, unlike files of Html type, which undergo modification by the documentation server. The DocumentationEndpoint.determineType() method now handles these new types.

RN_603 code 18

In DocumentationEndpoint.getResponse(), Micropay authorization is now considered.

RN_603 code 19

The DocumentationEndpoint.micropayAuthorized() method demonstrates the basic logic that is required of a web server to authorize Micropay content. The transaction and supplemental transaction are sent to the /api/forwardTransaction endpoint on a Nyzo client, and the response is retrieved.

RN_603 code 20

The client response is checked to determine whether the Micropay content should be delivered to the user. The conditions for authorization are explained in the comments. For endpoints that do not require payment, authorization always succeeds.

RN_603 code 21

The DocumentationEndpoint.getResponseForInvalidMicropay() method assembles a helpful response to let the requester know how to access the content.

RN_603 code 22

The DocumentationEndpointType enumeration contains the new HtmlFragment and Text values previously explained.

RN_603 code 23

The Json class is a simple, purpose-built JSON parser. This is not a good, robust JSON parser. This is a minimal implementation that just barely works to support structuring the client response for the Micropay demonstration for the documentation server. The Json class stores internal parser state. This class will not parse JSON strings longer than 10,000 characters.

RN_603 code 24

Some helper methods are used to improve readability of the parser.

RN_603 code 25

The Json.parse() method will parse either a dictionary (JsonObject), array (JsonArray), or string. Escaped quotes are replaced with the null character to eliminate the need to handle them in the parsing logic. These null characters are then replaced with quotes at the end of the process.

RN_603 code 26

The Json.parseJsonObject() method starts by handling quoted strings.

RN_603 code 27

For characters outside quoted strings, the various JSON markers ({, }, [, ], and ,) are used to determine structure. Recursion is used to process nested values.

RN_603 code 28

The Json.parseJsonArray() method also starts with handling of quoted strings.

RN_603 code 29

The structure of an array is simpler, only containing a list of values instead of key/value pairs. This method also utilizes recursion to handle nesting.

RN_603 code 30

The JsonArray class structures lists, providing the accessors needed by the DocumentationEndpoint.

RN_603 code 31

The JsonObject class structures dictionaries, also providing the accessors needed by the DocumentationEndpoint.

RN_603 code 32

The HttpStatusCode enumeration now includes a value for 402: Payment Required.

RN_603 code 33

A small styling change was made to the hover-button CSS class.

RN_603 code 34