tldr: accounting for resources proposal and example
In an open p2p network, certain valuable services are provided. While some nodes might choose to be altruistic, these services are not cost-free. Owing to this fact, there’s a natural supply and demand of these services in a network. We propose to capture this resource usage with an accounting mechanism. This is prerequisite for incentivization. It is the underlying structure that forms any incentives or disincentives. Later on, this can be extended through settlement and policy changes.
Accounting in Bittorrent
One basic example of accounting in a p2p network is Bittorrent. Here is how accounting works in BT, in a nutshell:
- Nodes upload and download chunks of a specific, valuable, file together in a swarm.
- A node wants to download a specific chunk, and it values other nodes sharing it.
- Uploading a chunk to another node brings a cost, and no direct benefit.
- The ratio between providing and extracting (upload/download) is called a seed ratio.
- A node can choke (not upload to) another node that doesn’t upload back.
- Choking uses tit-for-tat, where nodes trust at first but then penalize bad nodes.
- This tit-for-tat game, and the knowledge for it, is only local to a specific torrent.
- A user running a node can leech a torrent - download it quickly and then run.
- To discourage many torrents, private trackers have a global seed ratio.
- This seed ratio is self-reported and cross-checked against other nodes’ reports.
- If this seed ratio is too low, or node is lying, the private tracker can punish the user.
- Punishment for private trackers means restricting access to valuable torrent files.
This system does two important things:
- Accounting: It accurately identifies and accounts for the resources involved (upload/download BW)
- Policy: It encourages the right behavior by rewarding good behavior and punishing bad behavior
Notice how it doesn’t involve any form of monetary settlement, that is converting resources into cash. If we wanted to we could extend this system, but there’s no requirement to do so.
Based on the above, we have a blueprint for how to do accounting for resources. However, for Waku the domain is slightly different. Here’s how we might go about it. First, we need to answer the question:
What are the types of actions a node can take?
These are directly reflecting the capabilites a node has (see https://github.com/vacp2p/specs/issues/87):
- sending messages
- receiving messages
- relaying messages
- bootstrap nodes
- store historical messages and return them on request
A natural follow up question to this is:
Of the actions a node can take, which actions are contributions or costs for the network?
Sending a message is a cost to the network, because it is extra work nodes have to do that they don’t directly value. It is valuable to the node sending a message. (It is also, sometimes, valuable to the receiver).
Receiving a message is a neutral action as it is a passive result of being relayed messages one is interested in.
Relaying a message is a small cost to the node doing it. It is somewhat valuable to the node requesting to be relayed such messages, though usually in an indirect way (see example below). It is indirectly valuable to the end sender and receiver, but in many topologies - including the existing one for Waku - these aren’t directly known.
Bootstrapping other nodes is a valuable contribution to the node that is being served with other nodes. It is fairly low cost though and not generally a bottleneck, so we’ll ignore this one for now.
Storing historical messages for other nodes and returning them on request is a valuable contribution to the node requesting them. (It is also, sometimes, valuable to the sender).
We might notice that these contributions and costs aren’t equal. For example, storing a message depends on its size and duration of storage. Based on this, we can assign these actions some weight. In an ideal system, these prices would be discovered and set by the market in a Hayekian fashion.
Waku - Worked example
Let’s make the above more concrete with an example. Let’s start by assigning weights and who might be credited / debited for each action. Then we’ll look at an example of how things might work in a specific scenario.
- send: -10
- receive: -1
- relay: +1
- bootstrap: 0
- store: +10 (leaving out variablity for now)
Now, for this to be a proper accounting scheme we need these to balance out, like credit and debit. In some cases this is easy - a node storing historical messages should obviously be rewarded for its services. In the case of a node sending a message, shouldn’t everyone involved in delivering the message be rewarded? More on this later.
We have two light nodes two full nodes. A light node can only send and receive messages. A full node can do everything. They are connected in the following topology:
L1 <> F1 <> F2 <> L2
Let’s say L1 wants to send a message to L2. Let’s further assume L2 is initially offline. What does the accounting look like? Like Bittorrent, we want nodes to act on local knowledge and to keep an internal, pairwise, accounting balance. For brevity, we assume nodes all report the same numbers. We simplify this with a “global view” of the current account balances.
- L1 and L2 discover F1 and F2, respectively. F1 and F2 are already connected (-)
- L1 sends a message through F1 (L1 -10, F1 +10) 
- L1 relays a message to F1 based on F1’s interest (L1 +1, F1 -1) 
- F1 relays a message to F2 based on F2’s interest (F1 +1, F2 -1)
- L2 comes online and requests a historic message from F2 (L2 -10, F2 +10)
Net account balance:
L1: -10/+1 = -9
F1: +10/-1 = +9
F2: +10/-1 = +9
L2: +10/ = -10
In sum, we have two light nodes that are leeching of the network, and two nodes that help the network. In general, even though the forwarding costs F1 and F2, we can assume a form of steady state, where the inflow and outflow of relaying roughly adds up.
It is important to note that a node only has local information, and keeps track of their own accounting with the nodes they do business with.
What problems are we solving?
Accounting is just the first step. It allows us to rigorously identify good and bad (or costly) behaviour. Let’s look at a few behaviours we might observe:
- If a node is spamming several new messages, this is costly.
- Nodes that relay messages and store historical messages are rewarded.
- The more messages a node receives the more it costs.
- If node A knows another node B will likely ask for historical messages in the future, it can do arbitrage by asking a node C for more recent messages (assuming variability w.r.t. age).
- If two full nodes “in the middle”, like in example above, relay messages then this flow should even out in a form of a steady state (relayed in ~= relayed out).
- If we have two self-reports, this can inform other decision making (arbitrarion etc).
- Even simpler, self-reports allows local nodes to decide on their own policy 100% voluntarily, e.g. disconnect leeching or uncooperative nodes.
It doesn’t address:
- Proving end to end delivery or rewarding every hop in a send action. This likely isn’t doable at this layer with this gossip like topology, but different topologies might enable this enhancement. See .
- How a new message is identified. Self reporting among sender and receiver is the natural first step here. Conflicting information can inform policy and decision heuristics for settlement. It can also be extended with a proof later on.
- Settlement or policy based on accounting. More on this in a different post.
- Further discussion and input
- Basic spec (the existing one in Waku is too simplistic)
- PoC with relevant metrics for self-reporting in clients
- Extend simulation with this
- Further research into accounting mechanisms
- Sketch of basic policy and settlement design
- Further validation/interplay with digital double (e.g. Block.science etc)
BT economics http://bittorrent.org/bittorrentecon.pdf
Tit for tat game theory https://en.wikipedia.org/wiki/Tit_for_tat
Use of knowledge in society, on market prices https://www.econlib.org/library/Essays/hykKnw.html (http://bev.berkeley.edu/ipe/readings/The%20use%20of%20knowledge%20in%20society.pdf pdf)
Double entry bookkeeping https://en.wikipedia.org/wiki/Double-entry_bookkeeping_system
. Why do we reward F1? For simplicity. This is the only local information L1 has, and F1 is helping it get its message out into the world. Under different topologies with different assumptions this might look different. Another simple alternative here is to burn a token of some kind. Also see  and  for postal system and stamps.
. This could be optional. Depending on how much we want to - or are able to - distinguish relaying of messages from sending, this may or may not be optional. It might seem weird that F1 would pay, but it has expressed interest in these types of messages, so L1 is doing F1 a “favor” in that regard. On net, F1 comes out ahead if it also gets a piece of L1’s “sending” pie.
. Even for regular mail there’s rarely any end to end guarantees. Instead, you know that a certain type of service is reliable, and if it isn’t you switch. This is similar to peer rating. Additional guarantees instead happens on top, in terms of insurance or fines for postal service if letter arrives too late, etc.
. In fact, this is exactly how the postal system for international mail works. For international mail, your stamp money goes to the sender country. Settlement between intermediate destinations was only added after more than a hundred years of service (the current system is from 1969), and even the it is primarily based on quarterly settlement of imbalance (aka accounting).