EOS 네트워크에서 트랜잭션이 손실되고 있습니다.

특히, EOS 네트워크의 노드는 때때로 네트워크를 통해 현재 활성 블록 프로듀서에게 트랜잭션을 전달하는 데 실패합니다. 주관적인 청구가 종종 이 문제의 원인입니다.

본 기사에서는 주관적인 청구 기능, 그것이 존재하는 이유 및 ENF 후원기반 워킹 그룹이 식별한 주관적인 청구와 관련된 문제를 살펴봅니다. 이러한 문제를 방지하기 위한 빠른 참조 또한 포함되어 있습니다. 추후에는 기존 수정 사항을 더 자세히 살펴보고 Mandel 3.1 릴리스의 추가 기능을 살펴보겠습니다.

“주관적인 청구(Subjective billing)”란 무엇이며 도입된 이유는 무엇입니까?

주관적인 청구는 노드가 네트워크의 나머지 부분과 청구를 공유하지 않고 자체 노드에서 로컬로 계정 리소스를 청구할 수 있는 EOSIO의 기능입니다. 도입 이후 노드 CPU 사용이 거의 90% 감소했지만 때때로 트랜잭션이 지속적으로 실패하거나 트랜잭션이 손실되기도 합니다. 블록체인에서 실행되는 스마트 컨트랙트 코드가 assert() 또는 check()와 같은 “check” 기능을 사용하여 데이터를 확인하는 경우 주관적인 청구 문제가 발생할 수 있습니다.

이러한 문제의 세부 사항을 이해하려면 트랜잭션 수명 주기의 아키텍처를 이해하는 것이 좋습니다.

EOSIO에서 체인은 노드 간 P2P(피어 투 피어) 네트워크 연결을 사용하여 블록체인 네트워크를 통해 트랜잭션을 전파합니다. 이 P2P 네트워크에서 노드 구성 설정 및 네트워크 대기 시간은 트랜잭션이 노드 간에 이동할 때 이동하는 경로에 영향을 줍니다.

그림 1과 같이, EOSIO 트랜잭션의 수명 주기는 사용자가 API 노드(1.1)에 트랜잭션을 제출할 때 시작됩니다. API 노드는 트랜잭션을 내부적으로 P2P 프로토콜(1.2)에 전달하고, P2P를 통해 다른 노드에 전달하고, 이를 다시 다른 노드에 전달하는 방식으로(1.3) 트랜잭션이 결국 현재 블록을 생성하는(1.4) 블록 프로듀서(BP)에 도달할 때까지 계속됩니다. 이후 활성 BP가 블록(1.5)에 트랜잭션을 포함하고 계정에 리소스를 청구합니다. 네트워크의 각 노드는 연결된 다른 노드로 트랜잭션을 전달할지 또는 실패한 내부 확인 또는 리소스 과사용으로 인해 트랜잭션을 실패할지 여부를 독립적으로 결정합니다.

일부 다른 블록체인과 달리 EOSIO 체인은 기본적으로 유효하게 서명된 트랜잭션이 이런저런 이유로 실패할 때 사용된 리소스에 대해 계정에 청구하지 않습니다. 주관적인 청구를 통해 개별 노드가 그렇게 할 수 있습니다.

“주관적”이란 노드 운영자의 서버에서 실행되는 EOSIO 애플리케이션 노드의 개별 인스턴스에만 청구가 적용됨을 의미합니다. “청구”는 트랜잭션 처리에 사용된 노드 리소스에 대한 청구를 의미합니다. 간단히 말해서, 주관적인 청구는 네트워크의 개별 노드가 실패한 거래에 대해 계정에 청구할 수 있도록 하며, 생산된 블록에 청구를 포함하지 않고 로컬에서 추적합니다. 주관적인 청구가 활성화된 노드에 트랜잭션이 도착하면 노드는 서명을 확인하고 어떤 계정이 서명을 보냈는지 식별합니다. 계정이 주관적인 청구 한도를 초과하면 노드가 트랜잭션을 삭제합니다.

주관적인 청구는 2019년 후반 노드 리소스 사용량이 노드를 초과한 후 도입되었습니다. 특히 노드는 서명 유효성 검사를 통과한 수많은 수신 트랜잭션을 수신하기 시작했지만 실행 중 어설션 실패와 같은 내부 검사에 실패했습니다. 이러한 실패한 트랜잭션은 실패한 트랜잭션을 검증할 때 여전히 서버 리소스를 사용하는 BP(블록 생산자) 및 API 노드를 압도했습니다. 당시 BP 노드들은 실패한 트랜잭션을 처리하기 위해 노드 리소스를 소모하느라 바빴고 많은 유효한 트랜잭션이 블록으로 만들지 못했고 일부 블록은 완전히 비어 있었습니다.

