Introduction
Over the past couple of weeks, I’ve been involved in the PegNet project and I wanted to share my understanding of what it is and how it works with the rest of the world. I’m a developer and not an economist, so my perspective focuses more on the technical aspects than how to master the market. Due to the large scope of the project, this blog will be split into multiple pieces, with the first one focusing on the Oracle.
PegNet, short for Pegged Network, is a set of tokens pegged to existing currencies. It is built as a Factom Asset Token (“FAT”) standard on top of the Factom Protocol, meaning that the values and transactions sit inside chains and entries and using it will require you to use EC. We are still in earlier stages of development and at the time of writing, we are making preparations to launch the first public test of the PegNet test network which covers the mining process.
While you don’t need to know how the Factom Protocol works in-depth, you need to know how the basics of how to use it:
- Factoids (FCT) are the tokens
- Entry Credits (EC) are used to write entries
- The MainNet block time is 10 minutes
- Funding an EC address to pay for mining
Overview
To begin, let’s start with the vision of PegNet: a digital system that lets you store your assets as equivalents of well-known assets like the US Dollar, the Euro, Gold, or even Bitcoin. The goal is to allow you to freely convert between them at real-life exchange rates without requiring you to handle physical gold or go to an exchange. The exchange rates are determined through a proof-of-work mining process.
Assets inside PegNet are labeled with “p” and then their ISO 4217 code (or similar equivalent). For example, the US Dollar is pUSD
, the Euro is pEUR
, and Bitcoin is pXBT
, with the only exception being PegNet's own token: PEG. Each Factoid Address holds all available assets, meaning that an FA...
address will be able to send and receive PegNet assets. There are a total of thirty-two assets, including the US Dollar base and mineable PEG. Full list of assets at the time of writing.
The three functionalities of PegNet are:
- You can mine, which determines the exchange rates, and be rewarded with PEG. More details below.
- You can burn Factoids (FCT) into Pegged Factoids (pFCT). More details in blog part two.
- You can convert assets to each other at the current exchange rates or send them to another address. More details in blog part two.
Consensus
PegNet is a layer 2 application on top of Factom. This means that the data’s availability and immutability are secured by Factom’s proof of authority consensus model. PegNet itself is an interpreter of that data, using a Trust Yourself concept. This means that you read all of the data from Factom and determine which entries follow the rules and which do not. By applying all valid entries, you arrive at a certain state and anyone else running the same set of rules will also have arrived at the same conclusion. This allows you to write entries that will be seen as valid by other participants.
If you choose to alter your rules, then other participants may end up ignoring those entries. It’s not possible for you to change the behavior of other PegNet participants by altering your own rules.
Proof of Work
In the rest of the document, I’m going to make frequent references to something called “Difficulty” of an OPR. This Difficulty is the result of proof of work.
PegNet uses a custom hash called LXRHash, which is designed to be GPU and ASIC resistant. The idea behind is to overload CPU caches by keeping a large table in memory and accessing it in a non-cacheable manner. PegNet uses a one gibibyte (2³⁰) table with seed 0xFAFAECECFAFAECEC
, map size 30
bits, hash size of 256
bits, and 5
passes.
The difficulty of an OPR is calculated by:
- Calculate the LXRHash of the entire Factom Entry content, which is known as
OPR Hash
- Calculate the LXRHash of the
OPR Hash
appended by theNonce
, which is bytes of the first ExtId of the Factom Entry (ExtId[0]) - Take the first 8 bytes of the hash produced in step 2 and use it as a Big Endian unsigned 64-bit integer. This is the
Difficulty
, where higher is better.
In pseudocode, this looks like:
func Difficulty(entry) uint64 { oprhash = LXRHash(entry.content) noncehash = LXRHash(oprhash | entry.extids[0]) return (uint64)(noncehash[0-7]) }
The Oracle
The Oracle is what determines the exchange rates used in a particular block. The gist is that all miners submit a number of Oracle Price Records (OPRs) every Factom Directory Block and these records will be graded, with the top ten receiving PEG, and the winner setting the exchange values. The process is a continuous loop, with one cycle lasting ten minutes, the duration of a Factom Directory Block:
- GRADE: Take all of the OPRs inside of the most recent directory block and grade them, which yields a list of the top ten OPRs. These are the winners, with the best record setting the prices to use for that block.
- CREATE: Gather currency exchange data from a variety of sources, relative to the US Dollar. Combine these with the list of winners and your info to form the next OPR.
- MINE: Take your OPR and mine for most of the duration of the block, trying to find the highest proofs of work you can.
- WRITE: Write the OPRs you want to submit to the Factom Blockchain before the block is over so they can be graded next block.
Grade
The goal is to find the ten best OPRs, where “best” means closest to the true exchange rate. It relies on the assumption that the majority of miners submit honest data that is very similar with not too much deviation. If there are fewer than ten valid OPRs in the block, there are no winners and all transactions are not processed until the next winning block.
- Take all OPRs in a directory block and throw out ones with an invalid format
- Sort the OPRs by their Difficulty, from best to worst
- Throw out all but the top 50
- Take the remaining OPRs and
a. calculate the average asset values (leaving you with 32 averages )
b. grade each OPR where the grade is the sum of all differences between the OPR’s asset value and the average, normalized using the average, raised to the power of 4
c. throw out the record with the highest grade - Repeat step 4. until there are only 10 OPRs left (typically 40 iterations)
- Grade them one last time
- Sort the remaining ten OPRs by their Grade, from lowest to highest
In the case of ties, the OPR that appears first in the entry block wins the tiebreaker.
For a detailed example, please see this wiki page.
Create
The goal is to create the OPR that we will be submitting. Please note that we just have to create one OPR that we can submit multiple times. Submissions with the same OPR Hash but a different nonce count as a separate entry.
To build the OPR, we need the following data:
- The list of 10 winners in the previous block
- Asset exchange rates
- Your information, which includes your payout address
Miners want to select values that are closest to the average of the values everyone else picks (see Grading). The PegNet software queries a variety of APIs (configurable in the ini) at the beginning of the block, which should establish a hard-to-break precedent. The list of APIs will grow over time but this is an area where every miner (or mining pools) may implement their own way of grabbing financial data, with the goal to be right in the middle of everyone else.
All of that information is compiled into JSON format, the exact specifications of which are detailed in the PegNet FATIP: https://github.com/Factom-Asset-Tokens/FAT/blob/FATIP-2-Pegged-Asset-Token-Standard/fatips/2.md#opr-entry (subject to change when identities are implemented)
The JSON is then LXR-hashed to form the OPR Hash
.
Mine
The goal is to find a Nonce for the OPR that has a high difficulty. Calculating the OPR Hash itself has an input of around 800–900 bytes, resulting in a 32-byte hash. This only has to be done once. Calculating the difficulty for a specific nonce uses 32 + size of nonce
bytes. You can pick any Nonce you want but for performance reasons, it makes more sense to keep it as short as possible, since a longer input will take longer to hash:
The PegNet miner runs through the range of int64 (2⁶⁴ different nonces), only generating new bytes when absolutely necessary. This counter is then prefixed by a single-byte ID per goroutine, allowing for up to 256 miners per instance. There is no benefit to running more miners on one machine than you have CPU cores, however:
How many miners you run is a setting in the config file and this will largely depend on your system and preferences. One machine needs at least 1 GiBi of ram to hold the byte map, plus overhead, plus operating system. All miners running on the same machine will share the same RAM table.
Write
The goal is to submit OPRs that make it into the top 50 to make it into Grading. Miners are paid if an OPR they submit makes it into the top ten:
- First place: 800 PEG
- Second place: 600 PEG
- Third to Tenth place: 450 PEG
This comes up to a total of 5,000 PEG paid out every directory block. One miner can win multiple times in the list, making it possible to win all 5,000 PEG. That means the optimal amount of OPRs to submit is your ten best. This can be further optimized in the future by having the software automatically check the average difficulty of the last few blocks to see what the expected threshold for getting into the top 50 and top 10 is.
Now the caveat: it costs money to submit OPRs. The byte-size of the OPR is below 1KiBi, which costs exactly one Entry Credit to submit. One Entry Credit can be bought for the equivalent of $0.001 USD. There are a maximum of 144 directory blocks in a 24 hour window, giving us a simple price table:
How many OPRs you submit is independent of how many miners you run and is configurable in the config via RecordsPerBlock
. Since this is basically a money-dial, you can choose how many OPRs you want to submit, though it should be noted that submitting more than ten per block has no benefit of mining rewards.
LXRHash Attributes
- A longer input takes longer to hash
- The results are uniformly distributed
- Results for different input are independent
My analysis of why LXR Hash is uniformly distributed can be found here: https://github.com/WhoSoup/pegnet/wiki/LXRHash-Difficulty-Distribution-Analysis
That implies we can treat LXR Hash like a coin toss. The outcomes for different inputs are independent of each other. This makes it possible to calculate the likelihood of reaching certain targets using relatively simple math if you know the hash rate.
This will likely be the topic of a future blog but you can check out my initial research on the topic on GitHub: https://github.com/pegnet/pegnet/issues/83
Intermission
PegNet has been a very interesting project in terms of possibilities. There is a lot more analysis and benchmarking that has not made it into the blog, and I welcome all readers to join the PegNet Discord or check out the other ways of taking part in this project at https://pegnet.org/.
The next part will focus on the market aspect and the various kinds of transactions that exist.
Originally published at https://factomize.com on July 31, 2019.