gruut / tethys

This software cannot be used commercially without our permission. If you are interested in, contact nyang@thevaulters.com
GNU General Public License v2.0
2 stars 1 forks source link

Fix/result query #198

Closed SeongKwangMoon closed 5 years ago

SeongKwangMoon commented 5 years ago

주요 변경 내용

  1. findUserScopeFromeRDB, findContractScopeFromRDB의 chain에서의 wrapper를 삭제하였습니다. chain.cpp 외부에서 사용하지 않는 함수이므로 굳이 유지할 필요가 없습니다.

  2. setUserScopePid, setContractScopePid를 calculatePid로 통합하였습니다. 다만, tag/var_info가 존재할 때의 처리를 아직 덜 고려해서 이 함수는 추후 수정될 수 있습니다.

  3. queryUserScope를 전반적으로 수정하였습니다. 생성할 때만 var_type이 주어지며, 그로 인하여 기존의 수정일 때는 var_type을 찾는 연산이 필요합니다. 이런 분기 사항들을 고려하지 않고 뼈대만 만들어두고 올려뒀는데, 설계상의 구현에 가깝게 수정하였습니다.

  4. 위의 함수에 사용되는 getVarType과, 기타 다른 쿼리 처리에서도 사용되는 scope에서의 var_owner와 var_name의 unique함을 체크하는 함수를 구현하였습니다. 두 함수는 var_owner와 var_name을 가지고 var_type이 여러 개 존재하지 않는지를 체크하는 행동은 똑같이 수행하며, 단지 getVarType는 결과로써 true/false가 아니라 얻어낸 var_type 정보를 리턴하는 것이므로 두 함수를 통일해서 구현했습니다. 다만, 쓰이는 장소와 상황이 다르므로 함수명은 따로 구현하여 처리할 때 혼동이 없도록 하였습니다.

TODO : queryUserScope 외에도 Contract와 특히 transfer를 고쳐야 합니다.

SeongKwangMoon commented 5 years ago

@blackironj @morishjs getVarType / checkUniqueVarName 에 대해서 설명을 좀 써둬야 할 것 같아 추가합니다.

다른 종류의 임시값, ledger들은 특정 블록을 기준으로 최신의 정보만 있으면 충분합니다. 그러므로, head가 제대로 위치해있다면 state tree를 pid로 검색하기만 하면 바로 알 수 있습니다. head를 옮기기 위해 현재 블록에 있는 값을 취소하고 이전으로 되돌아갈 때 또한 state tree의 값은 사용하지 못하지만(이 연산 자체가 state tree를 바꾸기 위한 사전 작업이기 때문입니다), 역시 특정 pid의 최신 값만 있으면 됩니다.

하지만 getVarType / checkUniqueVarName 는 다릅니다. 두 함수 모두 var_type이라는 요소가 부족한 상태에서 실행되는 함수이며, var_type는 pid를 계산하기 위해 필요한 요소입니다. 즉, pid를 알 수 없습니다. 그러므로 state tree에서 직접적인 검색도 불가능합니다.

var_owner와 var_name 두 가지가 일치하는 것이 유일하거나 없어야 한다는 조건입니다. state tree에는 현재 head가 가리키고 있는 모든 정보가 들어있으므로, 분명 state tree에서 찾으면 원하는 정보가 존재하기는 합니다. 하지만 state tree는 pid가 없으면 모든 트리를 순회해야하는 구조인데, 하나하나 접근하여 값을 찾기에는 너무 비효율적입니다.

그래서 state tree가 아닌, 각 블록의 ledger들에 차례차례 접근하기로 합니다. 그런데, 최신 정보를 찾으면 끝나는 것이 아닙니다. 만약 RDB - A - B - C 블럭 순으로 연결되어있다고 합시다. C가 최신 블럭입니다. 데이터 형식은 (user_name, var_name, var_type) 으로 쓰겠습니다. 우리가 지금 찾고싶은 user_name, var_name은 (A, abc)입니다. 그런데 찾아보니, C 블럭에 (A, abc, int) 가 존재합니다. 다른 형식의 연산이었으면 최신 값을 찾았으므로 여기서 끝입니다. 하지만, A 블럭에 (A, abc, string) 이 존재할 수도 있습니다. 그러면 unique해야한다는 조건이 깨집니다. 그러므로 모든 층의 정보를 검색해야만 하는 것입니다.

그래서 이 PR에서의 getVarType / checkUniqueVarName 는 현 블록에서부터 RDB에 반영되기 전의 블록까지 거슬러올라가며 모든 ledger를 for로 begin부터 end까지 손수 찾는 것이며, RDB에서 query를 통해 빠르게 원하는 정보를 검색하는 방식으로 구현되었습니다.

함수 구현에 대한 설명을 남겨둘 겸, 함수를 체크하실 때 조금이라도 도움이 되시라고 씁니다.