옵트인(opt-in) 주관적 청구 도구는 노드가 처리해야 하는 실패한 트랜잭션 수를 줄여 이러한 노드의 로드를 줄입니다. 그림 2는 주관적 청구가 활성화된 노드로부터의 리소스 과금을 나타냅니다.

서명 확인 후 거래 실패(2.1) 시 주관적 과금이 적용됩니다. 소량의 주관적인 청구로 거래는 여전히 성공하는 경우가 많습니다. 성공적인 거래(2.2)의 경우, 새로운 거래에 대한 일시적인 주관적 청구가 블록체인에 기록될 때 객관적 청구로 대체됩니다.

주관적인 청구가 계정 리소스(2.3)에 비해 너무 많으면 트랜잭션이 실패합니다. 블록에 들어가지 않는 실패한 거래의 경우 노드는 주관적인 청구를 청구하지만 온체인 청구는 증가하지 않습니다. 노드를 통해 라우팅된 이후에 실패한 각 트랜잭션(2.4)은 해당 노드에 대한 주관적인 청구를 증가시킵니다.

계정에는 새 거래(2.5)와 함께 주관적인 청구를 처리할 수 있는 적절한 리소스가 있어야 합니다. 이는 주관적인 청구가 24시간(2.6) 동안 감소할 때까지 해당 노드를 통해 라우팅된 모든 계정 트랜잭션에 필요한 계정 리소스를 일시적으로 증가시킵니다.

노드의 성능에 따라 일부는 다음 노드로 트랜잭션을 전달할 수 있고 다른 일부는 계정의 허용된 리소스를 초과하여 트랜잭션을 중단할 수 있습니다.

기본 주관적 청구 감소 매개변수는 일반 리소스 청구 및 PowerUp 메커니즘과 마찬가지로 24시간으로 설정됩니다. Mandel 3.1의 새로운 기능을 통해 노드 운영자는 초기화 시 노드의 주관적인 청구 소멸 시간 매개변수를 설정할 수 있습니다. 이 옵션은 계정의 주관적인 청구서를 0으로 만드는 데 걸리는 시간을 조정합니다.

많은 블록 프로듀서와 일부 API 노드는 주관적인 청구를 가능하게 했습니다. 이 채택으로 노드 CPU 사용량이 거의 90% 감소했습니다.

주관적인 청구의 해결 과제

주관적인 청구는 빈 블록을 방지하고 노드의 부하를 줄이는 데 효과적이지만 사용자 사이에 좌절과 혼란을 초래할 수 있는 부작용이 있습니다.

주관적으로 계정에 청구하는 노드는 계정에서 들어오는 트랜잭션에 대한 추가 리소스 요금으로 청구를 추가합니다. 다음에 노드가 해당 계정에서 트랜잭션을 수신할 때 계정에는 새 트랜잭션을 처리하기 전에 이전에 실패한 트랜잭션을 처리하기에 충분한 추가 리소스가 있어야 합니다. 계정에 이전에 실패한 트랜잭션에 대한 추가 리소스가 충분하지 않은 경우 노드는 서명을 확인한 다음 나머지를 실행하지 않고 트랜잭션을 삭제합니다.

그림 3에서 보여주는 바와 같이, 블록 익스플로러가 적절한 리소스를 보여줌에도 불구하고 일부 사용자는 트랜잭션을 제출할 때 반복되는 오류 메시지를 받습니다. 이것은 사용자가 자신도 모르게 계정에 주관적인 청구가 적용된 API 노드(3.1)에 연결했을 때 발생합니다. 그들의 트랜잭션은 실패하지만 적어도 사용자는 노드가 오류 메시지(3.2)를 반환할 때 뭔가 잘못되었다는 것을 알고 있습니다.

더 나쁜 것은 그림 4와 같이 오류 메시지가 없는 상황입니다. 일부 사용자는 트랜잭션(4.1)을 API 노드(4.2)에 성공적으로 제출하지만 어떤 블록에서도 트랜잭션을 볼 수 없습니다.

이는 활성 블록 생산자 노드(4.4)에 대한 릴레이 경로(4.3)에 주관적으로 청구하는 노드가 충분할 때 자주 발생하여 네트워크를 통한 전파를 방지합니다. 이러한 문제는 청구 잔액이 줄어들면서 최대 24시간 동안 지속될 수 있습니다.

실패한 거래를 계속해서 다시 제출하려고 하면 주관적인 청구 잔액이 더 늘어나고 문제가 악화됩니다. (그림 2 (2.4) 참조)

분실 트랜잭션 도구

주관적 청구는 각 노드에 국한되어 있고 주관적 과금 데이터를 공유하는 프로토콜이 없기 때문에 사용자가 트랜잭션이 사라지는 이유를 찾는 것은 사실상 불가능합니다. 개별 노드 운영자는 문제 해결에 도움이 되는 주관적인 청구 데이터 공유 도구를 구축하고 공유할 수 있지만 전체 체인(chain-wide) 솔루션이 없으면 상호 운용성이 제한됩니다.

