자바 개발자의 go-ethereum 소스 읽기: Day 3
이 글은 자바 개발자의 go-ethereum(geth 클라이언트) 소스 분석기 시리즈의 연재 중 세 번째 글입니다. 앞으로 다음과 같은 내용으로 연재를 계획하고 있습니다.
- Day 01: Geth 1.0 소스 받기 및 코드 분석을 위한 개발환경 셋팅(VS Code)
- Day 02: CLI 라이브러리 기반
geth
의 전체 실행 구조 - (본 글) Day 03: VS Code를 사용한
geth
디버깅
...
전체 연재 목록은 아래 페이지에서 확인해 주세요
http://www.notforme.kr/block-chain/geth-code-reading
대상 독자
이 연재는 먼저 독자 분들이 적어도 Java와 같은 OOP 계열의 언어로 프로그래밍 경험이 있다는 것을 가정합니다. 또한 계정, 채굴 등 블록체인과 이더리움과 관련된 기초적인 개념을 알고 있다고 가정합니다.
다루는 내용
지난 글에서 우리는 geth
실행과 관련된 코드의 구조를 살펴보았습니다. 오늘은 geth
의 실행 로직을 분석하기 위해 실제 golang
의 install
명령을 사용하여 소스를 빌드하여 실행해보고자 합니다. 또한 코드를 수정 후 재빌드하여 우리가 수정한 코드가 반영되는지도 확인해 볼 것입니다. VS Code를 사용하여 수정사항을 확인하기 위하여 빌드하지 않고 디버그하는 방법도 볼 것입니다.
geth 빌드하기
golang
이 설치되어 있고 다음 명령을 사용하여 $GOPATH
에 geth
의 소스가 설치되어 있다면 geth
의 빌드는 아주 쉽습니다.
$ go get -d github.com/ethereum/go-ethereum
소스를 빌드하기 위한 명령은 golang
에서 제공하는 install
명령을 사용하면 됩니다. 이 명령은 소스를 빌드한 후 실행가능한 바이너리를 GOPATH
의 bin 폴더에 옮기는 일을 합니다. 빌드 전에 다음 명령을 통해서 geth
바이너리가 아직 설치되지 않았음을 확인해 봅니다.
$ ls -al (각자의 $GOPATH)/bin | grep geth
명령을 실행하면 아무런 결과도 보이지 않습니다. 이제 소스를 빌드해 봅시다. 명령은 다음과 같습니다.
$ go install github.com/ethereum/go-ethereum/cmd/geth
정상적으로 소스가 빌드되면 $GOPATH/bin
에 geth
바이너리가 생성됩니다. 앞의 ls
명령을 재실행하여 정상적으로 바이너리가 생성되었는지 확인해 봅니다. 바이너리를 확인했다면 빌드에 성공한 것입니다.
geth 실행 및 디버깅
$GOPATH/bin
의 경로가 $PATH
에 등록되어 있다면 이제 터미널에서 geth
명령을 실행할 수 있습니다. 아무런 실행옵션 없이 터미널에서 geth
명령을 바로 실행하면 몇십 줄의 로그가 올라온 뒤 잠시 대기합니다. 우린 아직 구체적인 코드를 보지 않았으나 추측하기론 이 시간이 메인 네트워크에 접속하다른 노드를 찾는 시간일 겁니다. 잠시의 대기시간이 지나면 우리가 실행한 geth
는 메인 네트워크에 합류하여 다음과 같이 블럭 정보를 받는 로그를 볼 수 있습니다.
CTRL-C
로 시그널을 보내면 실행 중인 geth
가 종료하게 됩니다
테스트 실행을 위한 옵션
geth
를 공부용으로 매번 실행할 때 마다 메인네트워크에 붙는 것은 부담스러운 일입니다. 몇가지 옵션을 설정하면 손쉽게 별도의 네트워크를 구성할 수 있습니다. 여기서는 간단하게 --nodiscover
옵션을 주고 geth
실행 시 블럭 정보를 받아오지 않도록 해보려고 합니다. 이 옵션은 네트워크 내 다른 노드에서 우리가 실행한 노드를 검색하지 않도록 하는 옵션입니다.
$ geth --nodiscover
위와 같은 명령으로 다시 실행하면 geth
에서 추가로 블록을 받아오고 싱크하는 일을 하지 않게 됩니다. 독립적인 테스트 네트워크의 구축은 공식 매뉴얼에 안내가 되어 있습니다. 이 부분은 다음에 관련 코드를 읽을 때 다시 살펴볼 예정입니다.
수정하고 빌드해 보기
한 걸음 더 나아가서 이제 코드를 수정하고 빌드하여 우리가 수정한 코드가 동작하는지 확인해 봅시다. 우리가 작성한 코드가 반영되었는지 확인하는 가장 쉬운 방법은… 진리의 printf
입니다. 지난 시간에 확인했던 최초의 진입점 cmd/geth/main.go
의 main
함수에 우리의 흔적을 남겨봅시다.
geth
의 최초 시작 지점에 한 줄의 코드를 추가했습니다. 이제 위에서 진행한 빌드/실행을 해봅시다. 물론 --nodiscover
옵션도 포함합니다.
비록 간단한 print 문이지만 드디어 Java 개발자가 golang
의 오픈소스를 수정한 순간이네요! 여기까지만 와도 앞으로 코드를 읽고 분석할 때 직접 코드를 수정해서 빌드해서 실행해 볼 수 있는 발판이 마련된 것입니다. 그러나 여전히 아쉬운 점이 하나 있습니다. 그건 바로 디버깅 환경입니다.
VS Code로 디버깅
상용 툴을 쓸 수 있다면 Jetbranins 사의 Goland가 Java 개발자가 많이 쓰는 Intellij와 인터페이스가 동일하여 손쉽게 디버깅할 수 있습니다. 다행히 VS Code로도 golang
의 코드를 디버깅할 수 있습니다.
첫 번째 글에 따라 VS Code를 설치하고 Go
확장을 설치했으면 터미널에서 다음 명령을 실행하면 golang
을 위한 디버깅 환경 준비가 모두 끝납니다.
$ go get -u github.com/derekparker/delve/cmd/dlv
설치가 끝나면 VS Code를 실행하고 cmd/geth/main.go
파일을 엽니다. 이제 기존 IDE와 동일한 인터페이스로 geth
코드의 디버깅 포인트를 찍을 수 있습니다. 아래 그림과 같이 위에서 추가한 print 문 코드 바로 다음, app
인스턴스의 실행 부분에 디버깅 포인트를 찍고 디버깅 명령을 수행해 보겠습니다.
정상적으로 디버그 모드로 geth
가 실행되면 다음과 같이 우리에게 익숙한 디버깅 환경이 제공됩니다.
VS Code 내 디버그 콘솔을 보면 앞서 작성한 Println 명령이 실행되어 콘솔에 출력된 것을 확인할 수 있습니다. 이제 이 지점에서 다음 스텝으로 넘어가거나, 그대로 실행하는 등의 작업을 통해서 코드의 실행흐름을 추적할 수 있습니다.
참고로 디버깅은 반드시
func main
이 선언된 파일에서만 작동 가능합니다.
VS Code 디버그 환경 설정 추가
디버그 실행과 관련하여 한가지 설정이 남았습니다. 지금과 같은 환경에서 디버깅을 진행하면 터미널에서 아무런 옵션 없이 geth
를 실행한 것과 동일합니다. 우리에게 필요한 것은 디버그 모드로 실행할 때 우리가 필요한 인자를 옵션으로 줄 수 있어야 합니다.
VS Code의 왼쪽 하단의 디버그 탭을 클릭하면 상단에 톱니바퀴 모양 버튼이 보입니다.
톱니바퀴 모양의 버튼을 클릭하면 에디터에 launch.json
파일이 열립니다. 이 파일이 VS Code에서 디버그 모드로 실행할 때의 설정파일 역할을 합니다. 이제 json 파일의 args
에 실행 시 전달한 인자를 입력하면 됩니다. 그럼 앞에서 사용했던 --nodiscover
옵션을 디버깅 할때도 동일하게 적용해 봅시다.
이제 이전과 동일하게 VS Code 안의 디버그 콘솔에서 최초 터미널에서 실행할 때와 동일한 로그를 발견할 수 있습니다. 또한 --nodiscover
옵션이 추가되어 메인 네트워크로부터 블록을 싱크하지도 않을 것입니다.
마치며
오늘은 간단히 VS Code를 활용한 golang
코드의 디버깅 환경을 셋팅했습니다. 이제 우리는 오늘까지 연재를 통해서 본격적인 geth
코드 분석을 위한 모든 준비가 끝났습니다. 다음 글에서 본격적인 소스를 분석한 내용을 함께 나누고자 합니다.
블록체인을 공부하면서 일부러 steem을 통해서 글을 올려보고 있는데 공부한 내용을 함께 나누는 일을 지속적으로 할 수 있도록 보팅으로 응원 부탁드립니다.
감사합니다. ^^!
좋은 글 감사합니다.
저는 입문자로 비트코인 코어를 분석 시작했어요. 어렵고 더디지만 저도 이렇게 과정을 공유할 날이 오길 기대합니다.^^
와우! @endiyou님의 비트코인 분석 과정 공유도 기대하며 응원합니다 :)
좋은글 정말 감사드리며 보팅합니다 :) 실례지만 vscode 테마가 이뻐서 그런데 어떤 테마쓰시는지 알수있을까요?
@skybluemaru님 저는 드라큘라 테마 쓰고 있습니다 :)
https://marketplace.visualstudio.com/items?itemName=dracula-theme.theme-dracula
@woojin.joe 답변을 이제 확인했네요 ㅜ 알려주셔서 감사합니다. 자주 들릴게요😊