consensus : CVE-2012-2459 , amélioration possible du code et des performances, ma logique est-elle correcte  ?


Trigger warning  : je ne vais pas être gentil. Parce que ce code est responsable de ma tension artérielle élevée.

uint256 ComputeMerkleRoot(std ::vector hachages,

mutation bool = faux ;

while (hashes.

pos + 1 < hashes.size();

si (hachage == hachages) mutation = vrai;

if (hashes.

consensus : CVE-2012-2459 , amélioration possible du code et des performances, ma logique est-elle correcte  ?

hashes.back());

SHA256D64 (hachages.begin(), hachages.begin(), hashes.size() / 2);

hashes.resize(hashes.size() / 2);

si (muté) *muté = mutation ;

if (hashes.size() == 0) return uint256();

retourner les hachages;

« La première chose que je remarque est la signature de la fonction.

uint256 C’est 32 octets (octets), c’est la taille de l’ensemble de votre cache de données sur x86-64. Et il s’obtient en (déréférencement) en utilisant le premier élément du vecteur des échecs de cache (ou uint256, vous choisissez le nom que vous préférez).

La seule fois où un pointeur aurait suffi… (C’est bon…)

bool* Indique que le type de retour est erroné.

En fait, je sais ce qui ne va pas avec tout ça… Ce n’est pas une fonction membre du TYPE qui est un vecteur…

C’est l’arbre, n’est-ce pas ? Ou plutôt « la dernière branche du »

if (muté) Cela ne vérifie pas si quelque chose a muté. Que si la déclaration devrait être retirée et abattue.

Cela vérifie si le bool* muté est nullptr, ce qui sera rarement le cas.

(Et il NE DEVRAIT PAS devenir nullptr à l’intérieur de cette fonction. Sinon, vous avez une course de données et vous pouvez arrêter de lire ici car le reste est UB.)

if (hashes.size() & 1)

Si la taille est étrange, bien sûr. (Encore la première itération de ce…

hashes.back()); Pensez-y…

while (hashes.// Première vérification de la taille.

// Ce n’est pas `nullptr`.

// Vous NE DEVRIEZ PAS passer un bool comme pointeur brut.

// POUR L’AMOUR DE DIEU.

//.

pos = 0; // en utilisant auto vous n’auriez pas le problème de :

// À CHAQUE itération de boucle, vous vérifierez le débordement.

// Je peux vous dire tout de suite que le débordement est impossible dans ce cas.

// Mais puisque le code qui arrive est tellement faux…

pos + 1 < hashes.size(); // ÇA DOIT ÊTRE UNE FARCE.

pos += 2)

si (hachage == hachages) mutation = vrai; // POURQUOI?

// Et maintenant.

// Définir continuellement la mutation sur true.

// CHAQUE ITERATION provoquera un manque de cache

//.

//,

// parce que les échecs de cache sont lents,

// ET puisque vous NE POUVEZ PAS réorganiser un LOAD avec un STORE.

// Cela vous fera perdre du temps. `mutation = true` c’est incroyablement coûteux sur le bras.

// Ceci est une implémentation en temps polynomial d’un algorithme qui

// DEVRAIT être DANS LE PIRE CAS linéaire dans le temps.

// pour (lent ; lent ; bien) manque de cache ; échec de cache ; boutique; récidive…

// if (un pointeur vers un bool n’est pas `nullptr`.

// Qui est constant sur l’ensemble une fonction)

if (hashes.// actuellement faux pour un vecteur de taille 2.

//. NB : (1)

hashes.back()); // plus de manques de cache.

// Et potentiellement une nouvelle allocation d’un objet de longueur obscène.

// À ce stade, c’est juste intentionnel.

// Personne n’est aussi doué pour désoptimiser du code au hasard.

// Fait amusant  : les hachages peuvent être hachés.

// Je suis presque sûr que vous pourriez hacher votre uint256 avec 2 fonctions de hachage,

// puis simplement xor avec les autres hachages de hachages (😎),

// alors si, et seulement si UN des ensembles de 2 hachages (d’un hachage) ne correspond pas

// vous prendriez la peine de vérifier l’ensemble. ‘devrait être Θ(n^2) le pire des cas.

// Un échec de cache de L1 à L2 est un peu mauvais.

// L2 à L3 est déjà très mauvais.

// L3 à ramer ?

// Mieux vaut l’écrire en Java, il aura un débit plus élevé avec un GC bien réglé.

Je me fiche de ce que fait le reste. C’est juste trop lent comme ça.

retourner les hachages; peut-être même pas NRVO…

J’ai regardé ton code. C’est bien, tu fais un clz, on vient juste de l’avoir en C++ en C++20 avec bitcast, donc on pourrait intégrer quelque chose de similaire. je veux dire… Personne ne pense qu’il pourrait être intéressant de, maintenant que ce concept s’est avéré susciter l’intérêt du public, recommencer avec une ardoise « blanche »…

Indice : le réseau bitcoin est essentiellement le plus grand réseau de neurones décentralisé que je connaisse. Je ne suis pas sûr que vous vous en rendiez compte.

La complexité ne doit pas être artificielle. C’était juste comme ça pour prouver le concept.

Nitpick : uint safePoint = ((uint)Math.Pow(2, plus élevéBitPosition));

N’est-ce pas juste un décalage binaire vers la gauche sur 1 par upperBitPosition ? 🤔 (c’est. Pour une position de bit plus élevée, tout Naturel jusqu’à (à l’exclusion de) la plus grande largeur de registre) Bien que pow à virgule flottante soit également 1 instruction, dans ce cas, il est plus lent (pour les puissances entières de 2), sinon, c’est un travail parfait pour un gpu.