이더리움 샤딩

현재 이더리움이 겪고 있는 가장 큰 문제는 scalability다. 이더리움이 인기를 끌면서 트랜잭션의 양도 늘어나고 참여하고 있는 노드의 수도 늘고 있는데 PoW를 쓰는 이더리움의 특성상 초당 트랜잭션 처리 수는 늘지 못한다. 그래서 지금 이더리움 코어 개발자들이 초점을 맞춰서 개발하고 있는 것이 ethereum sharding이다.

이더리움 샤딩을 간단히 설명하면 샤드별로 merkle patricia tree를 만들고 그 샤드의 root들로 만들어진 merkle partricia tree의 root만을 블록체인에 올리는 것이다. 이렇게 하면 모든 miner가 모든 트랜잭션을 실행할 필요 없이 각 샤드별로 miner를 분산시켜 실행할 수 있기 때문에 전체 실행 속도가 올라간다는 내용이다. 설명은 간단하지만 구현은 간단하지 않다.

이더리움은 replay attack을 막기 위해서 account nonce라는 것을 도입했다. 현재 state에서 account가 가지는 nonce보다 1 큰 nonce를 가지는 트랜잭션만 유효한 transaction이기 때문에, 같은 account에서 보내는 2개 이상의 트랜잭션은 동시에 처리될 수 없다. 즉, 한 account의 트랜잭션이 두 개 이상의 샤드에서 실행되면 안전하지 못하다는 것이고, account는 샤드에 종속돼야 한다. 또한, 샤드는 독립적으로 실행돼야 한다. 이 말은 한 샤드에서 실행된 트랜잭션이 다른 샤드에 영향을 주지 못 한다는 것이고, 다른 샤드에 존재하는 account 사이에서는 트랜잭션을 주고받을 수 없다는 것이다.

현재 제안된 샤드 간 통신은 receipt tree를 이용하는 것이다. 예를 들어 shard N의 account A에서 shard M의 account B로 송금하는 상황을 생각해보자. 이때 N은 account A의 계좌를 차감하는 transaction T1을 실행한다. T1M의 state를 변경할 수 없기 때문에 B에게 바로 입금할 수 없다. 따라서 T1MB에게 돈을 추가하라는 receipt만 남긴다. 그 후 M에서 B에게 입금하는 transaction T2를 실행하고 자신이 입금했다는 것을 다시 receipt에 적는다.

이렇게 하면 기존보다 비효율적이지만 샤드 간 송금은 처리할 수 있다. 하지만 아직 넘어야 할 산이 있다. 이더리움의 consensus 방식은 finality를 확률적으로만 보장한다. 위의 예제에서 T1을 실행됐으면 T2가 실행되고, T1이 실행되지 않았으면 T2도 실행돼서는 안 된다. 따라서 N에 문제가 생겨 reorganization이 발생하여 T1이 사라졌으면, M도 reorganization하여 T2를 지워야 한다. 이를 악용하면, 쉽게 DoS 공격이 가능해진다. 따라서 T2를 실행하기 전의 T1의 finality를 보장해야 하는데, 앞서 말했듯이 현재 이더리움에서는 방법이 없다. 완전히 PoS로 옮겨가거나 최소한 Friendly Finality Gadget이 들어가야 확실하게 finality를 보장할 수있게된다. 그래서 현재 진행중인 sharding phase 1에서는 샤드 간 통신은 구현이 없고 phase 4에서야 구현될 것이라고 한다.

샤드 간 송금은 finalty만 보장되면 위와 같은 방식으로 할 수 있지만, smart contract를 실행하는 것은 이것보다 더 복잡해진다. smart contract에서는 다른 smart contract를 호출할 수 있는데, smart contract도 각자 자신의 state를 가지고 있기 때문에, 모든 smart contract가 같은 shard에 있어야 한다. 이 문제를 해결하기 위해 smart contract를 lock 하여 실행시킬 shard로 가져오는 cross shard lock scheme이 제안은 됐지만, 아직 결정된 것은 아무것도 없다.

이더리움의 성능 문제가 현재 이더리움이 가지는 가장 큰 문제인 것은 확실하다. 이더리움의 트랜잭션 양은 늘어나고 있는데 아직도 이더리움의 초당 트랜잭션 처리 속도는 20tx/s를 넘지 못하고 있다. 하지만 샤딩만으로 얼마나 성능을 향상할 수 있을지는 의문이다. 샤드를 N개 만들었을 때, 최상의 결과는 N배 빨라지는 것이다. 이것도 정말 이상적인 것이고 실제로 이만한 성능 향상을 얻지는 못할 것이다. 따라서 성능을 많이 올리고 싶으면 샤드의 개수를 늘려야 한다.

하지만 위에서 말했듯이 샤드를 도입하면, 샤드 간 transaction은 지금의 이더리움보다 처리 속도가 느려진다. 현재 제안된 casper에서 finality를 보장하기 위해서는 최소 50 block을 기다린다. 샤드 간 통신에서는 두 번째 트랜잭션이 실행되기 전에 finality가 보장돼야 하니, 샤드 간 통신의 finality를 보장하기 위해서는 최소 10분을 더 기다려야 한다는 것이다. 과연 이 overhead를 감수하면서 샤드가 가지고 올 성능 향상이 크지는 않을 것 같다.

댓글

  1. Dos 공격이 쉽다는건
    각 샤드에서 모두 recipt를 발행해서
    메인체인의 성능을 저하시킨다는 의미인가요??

    답글삭제

댓글 쓰기

이 블로그의 인기 게시물

[C++] enum class - 안전하고 쓰기 쉬운 enum

RAII는 무엇인가

Log Aggregator 비교 - Scribe, Flume, Fluentd, logstash

[Python] cache 데코레이터로 최적화하기

[Web] SpeechSynthesis - TTS API