Kodo pakartotinumas ir atsitiktinis bendrumas

Viena iš bjauriausių, sutarimui svarbių klaidų (CVE-2018–17144) neseniai buvo rasta „Bitcoin Core“ programinėje įrangoje, kuri iki tol turėjo beveik nepriekaištingą istoriją. Jimmy Song parašė puikų šios klaidos išskaidymą.

Trumpa klaidos santrauka yra ta, kad yra 4 atvejai, kai „Bitcoin Core“ programinei įrangai reikia patikrinti, ar nėra išlaidų dvigubai. Iš pradžių visais 4 atvejais buvo naudojamas tas pats kodo vykdymo srautas. Po keleto subtilių kodo kartojimų per kelerius metus, vienas iš 4 atvejų („vieno tx-dvigubai praleisk-praleisk bloke“) buvo praleistas, o tai leistų kalnakasiui potencialiai apgauti kai kuriuos mazgus priimant bloką. kad padidina „Bitcoin“ pasiūlą.

Šios klaidos pobūdis man primena nuolatinį konfliktą tarp:

a) kodo pakartotinio naudojimo ir optimizavimo poreikis

b) pavojus nukristi dėl to, ką aš vadinu atsitiktiniu bendrumu: dalykai, panašūs ne pagal savo dizainą, o dėl atsitiktinumo

Atsitiktinis bendrumas sukuria derlingą dirvą košmarų ir galimų klaidų, tokių kaip CVE-2018–17144, reagavimui.

Atsitiktinis bendrumas

Šiek tiek informacijos, jei nesate susipažinę su programinės įrangos inžinerija:
 
Programinėje įrangoje yra ši didžiulė vizija, kad programinės įrangos komponentai yra idealiai moduliniai - panašūs į jų fizinės inžinerijos kolegas. Dėl rimtos priežasties nereikia visur neštis kitokio tipo įkroviklio ar USB laido.

Taigi visada buvo didelis pastangų pakartotinis kodų panaudojimas. Rašydamas nereikalingą kodą dažnai susiraukia. Kodėl tą patį darbą galima atlikti du kartus, kai tu gali tai padaryti vieną kartą?

Taip pat yra ilga programinės įrangos išradimo istorija, kuri suteikia kodo pakartotiniam naudojimui dar didesnį prioritetą prioritetų sąraše. Kodo pakartotinis panaudojimas dažnai laikomas viena iš „geriausios praktikos pavyzdžių“. Siekiantis jaunesnysis programinės įrangos kūrėjas gali būti linkęs manyti, kad kodo pakartotinio panaudojimo galimybė yra neigiama.

Tačiau yra slaptas kodo pakartotinio naudojimo pavojus - ir netikiu, kad šie dalykai niekada nebus tinkamai mokomi mokyklose.

Nepaprastas kodo pakartotinis panaudojimas reiškia, kad bet kuris du panašiai atrodančius kodo fragmentus suskaido į vieną, neatsižvelgiant į jų naudojimo atvejus ir pirminį ketinimą.

Daugelis kartų baigiasi kodu, kuris turi atsitiktinį bendrumą.

Galbūt nėra akivaizdu, kodėl atsitiktinis bendrumas yra blogas, tačiau norint suprasti, kodėl, reikia ilgai palaikyti pakankamai didelį programinės įrangos projektą.

Tai yra blogai, nes keičiasi produkto reikalavimai, o programinė įranga yra nuolat tobulėjantis produktas, kurio gatavas produktas niekada nebuvo visiškai baigtas.

Ši nuolat judančio tikslo problema yra kažkas išskirtinio programinės įrangos. Jei esate konstruktorius, nesitikėkite, kad namas taps 20 aukštų, o automobilis - skraidančia lėkštute. Tačiau programinėje įrangoje mes tai nuolat darome.

Kai keičiasi produkto reikalavimai ir naudojimo atvejai, pagrindinės prielaidos, kurioms programinė įranga buvo sukurta iš pradžių, gali būti nebetaikomos.

Taigi tas išdidus bendrojo kodo fragmentas, kurį atnaujinote (bet dabar visiškai pamiršote), nebeveikia taip, kaip manote.

Aš praradau daugybę skausmingų rekonstravimo projektų ar bjaurių klaidų, kurias mačiau tiesioginio priešlaikinio optimizavimo ar atsitiktinio bendrumo padariniu - iki to laiko, kai aš vengiu tokių dalykų, kaip Paveldėjimas, kaip maras.

Daiktai, kurie turi atsitiktinį bendrumą, greitai atskleis savo skirtumus, kai jie vystysis už pradinės būklės ribų. Bet koks kodo bendrumo griežtumas atsikratytų.

Kuo daugiau kodų yra atsitiktinio bendrumo sluoksnių, tuo daugiau minos lauko reikia naršyti. CVE-2018–17144 yra puikus to pavyzdys.