Skip to content

Instantly share code, notes, and snippets.

View mgraczyk's full-sized avatar

Michael Graczyk mgraczyk

View GitHub Profile
547dce2f801f943423638c89e9b90a0f2c1ea8b9
1e7c40a1ca01421d56cdb9ef0ee6534aca1cdd58
@mgraczyk
mgraczyk / event_loop.go
Created June 27, 2018 20:42
Perlin Avalanche Code Review
func (state *NodeActor) Receive(ctx actor.Context) {
switch msg := ctx.Message().(type) {
// [OT] ... Other cases for starting, stopping
case *messages.QueryRequest:
response := &messages.QueryResponse{}
if msg.Transaction != nil && msg.Transaction.Verify() {
stronglyPreferred := state.node.OnQueryTx(msg.Transaction)
response.Transaction = msg.Transaction.Id
import numpy as np
import sys
from random import randint
from math import ceil
def run_simulation(N, sims):
threshold = int(0.5 + 2. * N / 3)
print('{} / {}'.format(threshold, N))
results = []
message Node {
map<string, Transaction> queried = 1;
map<string, Transaction> transactions = 2;
map<uint64, ConflictSet> conflicts = 3;
map<string, uint64> chits = 4;
}
func (state *NodeActor) Receive(ctx actor.Context) {
switch msg := ctx.Message().(type) {
// ... Other cases for starting, stopping
case *messages.QueryRequest:
// ...
case *messages.ApiReceiveTransaction:
// ...
}
// [OT] This case corresponds to onGenerateTx in the paper.
case *messages.ApiReceiveTransaction:
// [OT] small race, should be `utxo := atomic.Add...() - 1`
// already being fixed by Perlin
utxo := atomic.LoadUint64(&messages.LastUTXO)
atomic.AddUint64(&messages.LastUTXO, 1)
body := messages.CreateTx(utxo, store.GetKeys().PublicKeyHex(), state.node.SelectParents(), msg.Data)
state.node.OnReceiveTx(body.Sign(store.GetKeys()))
// Searches for suitable parent transactions for a new transaction.
func (n *Node) SelectParents() []string {
// [OT] The lock could be held for less time with BFS
mutex.RLock()
defer mutex.RUnlock()
var eligibleParents []*Transaction
// [OT] Search every historical transaction.
for _, tx := range n.Transactions {
if n.IsStronglyPreferred(tx) {
// [OT] Figure 19, line 2
case *messages.QueryRequest:
response := &messages.QueryResponse{}
if msg.Transaction != nil && msg.Transaction.Verify() {
stronglyPreferred := state.node.OnQueryTx(msg.Transaction)
response.Transaction = msg.Transaction.Id
response.StronglyPreferred = stronglyPreferred
ctx.Respond(response)
}
// [OT] Always respond with empty? Does this overwrite?
ctx.Respond(response)
func (n *Node) OnReceiveTx(tx *Transaction) bool {
// ... Verify tx
// [OT] Take a global read lock.
mutex.Lock()
defer mutex.Unlock()
// [OT] Line 9
if _, received := n.Transactions[tx.Id]; !received {
// [OT] Line 10
if set, exists := n.Conflicts[tx.Body.Utxo]; exists {
set.Transactions[tx.Id] = tx // [OT] Line 13