
Arbitrary Token Bridging
TL; DR오늘 우리는 Optimistic Ethereum에 대한 임의의 토큰 입금 및 인출을 가능하게 하는 새로운 게이트웨이 인터페이스를 출시하게 되어 매우 기쁩니다! 게이트웨이의 이전 주요 릴리스에서는 Optimism 토큰 목록 에 나열된 토큰을 L2로(및 그 반대로) 전송하도록 허용했습니다. 이 새로운 릴리스를 통해 우리는 혁신의 문을 열고 모든 ERC20 토큰이 계층 간의 경계를 전환할 수 있도록 하고자 합니다.작동 원리L2 체인을 개발할 때 토큰 브리징을 처리하는 방법을 알아내는 것은 복잡하고 균형이 풍부한 환경을 만듭니다. 우리의 브리지 구현은 다음과 같은 사실 간의 균형을 제공하고자 합니다.ERC20은 인터페이스일 뿐입니다 . L1에는 수백 가지의 다양한 토큰 구현이 있습니다. 이들 중 일부는 즉시 사용 가능한 OpenZeppelin 토큰과 크게 다릅니다. 따라서 모든 잠재적 유형의 예금 자금을 포괄하는 단일 "브리지 ERC20" 구현을 안치하는 것은 불가능합니다....
![Cover image for OVM Deep Dive [KOR]](https://img.paragraph.com/cdn-cgi/image/format=auto,width=3840,quality=85/https://storage.googleapis.com/papyrus_images/7bed0c28a7451bc3ac2d6c15ff32525701f35fb9e1f206452879effbef6ace46.png)
OVM Deep Dive [KOR]
핵심요약 – Layer 2 시스템용으로 설계된 모든 기능을 갖춘 EVM 호환 실행 환경인 OVM을 구축했습니다. 이 게시물은 OVM이 이더리움 메인 체인과 동일한 롤업을 가능하게 하는 방법을 설명합니다. OVM을 구축하는 이유는 무엇입니까? 우리 팀의 많은 사람들은 이전에 계약을 지원하는 최초의 일반화된 플라즈마 구성인 plapps를 설계하기 위해 일했습니다 ! 그러나 plapps에는 제한된 "단어" 계약과 관련된 완전히 새로운 개발자 도구가 필요했습니다. 이더리움 L2는 단순히 이더리움을 사용하여 확장하는 것을 의미하는 것이 아니라 이더리움 자체를 확장하는 것을 의미합니다 . 이것은 결국 이더리움 스마트 계약의 전체 기능 세트를 확장성 환경으로 가져오겠다고 약속한 최초의 L2 구성인 Optimistic Rollup을 개발하게 했습니다 . Unipig.exchange는 처음으로 이 전례 없는 기능을 시연했습니다. 처음으로 Uniswap은 L2에 있었습니다. 그러나 Unipig는...
![Cover image for Welcoming Ink to the Superchain - [KOR]](https://img.paragraph.com/cdn-cgi/image/format=auto,width=3840,quality=85/https://storage.googleapis.com/papyrus_images/b2916a1d71f6e83f0e0201a6bc5e272375b494975253e35b13588123db8a0ca2.png)
Welcoming Ink to the Superchain - [KOR]
오늘 우리는 OP Stack으로 구동되는 블록체인인 Ink를 통해 Kraken이 Superchain에 합류하게 되어 기쁩니다 . Ink는 끊임없이 성장하는 암호화폐 사용자 커뮤니티를 위해 매력적이고 간소화된 DeFi 경험에 대한 안전하고 원활한 액세스를 제공합니다. 180개국 이상에서 1,000만 명의 사용자를 보유한 Kraken은 세계에서 가장 큰 디지털 자산 거래소 중 하나이며 암호화폐에서 가장 존경받는 브랜드입니다. Ink의 Superchain에 대한 헌신은 전체 생태계에 큰 승리입니다. Kraken은 분산된 네트워크와 경쟁하거나 분열을 일으키는 것보다 Superchain에서 Ink를 출시하기로 결정했습니다. Superchain은 Optimism의 오픈소스 기술 스택으로 구동되고 Ethereum을 확장하려는 글로벌 비전으로 통합된 포지티브 합계 생태계입니다. Superchain을 통해 모든 단일 체인의 성공은 모든 관련자에게 이익이 되며, Ink는 이 긍정적인 합계 네트워...
<100 subscribers

Arbitrary Token Bridging
TL; DR오늘 우리는 Optimistic Ethereum에 대한 임의의 토큰 입금 및 인출을 가능하게 하는 새로운 게이트웨이 인터페이스를 출시하게 되어 매우 기쁩니다! 게이트웨이의 이전 주요 릴리스에서는 Optimism 토큰 목록 에 나열된 토큰을 L2로(및 그 반대로) 전송하도록 허용했습니다. 이 새로운 릴리스를 통해 우리는 혁신의 문을 열고 모든 ERC20 토큰이 계층 간의 경계를 전환할 수 있도록 하고자 합니다.작동 원리L2 체인을 개발할 때 토큰 브리징을 처리하는 방법을 알아내는 것은 복잡하고 균형이 풍부한 환경을 만듭니다. 우리의 브리지 구현은 다음과 같은 사실 간의 균형을 제공하고자 합니다.ERC20은 인터페이스일 뿐입니다 . L1에는 수백 가지의 다양한 토큰 구현이 있습니다. 이들 중 일부는 즉시 사용 가능한 OpenZeppelin 토큰과 크게 다릅니다. 따라서 모든 잠재적 유형의 예금 자금을 포괄하는 단일 "브리지 ERC20" 구현을 안치하는 것은 불가능합니다....
![Cover image for OVM Deep Dive [KOR]](https://img.paragraph.com/cdn-cgi/image/format=auto,width=3840,quality=85/https://storage.googleapis.com/papyrus_images/7bed0c28a7451bc3ac2d6c15ff32525701f35fb9e1f206452879effbef6ace46.png)
OVM Deep Dive [KOR]
핵심요약 – Layer 2 시스템용으로 설계된 모든 기능을 갖춘 EVM 호환 실행 환경인 OVM을 구축했습니다. 이 게시물은 OVM이 이더리움 메인 체인과 동일한 롤업을 가능하게 하는 방법을 설명합니다. OVM을 구축하는 이유는 무엇입니까? 우리 팀의 많은 사람들은 이전에 계약을 지원하는 최초의 일반화된 플라즈마 구성인 plapps를 설계하기 위해 일했습니다 ! 그러나 plapps에는 제한된 "단어" 계약과 관련된 완전히 새로운 개발자 도구가 필요했습니다. 이더리움 L2는 단순히 이더리움을 사용하여 확장하는 것을 의미하는 것이 아니라 이더리움 자체를 확장하는 것을 의미합니다 . 이것은 결국 이더리움 스마트 계약의 전체 기능 세트를 확장성 환경으로 가져오겠다고 약속한 최초의 L2 구성인 Optimistic Rollup을 개발하게 했습니다 . Unipig.exchange는 처음으로 이 전례 없는 기능을 시연했습니다. 처음으로 Uniswap은 L2에 있었습니다. 그러나 Unipig는...
![Cover image for Welcoming Ink to the Superchain - [KOR]](https://img.paragraph.com/cdn-cgi/image/format=auto,width=3840,quality=85/https://storage.googleapis.com/papyrus_images/b2916a1d71f6e83f0e0201a6bc5e272375b494975253e35b13588123db8a0ca2.png)
Welcoming Ink to the Superchain - [KOR]
오늘 우리는 OP Stack으로 구동되는 블록체인인 Ink를 통해 Kraken이 Superchain에 합류하게 되어 기쁩니다 . Ink는 끊임없이 성장하는 암호화폐 사용자 커뮤니티를 위해 매력적이고 간소화된 DeFi 경험에 대한 안전하고 원활한 액세스를 제공합니다. 180개국 이상에서 1,000만 명의 사용자를 보유한 Kraken은 세계에서 가장 큰 디지털 자산 거래소 중 하나이며 암호화폐에서 가장 존경받는 브랜드입니다. Ink의 Superchain에 대한 헌신은 전체 생태계에 큰 승리입니다. Kraken은 분산된 네트워크와 경쟁하거나 분열을 일으키는 것보다 Superchain에서 Ink를 출시하기로 결정했습니다. Superchain은 Optimism의 오픈소스 기술 스택으로 구동되고 Ethereum을 확장하려는 글로벌 비전으로 통합된 포지티브 합계 생태계입니다. Superchain을 통해 모든 단일 체인의 성공은 모든 관련자에게 이익이 되며, Ink는 이 긍정적인 합계 네트워...
편집팀의 메모:
옵티미스틱 이더리움 의 우주에는 흥미로운 작업이 너무 많아서 우리가 무엇을 했는지 세상에 알리기 위해 잠시 시간을 내는 것을 종종 잊습니다. 낙관적 이더리움의 내부 작동 방식과 이를 실현하는 데 도움을 주는 사람들에 대해 더 자세히 알고 싶다는 많은 분들의 의견을 들었습니다. 그 결과 우리는 낙관적 이더리움에서 일하는 사람들이 매일 그들이 다루는 아이디어와 도전에 대해 글을 쓰는 데브 블로그를 시작합니다 . 우리는 이러한 블로그 게시물에 특정 스타일이나 구조를 적용하지 않습니다. 우리 각자가 Optimism에서 우리의 작업에 대해 생각하는 방식을 그대로 볼 수 있습니다. 우리는 이것이 낙관적 경험을 들여다보는 작은 창처럼 작용하기를 바랍니다.
Highly Optimistic Dev Blog의 첫 번째 버전에 오신 것을 환영합니다! ☺️
저자: 켈빈 피처
이것은 2021년 6월 초 며칠 동안 Optimistic Ethereum 테스트넷 배포가 새로운 L1 ⇒ L2 예금 수락을 중단 하게 만든 버그를 조사한 경험에 대한 이야기입니다 . 어떤 맥락에서 L1 ⇒ L2 예금은 자산을 가져갑니다. L1 체인(Ethereum과 같은)에 앉아 L2 체인(Optimistic Ethereum과 같은)으로 이동합니다. 사건이 발생하는 동안 테스트넷 배포는 예치금을 올바르게 신용할 수 없었습니다. 버그의 정확한 원인을 이해하지 않고도 문제에 대한 합리적인 수정을 만들 수 있었기 때문에 이 이야기가 매력적이라는 것을 알았습니다 . 인간을 위한 소프트웨어 구축의 지저분한 현실을 강조하는 이야기 중 하나입니다. 나는 또한 이 게시물에 우리가 사고에서 얻은 엔지니어링 교훈 중 일부를 흩뿌릴 것입니다. 즐기다!
여러 사용자가 직접 문제를 보고한 후 Kovan 예금 문제를 처음 알게 되었습니다(이러한 종류의 문제에 대한 자동 경고를 개선해야 함을 상기). 보고된 일반적인 증상은 사용자가 L1에서 거래를 전송하여 입금을 시작할 수 있었지만 L2에서는 자금을 받지 못했다는 것입니다. 분명히 이것은 사용자가 자산을 L2로 이동하는 것을 막았기 때문에 꽤 문제가 있었습니다. 이것은 확실히 가능한 한 빨리 수정되어야 했습니다.
엔지니어링 수업 #1: 사용자 신고는 최후의 방어선입니다.
사용자 보고서는 문제를 발견할 때 최후의 방어선이 되어야 합니다. 사용자 보고서로 인해 문제를 발견한 경우 적절한 알림이 충분하지 않을 수 있습니다. 이 특정한 경우에 우리는 정기적으로 예금 트랜잭션을 제출하고 해당 트랜잭션의 실패를 모니터링해야 했습니다.
잠재적으로 문제를 일으킬 수 있는 소프트웨어의 여러 부분에 대한 작은 목록을 작성하여 디버깅 세션을 시작했습니다. 사용자 보고서를 기반으로 우리는 다음을 알고 있었습니다.
예금은 L1에서 올바르게 시작될 수 있습니다.
입금액이 L2에 올바르게 반영되지 않았습니다.
포인트 (1)은 스마트 계약에서 버그가 발생 하지 않았을 가능성이 있음 을 의미합니다 (예금 거래가 스마트 계약에서 문제인 경우 되돌릴 수 있음). 다행스럽게도 우리의 소프트웨어 스택은 상대적으로 단순하고 버그가 숨길 곳이 많지 않습니다. 문제가 계약에 없는 경우 L2 geth 노드에 있거나 L2 geth( 데이터 전송 계층 또는 DTL 이라고 하는 도구)로 트랜잭션을 전달하는 프로세스에 있었습니다 . 대안에 대한 제안을 받고 있습니다 😂).
DTL은 이와 같은 오류가 자주 발생하지 않는 최소한의 소프트웨어입니다. 우리는 우리 자신의 예금을 몇 개 만들었고 DTL이 이러한 예금을 올바르게 발견하고 인덱싱하고 있음을 발견했기 때문에 우리의 의심은 L2 geth로 바뀌었습니다 . 로그를 빠르게 훑어봐도 우리의 새로운 예금 거래가 분명히 L2에서 실행되고 있지 않다는 사실 외에는 많은 것이 드러나지 않았습니다.
다행히 다음 로그 라인을 발견했을 때 운이 좋았습니다.
대기열에 넣기 트랜잭션 동기화 범위 시작=2500 end=3545
...
대기열에 넣기 트랜잭션 동기화 범위 시작=2500 end=3546
...
대기열에 넣기 트랜잭션 동기화 범위 시작=2500 end=3547
이러한 로그는 L2 geth가 일련의 L1 ⇒ L2 예금 트랜잭션을 실행하려고 할 때 생성됩니다 . startL2 geth가 하나의 트랜잭션을 실행하고 다음 트랜잭션으로 이동해야 하기 때문에 시간이 지남에 따라 값이 증가할 것으로 예상됩니다 . 값이 변경되지 않는다는 사실은 startdeposit 을 실행하려고 할 때 L2 geth가 어떻게든 멈춘다는 것을 암시했습니다 2500. 이제 우리는 예금에 무슨 일이 일어나고 있는지 알아내야 했습니다 2500.
무슨 일이 일어나고 있는지 파악하는 가장 쉬운 방법은 데이터 전송 계층을 확인하여 무엇이 L2 geth로 전송되고 있는지 확인하는 것이었습니다. DTL에는 시퀀서로 전송되는 내용을 확인하기 위해 수동으로 쿼리할 수 있는 멋진 API가 있습니다. 그래서 다음 쿼리를 보냈습니다.
GET <https://url.of.dtl/enqueue/index/2500>
우리는 무엇을 되찾았습니까? null. 분명히 DTL은 이 입금에 대한 기록이 없었습니다.
그럼 보증금은 2501?
GET <https://url.of.dtl/enqueue/index/2501>
아니 null! 예, DTL에는 이에 대한 기록이 있습니다. 그리고 그 이후에 다른 모든 예금에 대한 기록이 있었습니다. 이것은 분명히 초기 문제의 원인이었습니다. DTL에는 입금 내역이 없어서 2500L2 geth는 입금 이상으로 진행하지 못했으나 2500신규 입금이 계속 접수되고 있었습니다. 흠...
이 버그의 기이한 특성은 비결정론적일 수 있음을 시사했습니다. 내 말은, 왜 보증금 이 2500누락되었을까요? 아니나 다를까 처음부터 동기화된 새 DTL이 예치금을 제대로 가져왔습니다. 즉, 프로덕션 DTL을 재설정하여 시스템을 다시 온라인 상태로 만들 수 있었지만 처음에 왜 이런 일이 발생했는지 정확히 이해하지 못했습니다. 앞으로 유사한 문제가 발생하지 않도록 근본 원인을 찾기 시작했습니다.
운이 좋게도 DTL은 비교적 단순한 소프트웨어입니다. 많은 일을 하지 않습니다. 기본적으로 다음과 같은 루프입니다.
결과적으로 이렇게 깨질 수 있는 것은 많지 않습니다. 우리에게 눈에 띄는 것이 없었기 때문에 우리는 결국 약간의 파기를 해야 했습니다. 가능성을 낮추기 위해 세 가지 잠재적인 버그 원인을 생각해 냈습니다.
첫 번째 직감은 Kovan이 대규모 블록 재구성을 경험했을 수도 있다는 것입니다. 대규모 재구성이 발생하면 노드는 일시적으로 네트워크의 오래된 보기를 볼 수 있습니다. Kovan의 DTL 은 트랜잭션을 수락하기 전에 12개의 확인(블록)을 기다리도록 구성되었습니다 . 이것이 근본 원인이라면 12개 이상의 블록에 대한 일종의 재구성이 예상됩니다.
Etherscan의 reorg 목록을 간단히 살펴보고 원점으로 돌아왔습니다. 사건 당시 거의 한 달 동안 개편이 없었습니다. Etherscan이 대규모 국지적 중단을 경험하고 Kovan의 나머지 부분과 동기화되지 않는 한, 눈에 띄지 않는 12개 이상의 블록 재구성이 있었을 가능성은 없습니다. 다음으로 넘어갑니다.
재구성이 아니었다면 우리 소프트웨어가 동기화 프로세스 중에 실수로 블록을 건너뛴 것일 수 있습니다. 그럴 가능성은 거의 없어 보였지만 이것이 문제의 원인이 아닌지 확인해야 했습니다.
우리가 블록을 건너뛰었는지 여부를 알아내기 위해 예치금이 포함된 L1 블록을 스캔했는지 알려주는 특정 로그 라인을 찾아야 했습니다 . 그러기 위해서는 먼저 이벤트가 발생한 블록을 찾아야 했습니다. 그래서 보증금을 찾기 위해 Etherscan으로 돌아 갔습니다 .

여기서 반환 값은 다음 형식의 구조체입니다.

여기서 timestamp및 blockNumberhere는 이 예치금이 제출된 블록의 타임스탬프와 블록 번호입니다. 우리는 우리가 원하는 것을 가지고 있었습니다: 이 예치금은 블록에 제출되었습니다 25371197. 이제 문제의 블록을 포함하는 로그를 찾기 위해 DTL 로그를 살펴보기만 하면 되었습니다. 확실히:

이 로그 라인의 는 targetL1Block우리가 찾고 있던 L1 블록과 일치합니다. 보증금이 포함된 블록을 확실히 동기화하려고 시도했습니다 . 그래서 우리는 왜 아무것도 보지 못했습니까?
DTL 로그를 조사한 결과 입금이 DTL에서 감지되어야 했지만 감지되지 않았음이 분명해졌습니다. 또한 DTL은 이 블록을 동기화할 때 오류를 발생시키지 않았습니다. 이벤트를 찾지 못했습니다 .
DTL 코드에 비교적 자신이 있었기 때문에 우리는 우리 자신이 아닌 다른 사람을 비난할 잠재적인 이유를 찾기 시작했습니다(그렇게 하는 것이 더 쉽기 때문입니다). Infura가 이 오류가 발생했을 때 거의 동시에 다양한 504 오류를 반환하고 있음을 발견했습니다.

흥미로운? 예. Infura에 문제가 있다는 증거? 그다지. 6월 9일 Infura에서 문제가 발생했을 수 있습니다. 아니면 아닐 수도 있습니다. 누가 알아. 안타깝게도 RPC 요청 기록을 저장하지 않았기 때문에 로그만으로는 이 문제를 더 이상 디버깅할 수 없었습니다.
엔지니어링 수업 #2: RPC 요청을 기록해 두십시오.
Ethereum 노드가 시스템에 중요한 경우 노드에 대한 모든 RPC 요청의 기록을 유지하는 것이 좋습니다. 스토리지 비용을 낮게 유지하기 위해 일정 기간이 지나면 로그를 항상 삭제할 수 있습니다.
공학 수업 #3: Infura는 합의가 아닙니다.
들어오는 결과의 유효성을 교차 확인하기 위해 동시에 여러 노드 또는 노드 공급자에게 요청을 보내는 것을 고려하십시오 . 이러한 노드 중 하나 이상을 직접 호스팅하는 것을 고려하십시오. 노드 공급자가 항상 올바른 결과를 반환한다는 가정에 절대 의존해서는 안 됩니다. 신뢰하되 확인하십시오.
우리는 Infura가 고장났거나 우리 시스템에 우리가 알아낼 수 없는 버그가 있었다는 상대적으로 만족스럽지 못한 결론에 갇혔습니다. 우리는 또한 사람들이 Kovan 테스트넷에 의존하고 시스템에 대한 입금이 여전히 완전히 중단되었기 때문에 약간의 압력을 받았습니다. 우리는 DTL을 재동기화하여 시스템을 백업할 수 있다는 것을 알고 있었지만 근본 원인 없이는 아마도 하루나 이틀 후에 같은 문제에 직면하게 될 것입니다.
약간의 논의 끝에 다음과 같은 절충안이 도출되었습니다.
DTL을 다시 동기화하여 시스템을 백업하십시오.
이 복구 논리가 트리거될 때마다 로그 줄을 추가하여 나중에 추가로 디버깅할 수 있습니다.
이 전략은 상황을 최대한 활용했습니다. DTL의 새로운 복구 논리는 근본적인 문제의 최악의 영향으로부터 우리를 보호했습니다. 버그가 다시 고개를 들면 정지된 시스템 대신 편리한 로그 라인을 얻게 됩니다. 윈윈.
공학 수업 #4: 근본 원인이 전부는 아닙니다.
문제를 완전히 이해하기 전에 문제를 완화하는 것이 가능하거나 더 나은 경우도 있습니다. 문제의 향후 발생을 계속 모니터링해야 합니다. 알 수 없는 버그가 시스템에서 유발할 수 있는 다른 효과를 브레인스토밍하는 것을 고려하십시오.
그리고 근본 원인을 이해하지 않고도 버그를 효과적으로 완화할 수 있었습니다. 패치는 원래 사건 이후 여러 차례 이 오류를 성공적으로 복구했습니다. 이 게시물을 작성하는 시점에서 우리는 아직 이 문제의 근본 원인을 파악하지 못했습니다. 작업할 다른 작업이 너무 많고 그동안 복구 논리가 이 문제를 완벽하게 잘 처리하고 있습니다. , 결함 허용!).
나는 이 사가가 소프트웨어 엔지니어링의 더 더러운 측면을 강조했기 때문에 매우 흥미로웠다. 소프트웨어를 구축하고 유지 관리하는 프로세스는 우리 모두가 원하는 것처럼 간단하지 않습니다. 실용적인 문제는 종종 "이상적인" 방법을 희생하면서 올 수 있습니다. 결국 좋은 소프트웨어 엔지니어링은 순수 수학이라기보다는 대략적인 과학에 가깝습니다. 사람들이 다른 사람들을 위해 소프트웨어를 만들 때 발생하는 지저분한 상황을 처리해야 합니다 . 당신이 할 수 있는 일은 최선을 다하는 것입니다. 배우고, 적응하고, 계속 나아가십시오.
우리는 Ethereum의 미래를 구축하기 위해 고용하고 있습니다. 여기에서 읽은 내용이 마음에 들면 채용 공고를 확인하십시오 . 다음 집을 찾을 수도 있습니다. 💖
편집팀의 메모:
옵티미스틱 이더리움 의 우주에는 흥미로운 작업이 너무 많아서 우리가 무엇을 했는지 세상에 알리기 위해 잠시 시간을 내는 것을 종종 잊습니다. 낙관적 이더리움의 내부 작동 방식과 이를 실현하는 데 도움을 주는 사람들에 대해 더 자세히 알고 싶다는 많은 분들의 의견을 들었습니다. 그 결과 우리는 낙관적 이더리움에서 일하는 사람들이 매일 그들이 다루는 아이디어와 도전에 대해 글을 쓰는 데브 블로그를 시작합니다 . 우리는 이러한 블로그 게시물에 특정 스타일이나 구조를 적용하지 않습니다. 우리 각자가 Optimism에서 우리의 작업에 대해 생각하는 방식을 그대로 볼 수 있습니다. 우리는 이것이 낙관적 경험을 들여다보는 작은 창처럼 작용하기를 바랍니다.
Highly Optimistic Dev Blog의 첫 번째 버전에 오신 것을 환영합니다! ☺️
저자: 켈빈 피처
이것은 2021년 6월 초 며칠 동안 Optimistic Ethereum 테스트넷 배포가 새로운 L1 ⇒ L2 예금 수락을 중단 하게 만든 버그를 조사한 경험에 대한 이야기입니다 . 어떤 맥락에서 L1 ⇒ L2 예금은 자산을 가져갑니다. L1 체인(Ethereum과 같은)에 앉아 L2 체인(Optimistic Ethereum과 같은)으로 이동합니다. 사건이 발생하는 동안 테스트넷 배포는 예치금을 올바르게 신용할 수 없었습니다. 버그의 정확한 원인을 이해하지 않고도 문제에 대한 합리적인 수정을 만들 수 있었기 때문에 이 이야기가 매력적이라는 것을 알았습니다 . 인간을 위한 소프트웨어 구축의 지저분한 현실을 강조하는 이야기 중 하나입니다. 나는 또한 이 게시물에 우리가 사고에서 얻은 엔지니어링 교훈 중 일부를 흩뿌릴 것입니다. 즐기다!
여러 사용자가 직접 문제를 보고한 후 Kovan 예금 문제를 처음 알게 되었습니다(이러한 종류의 문제에 대한 자동 경고를 개선해야 함을 상기). 보고된 일반적인 증상은 사용자가 L1에서 거래를 전송하여 입금을 시작할 수 있었지만 L2에서는 자금을 받지 못했다는 것입니다. 분명히 이것은 사용자가 자산을 L2로 이동하는 것을 막았기 때문에 꽤 문제가 있었습니다. 이것은 확실히 가능한 한 빨리 수정되어야 했습니다.
엔지니어링 수업 #1: 사용자 신고는 최후의 방어선입니다.
사용자 보고서는 문제를 발견할 때 최후의 방어선이 되어야 합니다. 사용자 보고서로 인해 문제를 발견한 경우 적절한 알림이 충분하지 않을 수 있습니다. 이 특정한 경우에 우리는 정기적으로 예금 트랜잭션을 제출하고 해당 트랜잭션의 실패를 모니터링해야 했습니다.
잠재적으로 문제를 일으킬 수 있는 소프트웨어의 여러 부분에 대한 작은 목록을 작성하여 디버깅 세션을 시작했습니다. 사용자 보고서를 기반으로 우리는 다음을 알고 있었습니다.
예금은 L1에서 올바르게 시작될 수 있습니다.
입금액이 L2에 올바르게 반영되지 않았습니다.
포인트 (1)은 스마트 계약에서 버그가 발생 하지 않았을 가능성이 있음 을 의미합니다 (예금 거래가 스마트 계약에서 문제인 경우 되돌릴 수 있음). 다행스럽게도 우리의 소프트웨어 스택은 상대적으로 단순하고 버그가 숨길 곳이 많지 않습니다. 문제가 계약에 없는 경우 L2 geth 노드에 있거나 L2 geth( 데이터 전송 계층 또는 DTL 이라고 하는 도구)로 트랜잭션을 전달하는 프로세스에 있었습니다 . 대안에 대한 제안을 받고 있습니다 😂).
DTL은 이와 같은 오류가 자주 발생하지 않는 최소한의 소프트웨어입니다. 우리는 우리 자신의 예금을 몇 개 만들었고 DTL이 이러한 예금을 올바르게 발견하고 인덱싱하고 있음을 발견했기 때문에 우리의 의심은 L2 geth로 바뀌었습니다 . 로그를 빠르게 훑어봐도 우리의 새로운 예금 거래가 분명히 L2에서 실행되고 있지 않다는 사실 외에는 많은 것이 드러나지 않았습니다.
다행히 다음 로그 라인을 발견했을 때 운이 좋았습니다.
대기열에 넣기 트랜잭션 동기화 범위 시작=2500 end=3545
...
대기열에 넣기 트랜잭션 동기화 범위 시작=2500 end=3546
...
대기열에 넣기 트랜잭션 동기화 범위 시작=2500 end=3547
이러한 로그는 L2 geth가 일련의 L1 ⇒ L2 예금 트랜잭션을 실행하려고 할 때 생성됩니다 . startL2 geth가 하나의 트랜잭션을 실행하고 다음 트랜잭션으로 이동해야 하기 때문에 시간이 지남에 따라 값이 증가할 것으로 예상됩니다 . 값이 변경되지 않는다는 사실은 startdeposit 을 실행하려고 할 때 L2 geth가 어떻게든 멈춘다는 것을 암시했습니다 2500. 이제 우리는 예금에 무슨 일이 일어나고 있는지 알아내야 했습니다 2500.
무슨 일이 일어나고 있는지 파악하는 가장 쉬운 방법은 데이터 전송 계층을 확인하여 무엇이 L2 geth로 전송되고 있는지 확인하는 것이었습니다. DTL에는 시퀀서로 전송되는 내용을 확인하기 위해 수동으로 쿼리할 수 있는 멋진 API가 있습니다. 그래서 다음 쿼리를 보냈습니다.
GET <https://url.of.dtl/enqueue/index/2500>
우리는 무엇을 되찾았습니까? null. 분명히 DTL은 이 입금에 대한 기록이 없었습니다.
그럼 보증금은 2501?
GET <https://url.of.dtl/enqueue/index/2501>
아니 null! 예, DTL에는 이에 대한 기록이 있습니다. 그리고 그 이후에 다른 모든 예금에 대한 기록이 있었습니다. 이것은 분명히 초기 문제의 원인이었습니다. DTL에는 입금 내역이 없어서 2500L2 geth는 입금 이상으로 진행하지 못했으나 2500신규 입금이 계속 접수되고 있었습니다. 흠...
이 버그의 기이한 특성은 비결정론적일 수 있음을 시사했습니다. 내 말은, 왜 보증금 이 2500누락되었을까요? 아니나 다를까 처음부터 동기화된 새 DTL이 예치금을 제대로 가져왔습니다. 즉, 프로덕션 DTL을 재설정하여 시스템을 다시 온라인 상태로 만들 수 있었지만 처음에 왜 이런 일이 발생했는지 정확히 이해하지 못했습니다. 앞으로 유사한 문제가 발생하지 않도록 근본 원인을 찾기 시작했습니다.
운이 좋게도 DTL은 비교적 단순한 소프트웨어입니다. 많은 일을 하지 않습니다. 기본적으로 다음과 같은 루프입니다.
결과적으로 이렇게 깨질 수 있는 것은 많지 않습니다. 우리에게 눈에 띄는 것이 없었기 때문에 우리는 결국 약간의 파기를 해야 했습니다. 가능성을 낮추기 위해 세 가지 잠재적인 버그 원인을 생각해 냈습니다.
첫 번째 직감은 Kovan이 대규모 블록 재구성을 경험했을 수도 있다는 것입니다. 대규모 재구성이 발생하면 노드는 일시적으로 네트워크의 오래된 보기를 볼 수 있습니다. Kovan의 DTL 은 트랜잭션을 수락하기 전에 12개의 확인(블록)을 기다리도록 구성되었습니다 . 이것이 근본 원인이라면 12개 이상의 블록에 대한 일종의 재구성이 예상됩니다.
Etherscan의 reorg 목록을 간단히 살펴보고 원점으로 돌아왔습니다. 사건 당시 거의 한 달 동안 개편이 없었습니다. Etherscan이 대규모 국지적 중단을 경험하고 Kovan의 나머지 부분과 동기화되지 않는 한, 눈에 띄지 않는 12개 이상의 블록 재구성이 있었을 가능성은 없습니다. 다음으로 넘어갑니다.
재구성이 아니었다면 우리 소프트웨어가 동기화 프로세스 중에 실수로 블록을 건너뛴 것일 수 있습니다. 그럴 가능성은 거의 없어 보였지만 이것이 문제의 원인이 아닌지 확인해야 했습니다.
우리가 블록을 건너뛰었는지 여부를 알아내기 위해 예치금이 포함된 L1 블록을 스캔했는지 알려주는 특정 로그 라인을 찾아야 했습니다 . 그러기 위해서는 먼저 이벤트가 발생한 블록을 찾아야 했습니다. 그래서 보증금을 찾기 위해 Etherscan으로 돌아 갔습니다 .

여기서 반환 값은 다음 형식의 구조체입니다.

여기서 timestamp및 blockNumberhere는 이 예치금이 제출된 블록의 타임스탬프와 블록 번호입니다. 우리는 우리가 원하는 것을 가지고 있었습니다: 이 예치금은 블록에 제출되었습니다 25371197. 이제 문제의 블록을 포함하는 로그를 찾기 위해 DTL 로그를 살펴보기만 하면 되었습니다. 확실히:

이 로그 라인의 는 targetL1Block우리가 찾고 있던 L1 블록과 일치합니다. 보증금이 포함된 블록을 확실히 동기화하려고 시도했습니다 . 그래서 우리는 왜 아무것도 보지 못했습니까?
DTL 로그를 조사한 결과 입금이 DTL에서 감지되어야 했지만 감지되지 않았음이 분명해졌습니다. 또한 DTL은 이 블록을 동기화할 때 오류를 발생시키지 않았습니다. 이벤트를 찾지 못했습니다 .
DTL 코드에 비교적 자신이 있었기 때문에 우리는 우리 자신이 아닌 다른 사람을 비난할 잠재적인 이유를 찾기 시작했습니다(그렇게 하는 것이 더 쉽기 때문입니다). Infura가 이 오류가 발생했을 때 거의 동시에 다양한 504 오류를 반환하고 있음을 발견했습니다.

흥미로운? 예. Infura에 문제가 있다는 증거? 그다지. 6월 9일 Infura에서 문제가 발생했을 수 있습니다. 아니면 아닐 수도 있습니다. 누가 알아. 안타깝게도 RPC 요청 기록을 저장하지 않았기 때문에 로그만으로는 이 문제를 더 이상 디버깅할 수 없었습니다.
엔지니어링 수업 #2: RPC 요청을 기록해 두십시오.
Ethereum 노드가 시스템에 중요한 경우 노드에 대한 모든 RPC 요청의 기록을 유지하는 것이 좋습니다. 스토리지 비용을 낮게 유지하기 위해 일정 기간이 지나면 로그를 항상 삭제할 수 있습니다.
공학 수업 #3: Infura는 합의가 아닙니다.
들어오는 결과의 유효성을 교차 확인하기 위해 동시에 여러 노드 또는 노드 공급자에게 요청을 보내는 것을 고려하십시오 . 이러한 노드 중 하나 이상을 직접 호스팅하는 것을 고려하십시오. 노드 공급자가 항상 올바른 결과를 반환한다는 가정에 절대 의존해서는 안 됩니다. 신뢰하되 확인하십시오.
우리는 Infura가 고장났거나 우리 시스템에 우리가 알아낼 수 없는 버그가 있었다는 상대적으로 만족스럽지 못한 결론에 갇혔습니다. 우리는 또한 사람들이 Kovan 테스트넷에 의존하고 시스템에 대한 입금이 여전히 완전히 중단되었기 때문에 약간의 압력을 받았습니다. 우리는 DTL을 재동기화하여 시스템을 백업할 수 있다는 것을 알고 있었지만 근본 원인 없이는 아마도 하루나 이틀 후에 같은 문제에 직면하게 될 것입니다.
약간의 논의 끝에 다음과 같은 절충안이 도출되었습니다.
DTL을 다시 동기화하여 시스템을 백업하십시오.
이 복구 논리가 트리거될 때마다 로그 줄을 추가하여 나중에 추가로 디버깅할 수 있습니다.
이 전략은 상황을 최대한 활용했습니다. DTL의 새로운 복구 논리는 근본적인 문제의 최악의 영향으로부터 우리를 보호했습니다. 버그가 다시 고개를 들면 정지된 시스템 대신 편리한 로그 라인을 얻게 됩니다. 윈윈.
공학 수업 #4: 근본 원인이 전부는 아닙니다.
문제를 완전히 이해하기 전에 문제를 완화하는 것이 가능하거나 더 나은 경우도 있습니다. 문제의 향후 발생을 계속 모니터링해야 합니다. 알 수 없는 버그가 시스템에서 유발할 수 있는 다른 효과를 브레인스토밍하는 것을 고려하십시오.
그리고 근본 원인을 이해하지 않고도 버그를 효과적으로 완화할 수 있었습니다. 패치는 원래 사건 이후 여러 차례 이 오류를 성공적으로 복구했습니다. 이 게시물을 작성하는 시점에서 우리는 아직 이 문제의 근본 원인을 파악하지 못했습니다. 작업할 다른 작업이 너무 많고 그동안 복구 논리가 이 문제를 완벽하게 잘 처리하고 있습니다. , 결함 허용!).
나는 이 사가가 소프트웨어 엔지니어링의 더 더러운 측면을 강조했기 때문에 매우 흥미로웠다. 소프트웨어를 구축하고 유지 관리하는 프로세스는 우리 모두가 원하는 것처럼 간단하지 않습니다. 실용적인 문제는 종종 "이상적인" 방법을 희생하면서 올 수 있습니다. 결국 좋은 소프트웨어 엔지니어링은 순수 수학이라기보다는 대략적인 과학에 가깝습니다. 사람들이 다른 사람들을 위해 소프트웨어를 만들 때 발생하는 지저분한 상황을 처리해야 합니다 . 당신이 할 수 있는 일은 최선을 다하는 것입니다. 배우고, 적응하고, 계속 나아가십시오.
우리는 Ethereum의 미래를 구축하기 위해 고용하고 있습니다. 여기에서 읽은 내용이 마음에 들면 채용 공고를 확인하십시오 . 다음 집을 찾을 수도 있습니다. 💖
Share Dialog
Share Dialog
No comments yet