Aplatissement de l’intégration Anvil On Ink et des tests E2E

  • Identification et documentation des fonctionnalités manquantes dans les tests d'intégration
  • Développement de 7 fonctions avec des implémentations manquantes mais réalisables dans l'environnement de test d'intégration
  • Résolution de problèmes avec 3 fonctions qui ont été implémentées lors des tests d'intégration, mais ont montré des différences par rapport à leurs équivalents sur e2e
  • Signalisation et résolution d'un problème avec une fonction présentant un problème du côté de bout en bout (e2e)

Aperçu

Pour aplatir efficacement une enclume, il faut identifier ses imperfections et appliquer la chaleur et la pression nécessaires pour les corriger. Une enclume plate est indispensable pour fixer d’autres outils et armures. De même, à l’encre ! contrats intelligents, nous considérons les environnements d’intégration et de test de bout en bout (e2e) comme des enclumes pour résoudre les imperfections des contrats intelligents. Cependant, lors de nos recherches sur les techniques de détection de vulnérabilités pour l’encre ! en collaboration avec LAFHIS en mars 2013, nous avons observé que tandis que l’encre ! les tests d’intégration sont plus rapides, il leur manque certaines fonctionnalités par rapport aux tests e2e. Combler ces lacunes pourrait rationaliser le processus de développement et potentiellement réduire les délais de test et d’assurance qualité.

Au cours des trois derniers mois, de septembre à novembre 2023, nous avons travaillé avec diligence pour identifier et implémenter les fonctionnalités manquantes dans l’encre ! environnement de test d’intégration, notre enclume. Nous y sommes parvenus grâce à une série de subventions du Fondation Web3.

La première partie de notre parcours s’est concentrée sur l’identification et la documentation des fonctionnalités manquantes dans les tests d’intégration, ainsi que sur les différences de mise en œuvre par rapport aux tests e2e. Notre effort s’est concentré autour des 24 fonctions exposées dans le fichier env_access.rs de l’encre ! dépôt. Ces fonctions sont exposées dans ce fichier pour leur utilisation dans Ink ! tests d’intégration (IT) et e2e. Au fur et à mesure que nous avons documenté chaque fonction, nous avons créé un ensemble de cas de test évaluant leur comportement par rapport à leur équivalent e2e. Ces cas de tests et une analyse approfondie de chaque fonction sont disponibles dans notre référentiel d’analyse.

Aplatissement de l’intégration Anvil On Ink et des tests E2E

À partir de cette analyse, nous avons déterminé que 11 fonctions présentaient une mise en œuvre cohérente dans les environnements d’intégration et de test e2e. Les 13 autres fonctions présentaient des implémentations manquantes pour les tests d’intégration, ou des différences d’implémentation par rapport aux tests e2e.

Aplatir l’enclume

Notre travail sur les 7 fonctions avec des implémentations manquantes mais réalisables dans l’environnement de test d’intégration a commencé avec l’implémentation de instantiate_contract(), permettant d’appeler des constructeurs sous contrat. Cela a été la pierre angulaire de notre développement, car cela nous a permis de travailler ensuite sur l’invocation de contrat, en implémentant les fonctions Invoquer_contract() et Invoquer_contract_delegate(). Les fonctions liées au hachage du code du contrat étaient également liées à l’instanciation du contrat : set_code_hash(), code_hash() et own_code_hash(); nous avons implémenté ces fonctions pour avoir un comportement équivalent à ce qui est observé dans l’environnement e2e. Enfin, nous avons développé caller_is_origin(), qui détecte les changements d’appelant à chaque fois que des appels sont passés entre des contrats. Ces développements ont été publiés sous forme de pull request vers l’encre ! référentiel dans PR #1988 et PR #1991.

D’un autre côté, nous avons résolu des problèmes avec 3 fonctions qui ont été implémentées lors des tests d’intégration, mais ont montré des différences par rapport à leurs équivalents sur e2e. À partir de default_accounts(), nous avons mis à jour les noms et adresses des comptes dans les tests d’intégration pour qu’ils coïncident avec les tests e2e, les faisant également dépendre de la bibliothèque sp_keyring::sr25519::Keyring et garantissant une implémentation cohérente dans les deux environnements. Pour set_contract_storage(), nous avons ajouté une validation manquante dans les tests d’intégration qui était présente dans e2e, qui vérifiait que la taille de l’ensemble de stockage ne dépassait pas 16380 octets. Enfin, nous avons corrigé la fonction balance(), garantissant que le solde initial est le même dans les environnements d’intégration et e2e. Les corrections proposées pour ces fonctions ont été publiées respectivement via les pull request PR #1955, PR #1961 et PR #1982.

Les 2 fonctions avec des implémentations manquantes et irréalisables dans les tests d’intégration étaient gaz_gauche() et appel_runtime(). L’implémentation de gas_left() a été jugée irréalisable car les tests d’intégration sont effectués sur du code natif plutôt que sur du code WASM, et parce que le coût du gaz est basé sur le nombre d’instructions WASM exécutées. Quant à call_runtime(), l’implémentation de cette fonction nécessiterait d’émuler pratiquement tout le nœud pour obtenir des résultats cohérents, ce qui n’est pas pratique.

Enfin, la seule fonction présentant un problème du côté de bout en bout (e2e) était poids_to_fee()qui a renvoyé des valeurs différentes dans les tests d’intégration et e2e. Cependant, la grande taille du runtime ralentissait considérablement le débogage. Nous avons signalé ce problème (#1985) ainsi qu’un rapport détaillé associé pour faciliter la discussion avec l’encre ! équipe de développement. Le problème a finalement été résolu dans la pull request PR #219 vers le nœud substrat-contrats-noeud.

Au total, sur l’univers des 24 fonctions analysées, nous avons réussi à en aplatir 22, en corrigeant leurs différences de mise en œuvre entre les tests d’intégration et les tests e2e. Nous avons également justifié l’infaisabilité du développement de gas_left() et call_runtime().

Allumer la forge

Ce projet est né de nos recherches sur les techniques de détection de vulnérabilités que nous avons effectuées pour créer Scout, notre encre ! outil de détection de bugs. En évaluant cargo-fuzz, nous avons découvert que les tests d’intégration constituent une base utile pour créer des harnais de test pour les détecteurs de fuzzing. Cependant, nous avons vite réalisé que notre travail était limité par les limites de l’environnement de test d’intégration lui-même, car de nombreuses fonctions n’étaient pas implémentées à des fins de test. Cela a marqué notre première rencontre avec l’encre ! tests d’intégration et nous ont d’abord motivés à travailler à leur amélioration.

À quelques exceptions près, nous pouvons désormais affirmer avec fierté que nous avons contribué de manière significative à la finalisation de l’encre ! environnement de test d’intégration. Après avoir relevé avec succès les défis de l’encre ! intégration et tests de bout en bout, nous espérons que nos contributions contribueront non seulement à lever les contraintes pour les équipes de recherche comme la nôtre, mais également à améliorer les pratiques de test en général dans cet environnement.