Skip to content

Commit

Permalink
cleaning
Browse files Browse the repository at this point in the history
  • Loading branch information
Benjamin-Loison committed Oct 17, 2021
1 parent 7c81706 commit 2e64f5c
Show file tree
Hide file tree
Showing 8 changed files with 335 additions and 1 deletion.
Binary file added PDFs/fichesynth.pdf
Binary file not shown.
85 changes: 85 additions & 0 deletions PDFs/fichesynth.tex
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
\documentclass{article}

\usepackage[francais]{babel} %
\usepackage[T1]{fontenc} %
\usepackage[utf8]{inputenc} %
\usepackage{a4wide} %
\usepackage{palatino} %

\let\bfseriesbis=\bfseries \def\bfseries{\sffamily\bfseriesbis}


\newenvironment{point}[1]%
{\subsection*{#1}}%
{}

\setlength{\parskip}{0.3\baselineskip}

\begin{document}

\title{Réduction de la taille de stockage des blockchains}

\author{Benjamin LOISON, Emmanuelle ANCEAUME, IRISA}

\date{2 août 2021}

\maketitle

\pagestyle{empty}
\thispagestyle{empty}

%% Attention: pas plus d'un recto-verso!

\begin{point}{Le contexte général}

Les blockchains est un concept récent en informatique, défini pour sa célèbre application dans Bitcoin par S. Nakamoto en 2008. Bitcoin étant une blockchain permettant des échanges de la monnaie virtuelle Bitcoin de manière décentralisée, c'est-à-dire sans intervention d'états ou de banques. Il est intéressant de remarquer que les blockchains est un des rares domaines où la pratique à une avance importante sur la théorie, par exemple Bitcoin a été démontré sûr sous certaines conditions seulement en 2014 par Juan A. Garay.\\
Une des grandes difficultés pour les blockchains est le passage à l'échelle, c'est-à-dire le fait de maintenir la stabilité et une interaction aisée avec la blockchain même si le nombre d'utilisateurs augmente d'un ordre de grandeur. Dans le cas de Bitcoin afin de vérifier les transactions, que ce soit en tant que mineur (utilisateur sécurisant le réseau) ou en tant que full node (utilisateur vérifiant le réseau), ceux-ci doivent vérifier que chaque transaction du réseau est légitime et correcte. Cependant pour se faire ils doivent retracer la provenance de l'argent dans tout l'historique de Bitcoin qui pèse 338 Go actuellement en 2021. Cette quantité de données stockée de manière linéaire en l'utilisation de la blockchain en plus de ralentir l'initialisation des mineurs et full nodes (qui doivent alors télécharger sur le réseau peer-to-peer Bitcoin l'intégralité de la blockchain), cela empêche les utilisateurs lambdas utilisant par exemple leur téléphone de vérifier le réseau.\\
Le logiciel de référence Bitcoin Core pour les noeuds qui constituent le réseau Bitcoin propose une option d'élagage qui supprime l'historique de Bitcoin pour ne garder que l'état courant qu'une fois le téléchargement entier de la blockchain de Bitcoin effectué.
En pratique jusqu'à maintenant les smartphones se basait sur la technique du Simple Payment Verification (SPV) qui consiste à dépendre de full nodes et d'avoir à attendre un certain nombre de confirmations dans la blockchain pour s'assurer que le paiement effectué depuis son smartphone est bien pris en compte pour de bon par le réseau.

%De quoi s'agit-il? D'où vient la question? Quels sont les travaux déja accomplis dans ce domaine dans le monde?

\end{point}

\begin{point}{Le problème étudié}

Notre solution permet de réduire la consommation en bande passante et aussi en stockage, bien que des solutions sur ce dernier point existe déjà. Effectivement à part la consommation en électricité très élevé de Bitcoin, équivalente à un pays comme Israël, à cause de sa preuve de travail nécessitant la compétition de très nombreux processeurs, un problème majeur pour quelqu'un voulant participer au protocole est l'initialisation et le stockage. En pratique l'initialisation dure 10 jours avec une connexion fibre 1 Go/s puisque le téléchargement de la blockchain de Bitcoin grâce aux noeuds est très lent. En plus des plus de 340 Go que le noeud initialisant doit allouer pour conserver la blockchain de Bitcoin. Ces deux points découragent de nombreux amateurs, alors que justement Bitcoin se veut être une cryptomonnaie décentralisée sécurisée par la participation au protocole de tout le monde.

%Quelle est la question que vous avez résolue? Pourquoi est-elle importante, ? quoi cela sert-il d'y répondre? Pourquoi êtes-vous le premier chercheur de l'univers à l'avoir posée?

\end{point}

\begin{point}{La contribution proposée}

Une idée peut alors être de stocker uniquement un état courant vérifié du montant monétaire appartenant à chaque utilisateur, ainsi au lieu de parcourir toute l'histoire de la provenance de l'argent, on peut simplement vérifier le solde du compte. Cela permet notamment de se débarasser de l'historique des transactions et donc de la majeur partie de la blockchain de Bitcoin tout en gardant le même niveau de sécurité. Mes travaux se base sur cette idée ingénieuse de l'article "Mining in Logarithmic Space" qui a toutefois ses limites que l'on va essayer de repousser, puisque effectivement cet article ne traite pas le cas d'une difficulté croissante pour les mineurs ce qui est le cas dans Bitcoin. En pratique après application numérique, on transformera la blockchain de Bitcoin de 338 Go à 4.2 Go, ce qui permet notamment alors à un téléphone moderne de vérifier aisément le réseau Bitcoin.\\

%Qu'avez vous proposé comme solution à cette question? Attention, pas de technique, seulement les grandes idées! Soignez particulièrement la description de la démarche \emph{scientifique}.

\end{point}

\begin{point}{Les arguments en faveur de sa validité}

Le cas particulier de Bitcoin par rapport au papier "Mining in Logarithmic Space", traitant les blockchains de manière générale, profite des preuves de ce dernier et de celles inhérentes au papier "The Bitcoin Backbone Protocol with Chains of Variable Difficulty". Tant que l'hypothèse selon laquelle la majorité des noeuds participants protocole sont honnêtes est vérifiée, la sécurité de cette approche est garantie. Toutefois en pratique si on implémente cette approche toute en conservant l'ancienne en fonctionnement, on remarque que le haché de l'état actuel n'est vérifié que par les noueds éxécutant le nouveau protocole, cependant on pourra remarquer que seul le dernier haché est considéré dans notre approche et que donc celui-ci est le fruit du concensus de la majorité des noeuds éxécutant le nouveau protocole et que donc puisque les noeuds déjà initialisés passant au nouveau protocole peuvent vérifier ce haché de manière indépendante, on peut espérer que notre contribution garantie la correction des données partagées par la blockchain.\\
% peut demander le hash du set d'UTXO avec le protocole actuel à un noeud donné ?

%Qu'est-ce qui montre que cette solution est une bonne solution? Des expériences, des corollaires? Commentez la \emph{stabilité} de votre proposition: comment la validité de la solution dépend-elle des hypothèses de travail?

\end{point}


\begin{point}{Le bilan et les perspectives}

Par rapport à l'alternative d'élagage proposée par Bitcoin Core, notre contribution rétro-compatible permet d'une part de ne pas avoir besoin de stocker, même temporairement, l'entièreté de la blockchain de Bitcoin et permet surtout d'autre part de ne même pas avoir à télécharger l'entièreté de la blockchain mais seulement l'état courant et quelques blocs bien sélectionnés assurant l'authenticité de l'état courant reçu.\\
De cette manière si une telle approche était utilisée à l'initialisation des plus de 10 000 noeuds Bitcoin, on pourrait économiser plus de 3 000 To de bande passante.\\
Pour permettre aux nouveaux noeuds s'initialisant de bénéficier de cette initialisation rapide et légère il faudrait proposer une modification de Bitcoin Core implémentant notre approche et une modification d'un des logiciels utilisant pour miner du Bitcoin pour rajouter le haché de l'état courant dans les blocs de la blockchain afin de profiter pleinement de l'efficacité de notre approche.\\
Cette approche ne peut être généralisée qu'aux blockchains utilisant la preuve de travail.\\

%Et après? En quoi votre approche est-elle générale? Qu'est-ce que votre contribution a apporté au domaine? Que faudrait-il faire maintenant? Quelle est la bonne \emph{prochaine} question?

\end{point}

\end{document}




48 changes: 48 additions & 0 deletions Statistics/bitcoinStatsViewer.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import svgwrite, os

os.chdir("C:\\Users\\Benjamin\\Desktop\\BensFolder\\School\\ENS\\Saclay\\Stage\\Emmanuelle Anceaume\\Stage\\important\\Bitcoin viewer\\Stats\\")

fileName = "bin" # bin

f = open(fileName + '.txt')
lines = f.readlines()
f.close()
linesLen = len(lines)

maxAmount = 0
for linesIndex in range(linesLen):
line = lines[linesIndex]
if line[-1] == "\n":
line = line[:-1]
lineParts = line.split()
hashLevel, amount = [int(linePart) for linePart in lineParts]
if amount > maxAmount:
maxAmount = amount

width = 1000

svg_document = svgwrite.Drawing(filename = fileName + "HashesStats.svg", size = (str(width) + "px", str(linesLen * 15) + "px"))

def space(n):
if n < 1000:
return str(n)
if n < 10000:
return str(n)[0] + " " + str(n)[1:]
if n < 100000:
return str(n)[:2] + " " + str(n)[2:]
if n < 1000000:
return str(n)[:3] + " " + str(n)[3:]
#return str(n)[:3] + " " + str(n)[3:]

for linesIndex in range(linesLen):
line = lines[linesIndex]
if line[-1] == "\n":
line = line[:-1]
lineParts = line.split()
hashLevel, amount = [int(linePart) for linePart in lineParts]
rectSize = width * (amount / maxAmount)
svg_document.add(svg_document.rect(insert = (0, linesIndex * 15), size = (str(rectSize) + "px", "15px"), stroke_width = "1", stroke = "black", fill = "rgb(255,255,0)"))

svg_document.add(svg_document.text(str(hashLevel) + " (" + space(amount) + ")", insert = (1, (linesIndex + 1) * 15 - 2)))

svg_document.save()
Binary file added Statistics/difficultyChangesRelatively.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
64 changes: 64 additions & 0 deletions Statistics/statsOnDifficultyModification.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
import os, matplotlib.pyplot as plt

os.chdir('C:\\Users\\Benjamin\\Desktop\\BensFolder\\School\\ENS\\Saclay\\Stage\\Emmanuelle Anceaume\\Stage\\important\\difficultyChanges\\')

f = open('btc.com_diff_2021-06-14_14 00 58.csv') # https://btc.com/stats/diff/export
lines = f.readlines()
f.close()

l = []
difficultyChanges = {}
difficulties = {}

X, Y = [], []
X0, Y0 = [], []

maxDifficultyChange, maxDifficultyIndex = 0, 0
#difficulty = 1

linesLen = len(lines)
for linesIndex in range(1, linesLen):
line = lines[linesIndex]
lineParts = line.split(',')
linePartsLen = len(lineParts)
if not linePartsLen in l:
l += [linePartsLen]
difficulty = float(lineParts[2])
difficultyChange = float(lineParts[3])
#print(difficultyChange)
X += [linesIndex]
Y += [difficultyChange]
X0 += [linesIndex]
Y0 += [0]
difficultyChangeAbs = abs(difficultyChange)
#print(difficultyChangeAbs)
if difficultyChangeAbs > maxDifficultyChange:
maxDifficultyIndex = linesIndex
maxDifficultyChange = difficultyChangeAbs
if difficultyChangeAbs in difficultyChanges:
difficultyChanges[difficultyChangeAbs] += 1
else:
difficultyChanges[difficultyChangeAbs] = 1
if difficulty in difficulties:
difficulties[difficulty] += 1
else:
difficulties[difficulty] = 1

difficultyChanges = dict(sorted(difficultyChanges.items()))
difficulties = dict(sorted(difficulties.items()))

#for difficultyChange in difficultyChanges:
# print(difficultyChange, difficultyChanges[difficultyChange])

for difficulty in difficulties:
print(difficulty, difficulties[difficulty])

plt.plot(X, Y)
plt.plot(X0, Y0)
plt.show()

# 25 046 487 590 083 harder than initially

#print(l)
#print(maxDifficultyChange, maxDifficultyIndex)

2 changes: 1 addition & 1 deletion Statistics/zerosHashes.txt
Original file line number Diff line number Diff line change
Expand Up @@ -58,4 +58,4 @@
89 1
90 5
91 3
94 1
94 1
Binary file added bitcoin core.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
137 changes: 137 additions & 0 deletions bitcoinReader.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
#include <iostream>
#include <string>
#include <vector>
#include <fstream>
#include <sstream>
#include <cstdio>
#include <dirent.h>
using namespace std;

template<typename T>
string convertNbToStr(const T& number)
{
ostringstream convert;
convert << number;
return convert.str();
}

void print(string s);
vector<string> listFiles(string folder), getFileContent(string path);
bool endsWith(const string&, const string&);

//string blocksFolder = "/mnt/d/
string blocksFolder = "/mnt/c/Users/Benjamin/Desktop/BensFolder/School/ENS/Saclay/Stage/Emmanuelle Anceaume/Stage/important/Bitcoin reader/";

char pathSeparator = '/';
string pathSeparatorStr = "/";

int main()
{
vector<string> files = listFiles(blocksFolder);
unsigned int filesSize = files.size();
for(unsigned int filesIndex = 0; filesIndex < filesSize; filesIndex++)
{
string file = files[filesIndex];
//print(file);
if(endsWith(file, ".dat"))
{
print(file);

vector<string> lines = getFileContent("main.cpp"/*blocksFolder + file*/);
unsigned int linesSize = lines.size();
print("linesSize: " + convertNbToStr(linesSize));
for(unsigned int linesIndex = 0; linesIndex < linesSize; linesIndex++)
{
string line = lines[linesIndex];
print(convertNbToStr(linesIndex) + " " + line + " !");
}

/*unsigned short magics[4];
FILE* f = fopen(file.c_str(), "rb");
if(f == NULL)
{
print("Failed to open file !");
return 1;
}
for(unsigned short i = 0; i < 40; i++)
{
//magics[i] = fgetc(f);
//print(convertNbToStr(i) + " " + convertNbToStr(magics[i]) + " !");
print(convertNbToStr(i) + " " + convertNbToStr(fgetc(f)) + " !");
}
fclose(f);*/
}
}
return 0;
}

vector<string> getFileContent(string path)
{
vector<string> vec;
ifstream infile(path.c_str());
string line;
while(getline(infile, line))
vec.push_back(line);
return vec;
}

bool startsWith(string subject, string test)
{
return !subject.compare(0, test.size(), test);
}

void listFiles(string direc, vector<string>* str)
{
DIR* dir;
struct dirent* ent;
if((dir = opendir(direc.c_str())) != NULL)
{
while((ent = readdir(dir)) != NULL)
{
string file = ent->d_name;
if(!startsWith(file, "."))
{
string path = direc;
if(path[path.length() - 1] != pathSeparator)
path += pathSeparator;
path += file;
if(file.find_last_of(".") > file.length())
listFiles(path, str);
else
str->push_back(path);
}
}
closedir(dir);
}
}

bool endsWith(string const& value, string const& ending)
{
if(ending.size() > value.size()) return false;
return equal(ending.rbegin(), ending.rend(), value.rbegin());
}

string replace(string subject, const string& search, const string& replace = "")
{
unsigned int s = subject.find(search);
if(s > subject.length())
return subject;
return subject.replace(s, search.length(), replace);
}

vector<string> listFiles(string directory)
{
vector<string> files;
listFiles(directory, &files);
unsigned int filesSize = files.size();
for(unsigned int filesIndex = 0; filesIndex < filesSize; filesIndex++)
{
files[filesIndex] = replace(files[filesIndex], directory);
}
return files;
}

void print(string s)
{
cout << s << endl;
}

0 comments on commit 2e64f5c

Please sign in to comment.