Unitrie와의 더 높은 온-체인 확장성을 위하여
RSK는 2015년에 이더리움과 호환 가능한 비트코인 사이드체인으로 탄생했습니다. 2016년에 RSK 사이드체인이 아직 개발 중이었을 때, 저희는 이더리움의 주요 요소 중 하나이자 이더리움의 옐로우 페이퍼에서 “월드 스테이트” 트리라고 불리기도 하는 계정 트리를 대체해 RSK의 디자인을 개선하고 간소화하기로 했습니다. 월드 스테이트 트리는 이더리움과 비슷한 블록체인의 주요 데이터베이스이며, 이를 지지하는 데이터 구조는 “안전하고 수정된 패트리샤 트리”라고 불립니다. 저희는 현재 Unitrie(유니트리)라고 불리는 형태로 진화한 대체 상태 데이터 구조를 설계했습니다.
laBitConf(2016)에서 Unitrie를 소개하는 Sergio Lerner (RSK Labs)
(기존) Unitrie의 일부 주요 특성은 다음과 같습니다.
- 16진수 트리가 2진 (2진법) 트리로 대체되었습니다.
- 임의 길이 값은 저장 셀에 보관될 수 있습니다.
- 모든 트리는 통합되어 컨트랙트 저장 셀을 계정 셀에 합쳐서 우리가 “Unitrie(유니트리)”라고 부르는 더 큰 단일 데이터 구조가 됩니다.
- 링크는 마지막 업데이트 타임 스탬프(“lastUpdateTimestamp” 필드)가 찍혀 강화되고, Unitrie는 그 결과 저장소 임대료와 노드 자동 동면을 지원하게 됩니다.
- 각 자녀 노드의 프리픽스는 그 부모 노드에 저장됩니다. 이는 동면에 따른 리프 노드 제거를 활성화해 데이터 폐기를 최대화합니다. 이는 또한 병렬 거래 처리의 크로스 노드(교차) 부작용을 방지합니다.
- 키는 10바이트 (80 비트) 해시 프리픽스가 붙어 “프리픽스로 안전이 보장”되고 트리 불균형을 방지하나, 해시된 프리픽스 다음에 여전히 풀 키(해시 프리이미지)를 포함하게 됩니다.
- 노드는 자신의 페이로드 사이즈를 저장합니다.
- 노드는 그 서브 트리가 얼마나 큰 바이트를 소모하는지를 저장합니다.
- 특정 노드가 데이터베이스가 독립적으로 저장되기에는 크기가 너무 작은 경우, 그 노드는 자신의 부모 노드에 내장됩니다. 이는 노드를 레퍼런스하는 데 사용되는 32 바이트 해시 다이제스트를 절약해 줍니다.
Unitrie의 혜택 일부는 말할 필요 없이 분명하지만, 나머지는 좀 더 미묘합니다. 다음은 주요 개선 사항의 목록입니다.
- 전체 디자인의 간소화.
- 구현의 복잡함을 줄임에 따라 컨센서스 실패의 위험을 줄일 수 있음.
- 라이트웨이터 클라이언트의 디자인 간소화.
- 병렬 처리가 더욱더 쉽게 가능하며 악의적인 상태 제공자에 강력해져 상태 동기화 (빠른 동기화/워프 동기화라고도 불리는) 소요 시간을 줄임.
- SPV 클라이언트와 SPV 브리지를 위한 더 간단한 사기 방지 기능 활성화.
- 더 간단한 상태 쓰레기 수집 활성화.
- 각 저장 셀당 컨트랙트 임대료 활성화.
- 각 저장 셀당 동면 및 시동 활성화.
- 각 저장 셀당 충돌 감지를 포함하는 병렬 수행 활성화.
- 코드 데이터 회수 없이 빠른 EXTCODESIZE 요청 활성화.
RSK Labs는 2016년 11월 4-5일에 laBitConf에서 RSK Blockchain을 위해 Unitrie 디자인을 제안하고 간단하게 소개했습니다. 그러나 RSK 메인넷이 아직 런칭하지 않은 상태에서 그 당시 저희의 우선 사항은 이더리움 개발 도구와 더 큰 호환성을 유지하는 것이었습니다. 따라서 Unitrie 구현을 미루기로 하고 트리 데이터 구조에 16진수 대신 2진 사용과 임의 길이 값 보관 두 가지의 주요 변화만을 실행했습니다. 2진 사용은 풀 데이터베이스 이동 대신에 트리의 역동적인 변환을 통해 미래의 Unitrie로의 이동을 가능하게 합니다. 지금 저희는 대부분의 구조 부분을 유지하는 전체 트리 구조의 빠른 이동을 테스트하는 중이므로, 이는 결과적으로 현명한 선택이었습니다.
2017년 말에는 Vitalik이 이더리움 포럼에서 저희가 생각한 것과 비슷한 변화를 제안하고 있는 것을 보고 놀랐습니다. Vitalik은 또한 통합된 상태 트리의 혜택을 강조했습니다. 이는 트리 통합이 전체적으로 훨씬 더 나은 디자인이라는 저희의 초기 가설을 뒷받침하는 내용이었습니다.
Vitalik의 통합 상태 트리(2017)에 대한 제안
시간이 됐습니다
RSK Blockchain은 2019년 1월에 첫 번째 생일을 맞았으며, 1년 간 100%의 가동 시간을 달성했습니다. 따라서 저희는 다음 네트워크 업그레이드 시에 Unitrie 데이터 구조의 채택을 위한 노력을 계속 진행하기로 했습니다. 저희는 기존 RSKIP을 수정하고 개선해 새로운 RSKIP와 레퍼런스 구현을 만들었습니다. 이 글은 저희가 제안하는 이 변경 사항이 어떻게 RSK 커뮤니티에 도움이 될지를 설명하고자 하는 노력의 일환입니다. 저희는 RSKIP16을 업데이트하고, RSKIP107, RSKIP108 및 RSKIP109를 추가했습니다. RSKIP107 은 트리 노드가 저장되었을 때 압축되는 방법을 설명합니다. RSKIP108 은 계정 주소와 저장 셀이 어떻게 트리 키에 매핑되는지를 설명합니다. RSKIP109 은 저장 셀 기록 비용을 재정의해 더 짧은 저장 주소의 사용을 인센티브화합니다. 저희는 또한 이 모두를 한꺼번에 구현하고 검사했으며, 상태 업데이트에서 동기화에 이르기까지 노드 성능과 메모리 소비가 눈에 띄게 개선된 것을 확인했습니다. 그러나 검사 중 모든 것이 다 잘 진행된 것은 아닙니다. 예를 들어 저희는 저희가 한 제안에서 트리 노드 프리픽스를 부모 노드로 이동하는 아이디어를 배제하기로 했습니다. 그 이유는 이러한 변화가 트리 구조의 유사성에 의존하는 새로운 트리와 기존 트리 간의 빠른 변환을 더 복잡하게 한다는 것이었습니다.
저희는 하드 포크와 연관된 위험을 줄이기 위한 최고의 전략이 변화를 두 개의 연속적인 네트워크 업그레이드로 나눠 진행하는 것이라고 생각합니다. 첫 번째 업그레이드는 2019년 Q2에 진행되어 Unitrie, 프리픽스 보호 키, 페이로드 사이즈 캐시, 트리 사이즈 캐시 및 노드 디스크 압축을 포함할 예정입니다. 두 번째 업그레이드는 2019년 Q4에 진행되고 저장소 임대료 최종 업데이트 타임 스탬프를 포함할 예정입니다. 저장소 임대료 RSKIP이 아직 최종적으로 완성되지 않았고, 첫 번째 네트워크 업그레이드가 완전한 트리 이동을 요구하는 반면 두 번째 네트워크 업그레이드 내 변화는 새롭게 생성된 트리에만 영향을 미치므로(트리 이동이 필요하지 않음), 저장소 임대료 관련 기능은 향후로 미룰 예정입니다.
단 하나뿐인 특별한 네트워크 업그레이드
계정과 저장 노드을 하나의 트리로 완전 통합하는 것은 하드 포크로만 달성이 가능한 작업입니다. 이는 즉 대부분의 채굴자가 이 변화를 지원하기 위한 업그레이드를 진행해야 하며, 모든 풀 노드 역시 동기화를 유지하기 위해 업그레이드되어야 함을 뜻합니다. 그러나 Unitrie 업그레이드는 플랫폼 경제에 관련된 변화를 뜻하지는 않습니다. 물론 실제 저장 비용과 청구 비용을 더 정확하게 매치할 수 있게 하기 위해 저장 비용이 약간 줄어들기는 할 예정입니다. 이 변화는 커뮤니티 내 모든 행위자에게 도움이 될 것입니다. 또, 이러한 변화는 플랫폼의 보안이나 프라이버시에 영향을 주지 않습니다. 대부분의 개발 도구와 월렛은 월드 스테이트의 내부 구조를 사용하지 않으므로 이러한 하드 포크의 영향을 받지 않음을 참고하시기 바랍니다.
이러한 업그레이드 메커니즘의 단점은 기존의 풀 노드 상태 데이터베이스가 새로운 데이터베이스와 더이상 호환되지 않는다는 점입니다. 기존 트리와 새로운 트리 모두와 호환되는 풀 노드를 만드는 것은 어렵고 혜택이 적은 작업입니다. 좋은 소식은 여러 성능 개선으로 인해 새로운 완전 동기화에는 이전보다 훨씬 짧은 시간이 소요될 것이라는 점입니다. 저희는 또한 소프트웨어 업그레이드 이후에도 노드가 거의 방해 없는 운영 시간을 유지할 수 있게 노트 스타트업에서 상태 데이터베이스를 새로운 형식으로 이동하는 테스트를 마친 상태입니다.
Unitrie (유니트리)
Unitrie는 모든 컨트랙트의 저장 셀과 계정 정보를 통합합니다. 이는 컨트랙트 저장 셀을 컨트랙트의 저장 주소에 부합하는 노드에 루트된 서브트리의 리프(잎)으로 저장합니다. 이는 또한 컨트랙트 정보를 여러 가지의 개별적인 트리 서브 노드로 분할하기도 합니다. 다음의 간소화된 도표는 자녀가 없는 하나의 계정(ECDSA 통제)과, 컨트랙트 코드를 저장하는 자녀 노드가 하나 있는 컨트랙트, 그리고 실제 저장 셀을 포함하는 자녀 서브트리를 나타내고 있습니다.
블록체인 상태의 예제 Unitrie
이 트리의 차이점은 계정과 컨트랙트 저장의 통합뿐만이 아닙니다. 키의 매핑 또한 다릅니다. 그럼 이더리움 계정 트리가 어떻게 작용하는지를 다시 되새겨보도록 합시다. 이더리움 계정 트리는 계정 주소의 해시 다이제스트를 값을 반환하는 키로 사용해 “보호”합니다. 이때 트리의 노드는 계정 주소뿐만 아니라 그 해시 다이제스트로도 분류됩니다. 이 주요 변화는 공격자가 데이터 구조에 트리를 긴 체인으로 퇴화시키는, 점점 커지는 키 프리픽스를 공유하는 값으로 스팸 공격을 하는 것을 방지하기 위해 시행됩니다. 이러한 공격은 풀 노드가 특정 검색을 훨씬 느리게 수행하도록 강제하거나, 특정 트리 통합 증명의 사이즈를 늘릴 수 있습니다. Unitrie에서 키는 80 비트 해시 다이제스트 프리픽스에서 구축되어, 그 뒤에는 완전한 일반 계정 주소가 따르게 됩니다. 이때 트리에 키를 분산시키기고 확률적인 균형을 유지하기 위해 80 비트만이 사용됩니다. 트리 퇴화 공격의 영향이 최소화됨에 따라 80 비트는 공격을 비인센티브화하는 데 충분합니다. 이러한 공격은 ASIC 기반의 특별한 해시 프리픽스 억지 기법 설계를 필요로 합니다. 이는 작업 증명 채굴자와 비슷하며 이러한 “채굴” 박스 수백만 개를 제조하게 됩니다. 최첨단 비트코인 기계가 임의의 80 비트 프리픽스 프리 이미지 검색을 수행할 수 있다고 가정했을 때, 해당 공격자는 80개의 서로 다른 80 비트 포지션에서 충돌을 찾아 트리를 살짝 퇴화시키기 위해 전기료로 약 USD 6백만 달러를 소비해야 할 것입니다. 그러나 이러한 공격이 블록 처리 시간에 미치는 영향을 아주 적을 것이며 (캐시로 인하여), 불균형한 계정의 통합 증명은 2 킬로바이트밖에 증가하지 않게 됩니다.
이렇듯 새로운 매핑의 혜택은 상태에 계정 주소와 저장 셀 주소를 유지 보유해, 여러 데이터 수집 응용 프로그램이 블록체인 전체를 인덱스하지 않고도 사용자에게 의미 있는 정보를 소개할 수 있게 한다는 것입니다. 다음 도표는 계정 및 저장 주소의 트리 키로의 변화를 나타내고 있습니다.
계정 및 저장 주소의 트리 키로의 변화
전체 그림을 정확하게 소개하기 위해 각 데이터 유형이 Unitrie에 어떻게 매핑되는지를 보여드리겠습니다.
키 | 값 | 설명 |
0x00
SHA3(account_addr)[0:9] account_addr |
RIp (임시값, 양, 플래그) | 계정 상태 |
0x00
SHA3(account_addr)[0:9] account_addr 0x80 |
바이트 배열 | 계정 코드 |
0x00
SHA3(account_addr)[0:9] account_addr 0x00 |
0x00 | 저장 트리 격리를 위한 견본 플레이스 홀더 |
0x00
SHA3(account_addr)[0:9] account_addr 0x00 SHA3(storage_address)[0..9] trimmed_storage_address |
바이트 배열 | 저장 셀에서의 값 |
첫 번째 제로 바이트는 이 트리를 특별한 네임스페이스에 저장하는 데 사용됩니다. 이는 다른 네임스페이스가 충돌의 위험 없이 활용될 수 있는 향후 개선을 가능하게 합니다. 미래에 개선을 통해 고유 네임스페이스를 차지할 수 있는 다른 몇 가지는 다음과 같습니다.
- 트리로 확장되는, 기존 블록 해시 모두의 특별 노드를 저장해 작업 증명의 증명과 (NiPowPow) 건너뛰기 목록 활성화하기
- 보안 강화를 위해 더 긴 키 길이(예: 256 비트)의 계정 주소 레퍼런스하기
- RSKIP32의 정의에 따라 더블 해시 주소를 사용해 계정 주소 레퍼런스하기
RSKIP16 Unitrie와 Vitalik의 제안 내용 간에는 많은 차이점이 있습니다. 하나 다른 점은 Unitrie가 임시값과 양을 서로 다른 노드에 저장하지 않고 함께 저장한다는 것입니다. 이에 대한 이유는 다음과 같이 여러 가지입니다.
- 이 두 가지 필드의 직렬화와 역직렬화에는 많은 시간이 소요되지 않으므로, 더 큰 분할은 계정 상태 반환에 디스크 액세스를 추가함에 따른 효율성 감소를 일으킵니다.
- 미래에 컨트랙트 변화를 추적할 수 있게 컨트랙트의 특정 주소에 일부 데이터를 보유하는 것이 더 낫습니다.
- 계정은 트리에 “스팸 공격”을 하는 데 사용될 수 있으므로, 계정이 차지하는 공간을 줄이는 것이 중요합니다.
Unitrie RSKIP 구조
Unitrie는 9개의 RSKIP으로 정의됩니다 (RSK 개선 제안). 각 RSKIP은 Unitrie 내 특정 구성 요소를 설명합니다. 이는 구조, 저장/저장소, 키 매핑, 저장소 임대료, 동면, 가스 비용입니다. 다음 도표는 이러한 구분을 나타내고 있습니다.
Unitrie 관련 RSKIP
첫 번째 네트워크 업그레이드에서는 4개의 RSKIP만이 배치될 예정이며, 나머지는 다음 네트워크 업그레이드 시로 미룰 예정입니다. 이는 이동 위험을 최소화할 수 있도록 보장합니다.
Unitrie에 포함되지 않은 것
저희는 Unitrie에 대한 기존 의논 도중 노드 데이터의 프리픽스를 두 개의 서로 다른 노드로 분리하는 것이 터치되지 않은 트리 브랜치의 완전한 불역성을 유지하는 데 도움이 되고, 트리 업데이트의 더 세분화된 병렬화(평행화)를 활성화할 수 있다고 판단했습니다. 저희는 이 구조를 PDB 트리라고 부르기로 했습니다. 구조상 노드가 다음 세 가지의 해체 유형 중 하나를 따를 수 있기 때문입니다. 프리픽스, 데이터, 또는 브랜치가 그것입니다. PDB 트리로의 전환이 아주 큰 구조적 변화를 요구하므로, 이는 Unitrie 제안 내용에서 빠져 있습니다. 그러나 PDB 트리는 더 자세한 연구를 필요로 하는 주제가 될 수 있다고 생각합니다.
블록체인 상태를 저장하는 데 사용되는 샘플 PDB
그럼 이제 RSK Unitrie의 각 혜택을 더 자세히 의논해 보도롭 합시다.
더 짧은 멤버십 증명
RSK 트리 내 계정의 멤버십 증명은 16진수 트리 대신 2진법 트리를 사용해 가장 최대로 짧아지는 동시에 멤버십 증명 검증에 걸리는 시간 또한 최대로 최적화할 수 있습니다. 이는 휴대폰에서 작동하는 분산화된 라이트웨이트 노드를 활성화해 더 적은 대역폭과 전력 소모가 가능합니다. 다음 예제 도표에 나타난 타깃 노드(파란 원)의 존재 증명을 위해서 16진수 트리에는 포인터(도넛) 30개와 노드(원) 3개가 필요합니다. 반면 2진 트리에는 포인터 8개와 노드 8개만이 필요합니다. 전송된 노드는 부모 레퍼런스 전송을 필요로 하지는 않으나, 해당 레퍼런스는 역동적으로 산출될 수 있으므로, 2진 트리 증명은 16진수 트리가 차지하는 공간의 26%만을 차지하게 됩니다.
16진수 트리 멤버십 증명과 2진 트리 멤버십 증명의 비교
계정 노드 압축으로 인한 상태 사이즈 축소
Unitrie 내 계정은 “저장” 트리 루트 해시 다이제스트를 저장할 필요가 없을 뿐만이 아니라 코드 해시 다이제스트도 저장할 필요가 없으며, 이는 상태에서 60% 가까이의 계정 데이터가 제거됨을 뜻합니다. 예를 들어, 1 RBTC를 저장하는 계정은 이더리움에서 소모되는 104 바이트 대신에 약 38 바이트만을 소모하게 되는 것입니다. 다음 도표는 불필요한 필드 제거를 통한 대략적인 공간 절약을 나타내고 있습니다.
불필요한 필드를 제거해 계정 노드 압축
작은 노드를 내장해 상태 사이즈 축소
사이즈가 ~44 바이트 미만(정확한 값은 TBD)인 자녀 노드의 경우, Unitrie는 이를 부모 노드에 직접 내장시킬 수 있는 기능을 제공합니다. 이 기능은 RSKIP107에서 설명되어 있습니다. 대부분의 계정은 31에서 41 바이트 사이 사이즈의 노드를 가지게 되므로, 이는 대부분의 계정이 부모 노드에 내장될 것임을 뜻합니다. 이는 계정 오버헤드를 62% 감소시킵니다. 노드 내장과 더 짧은 계정 기록이 통합적으로 제공하는 계정 사이즈 축소는 81%에 달하며, 이는 풀 노드의 리소스 요건과 동기화 시간을 줄이는 것뿐만이 아니라 상태에 계정 생성을 통한 스팸 공격을 하는 DoS 공격의 위험 또한 줄여줍니다. 다음 예제 도표는 이더리움 트리 내에서 두 개의 자녀 노드를 가진 노드가 Unitrie에서 자녀 노드가 내장된 단일 노드로 변환되는 과정을 나타내고 있습니다.
두 개의 작은 노드를 부모 노드에 내장함
저장 셀 키 압축으로 인한 상태 사이즈 축소 및 더 낮은 가스 비용
저희의 RSKIP108은 저장 키가 긴 제로 프리픽스를 보유하고 있을 때 저장 셀이 압축될 수 있는 방법을 설명하고 있습니다. 단일 바이트 주소를 보유하고 단일 바이트를 저장하는 셀은 작은 사이즈가 노드 내장을 활성화하므로 압축 전 기존 사이즈의 10%까지 압축될 수 있습니다. RSKIP109는 사용자가 압축된 저장소를 사용하는 것을 인센티브화하기 위해 기록 작업 비용을 컨트랙트 저장소에 업데이트합니다. 예를 들어, 주소 0x00에 0x01을 저장하는 것은 이더리움에서의 20K(2만 개) 대신 5460 가스(연료) 단위만큼 낮은 양만을 소모하게 됩니다. 다음 도표는 저장 셀 주소 0x01이 이더리움과 Unitrie에서 서로 다른 키를 사용하는 경우를 나타내고 있습니다.
키 저장 압축 예제
거래 병렬 처리와 통합되면 확장성이 더 커짐
저희의 RSKIP04는 블록 처리 시간을 줄이기 위한 거래 병렬 처리를 제안합니다. 블록 처리 시간을 줄이면 블록을 더 빠르게 전파하고 컨센서스를 개선할 수 있습니다. 이는 또한 블록 전파를 지연시키지 않고도 블록에 더 많은 거래를 넣을 수 있다는 것을 뜻합니다. 일반적으로 더 긴 블록 전파 지연 시간은 작은 채굴 풀보다 더 큰 채굴 풀에 유용하므로, 분산화를 타협하지 않고도 스케일링을 할 수 있다는 점이 안심되는 사실입니다. 그러나 블록체인은 체인 내 거래의 컨트랙트 상태 액세스가 중복되지 않는 세트로 분할될 수 있어야만 병렬 거래 처리의 혜택을 누릴 수 있습니다. 체인 내 거래가 모두 단일 토큰 컨트랙트만을 불러온다면, 그 컨트랙트는 거래의 직렬화를 강제해 매우 번잡해집니다. RSKIP59에서 특별히 설명된 솔루션 하나는 컨트랙트 저장 셀이 서브 컨트랙트로 이동되어 부모-자녀 관계를 맺도록 컨트랙트를 설계하는 것입니다. 서로 다른 사용자의 토큰 잔액은 서로 다른 컨트랙트에 저장됩니다. 그러나 이 솔루션은 여전히 확장성 보장을 위해 특정 디자인 패턴 사용을 강제하는 컨트랙트 재설계 및 재구현을 필요로 합니다. 그러나 Unitrie는 새로운 패턴을 사용해야 한다는 장애물 없이도 문제를 해결할 수 있을 수 있습니다. Unitrie는 풀 컨트랙트의 동시 접근만을 탐지하는 대신 저장 셀의 병행 주소의 간소화된 탐지를 활성화합니다. 이는 두 개의 거래가 같은 저장 셀을 기록하지 않는 한 (아니면 하나가 다른 하나가 기록한 셀을 읽는 한) 둘 다 동시에 수행될 수 있음을 뜻합니다. 예를 들어 ERC20 컨트랙트는 일반적으로 출처와 목표 계정에 관련된 셀만을 변화시키며, 이러한 컨트랙트는 셀 수준 탐지와 함께 즉각적인 병렬화 능력을 갖게 됩니다. 이러한 기능은 Unitrie 없이도 사용 가능할 수 있으나, Unitrie의 존재는 충돌 탐지 알고리즘을 기록하는 방식을 엄청나게 간소화시킵니다. 그 예로 다음 도표는 거래를 처리하는 두 개의 스레드를 나타내고 있습니다. 첫 번째 스레드는 스레드 2의 영향을 받지 않는 컨트랙트 C (보라색 화살표가 가리키는)의 셀을 수정합니다. 그리고 스레드 2는 같은 컨트랙트에서 두 개의 다른 셀을 수정하며, 이는 스레드 1이 수정하는 셀에 영향을 주지 않습니다.
같은 컨트랙트 저장소를 수정하는 두 개의 수행 스레드
저장소 임대료와의 결합을 통해 더 큰 공정성 유지 가능
이더리움 디자인에 따라 발생하는 한 가지 특성은 가스 임의화를 활성화한다는 것입니다. 사용자는 이에 따라 유용한 데이터를 저장하지 않고도 저장 셀을 미리 구입하고 차지하여, 나중에 셀을 비워서 구입에 사용한 가스 일부를 돌려받고 가스를 제3자에게 판매할 수 있습니다. 의도하지 않게 탄생한 이 디자인의 또 다른 특징은 이더리움이 새로운 저장 셀 사용에 비싼 사전 지불금을 요구한다는 것입니다. 이 지불금이 키/값 한 쌍의 영구적인 저장과 활성 보장에 사용되기 때문입니다.
저장소 임대료는 두 가지 문제 모두를 완화합니다. 가장 많이 의논되고 수락된 형태의 저장소 임대료는 사용자가 컨트랙트와 작용해 해당 컨트랙트가 비활성화된 시간에 비례하고, 비활성화 시간 중 컨트랙트가 차지하는 메모리 공간에 비례하는 수수료를 지불하게 하는 것입니다. RSKIP61은 플랫폼의 공정성에 영향을 주는 기존 EVM 디자인의 부정적인 영향을 방지하기 위한 컨트랙트 임대료 사용을 제안합니다. 이는 확률적인 공정함을 제공하는 대신 세분화되지 않았으며 에지 케이스에서 사용하기 힘든 방식입니다. 수백만 개의 수 많은 키/값 페어를 저장하고 있으나 자주 사용되지 않는 크라우드 소유 컨트랙트는 장기적인 비사용 기간 후 처음으로 이를 불러오는 사용자에게 지나친 저장소 임대료 부담을 가져오게 됩니다. Unitrie는 개별적인 저장 셀의 마지막 접근 시간을 추적하는 작업을 간소화해 저장소 임대료가 세분화될 수 있게 하며, 컨트랙트가 콜(불러오기) 실행에 연관된 셀에 대한 임대료만을 지불할 수 있게 합니다. RSKIP113이 대표하는 이러한 간소화는 모든 노드가 동등하게 다루어져 계정, 코드 및 저장 셀이 액세스되었을 때 임대료를 소모할 수 있음에 따라 가능한 작업입니다.
더 간소하된 상태 쓰레기 수집과 함께 더 높아지는 완전성
상태 쓰레기 수집은 이미 덮어쓰기가 되어 정상적인 상태 아래 다시는 레퍼런스될 일이 없는 오래된 상태 데이터를 제거하는 것입니다. 커다란 블록체인 재정비와 같은 예외적인 이벤트 발생 시에 이 데이터는 사전 산출된 상태 체크포인트에서 기존 블록을 재수행하여 재산출될 수 있습니다. 그러나 이더리움 내 쓰레기 수집은 단순한 문제가 아닙니다. 각 활성화된 컨트랙트마다 하나씩 개별적인 여러 데이터베이스(또는 트리)에 적용되어야 하기 때문입니다. Unitrie의 사용은 그러한 쓰레기 수집이 단일 데이터베이스에만 적용됨을 뜻하며, 쓰레기 수집 중 데이터베이스를 변경해 일관성이 없는 상태로 방치하는 스레드 방해 위험을 줄일 수 있음을 뜻합니다.
더 빠르고 간단한 상태 동기화
특정 블록 높이에서 블록체인 상태를 조회해야 하는 응용 프로그램에는 라이트웨이트 월렛에서 블록체인 브리지에 이르기까지 여러 가지가 있습니다. Unitrie의 2진법 구조는 상태 데이터의 멤머십을 반환하고 증명하는 데 최소한의 공간 소모와 최대한의 성능을 제공합니다. 이는 또한 상태 정보 전송에 연관된 네트워크 명령의 복잡함을 줄여줍니다.
그러나 Unitrie는 가장 중요하게도 “빠른 동기화” 또는 “워프 동기회”를 수행하기 위해 상태 정보의 더 빠른 병렬 다운로드를 활성화합니다. 모든 정보가 단일 트리에 저장되면 노드는 상태 정보를 더 효율적으로 불러올 수 있습니다. Unitrie가 각 노드에 루트된 서브트리가 소모하는 바이트 수를 저장하면, Unitrie 데이터 구조는 사이즈 범위 조회를 지원합니다. 피어는 이를 아무 바이트 오프셋에서나 시작하는 특정 사이즈의 트리 “패킷”을 요청하는 데 사용할 수 있습니다. 따라서 요청은 처리량의 균형이 잘 잡힌 상태에서 병렬화될 수 있습니다. 예를 들어 특정 노드는 10개의 노드에서 상태 정보를 수집하고, 첫 번째 노드에서 0K에서 100K 바이트 범위를 요청하고, 두 번째 노드에서는 100K에서 200K 범위를 요청할 수 있게 됩니다. 이는 빠른 동기화의 혜택(반환된 데이터의 즉각적인 검증)과 워프 동기화의 혜택(여러 출처에서 동시에 커다란 데이터 청크를 가져옴)을 결합한 동기화 모드를 생성할 수 있게 합니다. 다음 됴포는 노드 서브 트리 사이즈를 표시한 예제 Unitrie를 나타내고 있습니다. 이 트리는 각자 거의 동일한 양의 데이터를 포함하는 세 개의 청크로 분할되어, 각자 서로 다른 피어에게 요청될 수 있습니다. 요청자가 각 청크의 내용과 한계를 모른다고 해도, 청크의 사이즈는 해당 요청자에게 미리 알려집니다. 각 청크는 수신했을 때 효율적이고 독립적으로 검증될 수 있습니다. 일부 내부 노드는 검증을 위해 하나 이상의 청크에 포함되어 있습니다.
세 개의 독립적으로 검증 가능한 청크로 나뉘어진 상태 Unitrie
Unitrie의 또 다른 커다란 혜택은 트리 노드 사이즈를 저장함으로써 네트워크 노드가 상태 동기화 완료 퍼센티지를 표시할 수 있으며 동기화 완료까지 남은 시간을 예상할 수 있다는 것입니다.
자동 코드 중복 제거를 통한 더 작은 블록체인
저장 셀과 코드를 하나의 컨텐츠 주소가 있는 데이터베이스로 통합함으로써, 동일한 키/값을 포함한 노드는 데이터베이스에 단 한 번만 저장됩니다. 이는 자동 데이터 중복 제거를 제공하여, 컨트랙트 코드의 경우 개별적인 중복 제거 메커니즘이나 데이터 압축 기술을 사용하지 않고도 블록체인 사이즈를 축소할 수 있습니다. 트리 내 코드 노드는 항상 같은 프리픽스를 포함하게 됩니다(0x80). 따라서 동일한 코드는 동일한 노드 해시와 동일한 저장을 뜻합니다.
더 빠른 EXTCODESIZE 수행
각 Unitrie 코드 모두는 해당 노드에 저장된 데이터의 사이즈를 캐시하는 필드를 포함합니다. 이더리움 트리에서 노드 데이터 사이즈를 조회하는 것은 강제로 데이터베이스에서 데이터를 불러오게 합니다. Unitrie는 이 새로운 필드를 조회해 하드 디스크에서 코드를 가져올 필요 없이도 EXTCODESIZE 연산 코드가 생성하는 것과 같은 사이즈 조회에 응답할 수 있습니다. EXTCODESIZE 연산 코드는 기존에 특정 이더리움 구현에 DoS 공격을 수행하는 데 사용된 적이 있으며, Unitrie는 이러한 공격에 대한 면역력을 제공합니다.
업그레이드 방식의 세부 내용
그 어떤 블록체인도 상태 데이터베이스가 블록 헤더에 헌신하고 있는 상태에서 상태 데이터베이스를 변경하는 업그레이드를 수행한 적은 없습니다. 따라서 이 업그레이드는 최초의 특별한 업그레이드가 될 것입니다. 이 업그레이드는 초기에 두 단계로 나뉘어 진행됩니다. 새로운 소프트웨어 출시는 새로운 상태 트리에서 기존 트리로의 구조적인 온 더 플라이 (그때그때마다) 변환을 시행하는 역동적인 알고리즘을 활용해 새로운 트리 루트를 산출하는 대신 여전히 기존 트리 루트를 파생할 예정이며, 그 후에는 새로운 상태 루트가 인정되고 검증되는 하드 포크가 진행되고 역동적인 변환은 더이상 발생하지 않을 예정입니다. 실제로 변환되어야 하는 것은 상태 트리뿐만이 아니라 거래 및 영수증 트리도 포함합니다.
성공적인 네트워크 업그레이드를 위해서는 여러 가지 이벤트가 발생해야 합니다. 풀 노드 소프트웨어의 새로운 버전은 타임 R 시기에 출시될 예정입니다. 새로운 출시 버전은 타임 C에 제네시스 블록에서 특정 블록으로의 주기적 체크포인트를 포함합니다. 타임 C는 타임 R 전에 발생합니다. 그리고 그 전에는 타임 H에 하드 포크 전에 노드가 업그레이드되는 간격이 있을 예정입니다. 다음 도표로 타임라인을 설명해 보았습니다.
Unitrie의 네트워크 업그레이드 타임라인
새로운 출시본(0.7.0이라고 불림)이 설치되면 풀 노드는 새로운 규칙에 따라 상태 데이터베이스를 재구축해야 합니다. 이때 현재 상태를 이동시키거나, 제네시스에서 최고의 체인 팁으로 모든 블록을 재처리해 상태를 다시 산출할 수 있습니다. 저희는 RSK 업그레이드에 재처리를 선택했습니다. 이는 기존의 데이터베이스가 어떤 방식으로든 손상이 된 경우에도 모든 풀 노드의 데이터베이스가 완벽하게 동기화되어 있음을 보장합니다.
이벤트 C는 하드 포크 약 2주 전에 발생하게 선택되었습니다. 사용자는 출시 날짜 R 이후에, 그러나 하드 포크 날짜 H 전에 풀 노드 소프트웨어를 업그레이드해야 합니다. C-H 기간 중에 노드는 기존 트리 상태 루트와 새로운 트리 상태 루트를 모두 산출할 것입니다. 기존의 상태 루트는 새로운 상태 트리로부터 역동적으로 산출될 것입니다. 라이트웨이트 노드(또는 SPV 노드)는 이 짧은 간격 동안 CPU 처리량을 줄이기 위해 상태 루트를 검증하지 않기로 할 수 있습니다. 이는 라이트웨이트 노드가 어차피 해시레이트를 따라가기 때문입니다. 노드는 또한 예를 들어 상태 루트 인증 10개마다 1개만을 검증하는 방식으로 C-H 기간 중 검증 오버헤드를 줄일 수 있습니다. 그러나 하드 포크 이후 첫 번째 블록은 더이상 기존의 상태 루트를 산출하거나 검증하지 않을 것입니다. 커뮤니티가 승인하기만 한다면 굉장히 클린한 하드 포크 이벤트가 발생할 것을 예상하고 있습니다.
요약
RSK가 2016년에 제안한 Unitrie는 RSK 같은 계정 기반 블록체인의 상태 저장을 크게 개선해 더 나은 풀 노드 성능을 제공하는 방식입니다. Unitrie는 풀 노드리소스 요건을 축소해 분산화를 개선하고, 더 나은 거래 병렬 수행을 활성화해 거래 처리량을 개선하며, 페이로드 사이즈를 캐시하고 계정 사이즈를 축소해 DoS 공격을 방지하고, 더 나은 저장소 임대료를 가능하게 해 공정성을 높이며, 상태를 압축해 동기화 시간을 줄여줍니다.
저희는 Unitrie를 사용하기 위한 네트워크 업그레이드를 수행하는 것이 어려운 일임을 알고 있습니다. 하지만 이와 같은 변화를 일으킬 올바른 시기가 되었다고 생각합니다. RSK 커뮤니티가 이러한 변화를 평가하는 동안 RSK Labs는 레퍼런스 코드를 마무리하고 RSKIP를 최종적으로 검토하고 있습니다. 앞으로 몇 달 안에 Unitrie를 활성화할 수 있는 안전한 네트워크 업그레이드를 예상하고 있습니다.