프로토타입 데이터 공유 도구의 한 예는 실패한 트랜잭션을 조회하기 위해 EOS Nation에 의해 구축되었지만, 데이터 사일로화는 해당 툴이 자체 노드에서 처리되는 트랜잭션을 검색하도록 제한합니다. 여러분들은 https://eos.api.eosnation.io/transaction_lookup에서 확인 가능합니다. 이 도구에 제공되는 데이터 유형을 광범위하게 공유하면 사용자와 앱이 거래가 실패한 이유를 식별할 수 있으므로 특정 버그를 정확히 찾아내고 주관적인 청구로 다른 문제를 진단하는 데 도움이 됩니다.

Mandel의 릴리스에는 블록 프로듀서, 노드 운영자, 지갑 및 dApp이 새로운 기능을 사용하기 시작하는 즉시 이러한 많은 문제에 대한 수정 사항이 포함됩니다. 그러나 개발 및 채택에는 시간이 걸립니다. 다행히 개발자와 운영자는 애플리케이션과 노드가 새 업데이트를 채택할 때까지 기존 완화 사례를 워크플로우에 통합할 수 있습니다.

다음 몇 주 동안, 우리는 노드 운영자 및 스마트 컨트랙트 개발자를 위한 현재 권장 사항을 간략하게 설명할 것입니다. 또한 API+ 청서에서 제안된 몇 가지 트랜잭션 수명 주기 개선 사항을 포함하여 향후 Mandel 버전에서 출시될 일부 기능을 강조할 것입니다.

현재로서는 운영자들이 잠재적 솔루션들을 테스트하는 데 사용할 수 있는 빠른 참조로 다음을 제공하고 있습니다. 우리는 다음 기사에서 이러한 제안 사항들을 더 자세히 살펴볼 것입니다.

주관적인 청구 문제 및 거래 손실 해결을 위한 빠른 참조:

각 노드 운영자는 실패한 트랜잭션을 너무 많이 보낼 것 같지 않은 계정을 결정할 수 있으며, 다음을 사용하여 해당 계정에 대한 주관적인 청구를 비활성화할 수 있습니다.
   disable-subjective-account-billing = <accountname>

그에 대한 예는 노드 운영자가 “신뢰할 수 있는” 충분한 비율 제한 혹은 Sybil 저항이 충분하다고 결정할 수 있는 Greymass Fuel이 될 수 있습니다. 운영자는 다음을 사용하여 Greymass Fuel에 대한 주관적 청구를 비활성화 합니다.
예: disable-subjective-account-billing = greymassfuel
‎‎

nodeos 2.x의 구현과 관련된 알려진 문제 때문에 disable_subjective_api_billingdisable_subjective_p2p_billing 옵션 매개 변수를 사용하는 노드는 둘 다 true이거나 false인 동일한 부울 값(Boolean value)으로 설정해야 합니다. Mandel 3.1 릴리스는 이러한 문제를 해결할 것으로 예상됩니다.
‎‎

그렇지 않으면, 운영자는 disable-subjective-billing = true 옵션을 사용하여 주관적인 과금을 완전히 해제할 수 있습니다. 

클라우드 노드는 database-map-mode = heap 을 사용하여 스왑 파티션을 tmpfs로 마운트하여 디스크 읽기 및 리소스 사용을 줄일 수 있습니다.

스마트 컨트랙트는 assert()check() 기능을 피해야 하는데, 둘 다 거래 실패를 유발하여 주관적인 청구로 이어질 수 있기 때문입니다. 대신 개발자는 모든 청구서가 객관적이고 온체인인지 확인하기 위해 리턴 명세서(return; statements)를 사용할 수 있습니다.


EOS 네트워크

EOS 네트워크는EOS VM을 기반으로 하는 3세대 블록체인 플랫폼으로 저지연, 고성능, 확장성이 뛰어난 Web Assembly 엔진으로, 최적의 Web3 사용자 및 개발자 경험을 제공하며, 결정적으로 저렴한 수수료를 통해 이용할 수 있도록 특별히 설계되었습니다. EOS는 EOS 네트워크 재단(ENF)을 통해 도구 및 인프라에 대한 멀티 체인 협업 및 공공재 펀딩의 원동력 역할을 하는 EOSIO 프로토콜의 대표 블록체인 및 금융 센터입니다.

EOS Network Foundation

EOS Network Foundation(ENF)은 EOS 네트워크의 성장과 발전을 장려하기 위해 재정 및 비재정적인 지원을 구성합니다. 저희는 긍정적인 글로벌 변화를 위한 힘으로서 EOS 네트워크의 조직화된 미래를 계획하기 위해 탈중앙화의 힘을 활용하고 있습니다.​