leap-node 는 index.js 로 시작하므로, 여기서부터 살펴봅니다.
먼저 require 하는 아래 3가지 핸들러부터 살펴보겠습니다.
const txHandler = require('./src/tx');
const blockHandler = require('./src/block');
const periodHandler = require('./src/period');
txHandler :
일단 leap-core 에서 트랜잭션들을 가져오고,
트랜잭션 타입에 따라서 기존의 상태를 리턴해 줍니다.
tx의 타입은
DEPOSIT, EPOCH_LENGTH, EXIT, TRANSFER, VALIDATOR_JOIN, CONSOLIDATE, VALIDATOR_LOGOUT 로 총 7개 가 있습니다.
applyTx 에서는
checkOutpoints, removeInputs, addOutputs 를 진행하는데
checkOutpoints 는 트랙잭션 인풋을 돌면서 input.prevout이 unspent 되었는지 즉, 존재하지 않는 output을 spend 하려 했는지 체크하고 에러를 throw 합니다. (에러는 계속 위로 올려버립니다.)
removeInputs 는 트랜잭션 인풋을 돌면서 input.prevout 이 unspent로 존재하면 해당 balance 를 삭제합니다.
addOutputs 에서는 트랜잭션 아웃풋을 돌면서 이미 존재하는 output 을 또 만들지 않도록 주의하면서 unspent 목록에 추가합니다.
cBalances Array 는 완전 복사(Deepcopy) 가 된 상태가 아니라서 balances 를 가리키게 됩니다.
Deepcopy 와 Shallow copy 에 대해서는 다음 시간에 알아보도록 하죠.
accumulateTx 에서는 남아있는 tx 들을 메모리풀에 적재합니다.
결국 기존 트랜잭션을 오류 없이 불러오려고 하는 것이네요.
blockHandler :
updatePeriod 에서는체인 길이를 32로 나눈 나머지가 0인 경우에 period 를 업데이트 하고 있습니다.
업데이트란, 이전 period 에 현재 period 를 복사하고, 이전 Period 의 merkleRoot() 로 현재 period 를 생성하는 것입니다. (swap)
체인 길이를 32로 나눈 나머지가 16인 경우, slot을 확인해서 활성화된 epoch 와 현재 epoch 의 차이가 1보다 크면, 각 slot 을 활성화 시킵니다. 이 부분은 확실히 이해가 안되서 코드를 남겨놓습니다.
addBlock 에서는
아까 메모리 풀에 적재해 놓았던 트랜잭션들을 매핑, JSON 화 해서 각각 새로운 블록에 바인딩 합니다. 이 새로운 블락을 bridgeState.currentPeriod 의 addBlock 의 매개변수로 줘서 블록을 생성하고, 메모리 풀을 비웁니다. 만약 받은 chainInfo 의 길이가 마지막으로 싱크된 블록의 길이보다 더 길면 블록을 다시 싱크하고 마지막으로 싱크된 블록의 길이를 늘려 줍니다.
updateValidators 에서는
state 의 slot 들에서 올바른 public key 를 불러오고, Address 를 가져옵니다.
그리고 각 Address에서 power 를 계산해서 (이것이 어디에서 변경되는지 확인 필요) 인덱스가 없고 0이 아니면 삭제하고, 인덱스가 있는데 0이면 체인에 validator로 추가합니다. 그리고 체인에서 해당 address 가 validator 로서 존재하지 않으면, power 10으로 추가해 줍니다.
key 의 알고리즘은 ed25519 이네요.
updateEpoch 에서는
코드가 짧아서 대체합니다. 말 그대로 epoch 의 길이를 업데이트 합니다.
periodHandler :
submitPeriod 에서는먼저 bridgeContract의 periods 메소드를 콜합니다. 그러면 submit 된 period 가 나옵니다.
--> bridgeState.bridgeContract.methods
submit 된 period 중 timestamp 가 0인 경우
slot을 가져와서 현재 slot 이 존재 하는 경우 slot의 id, submitPeriod 를 갖고 트랜잭션을 발생시킵니다. 트랜잭션은 아래처럼 받은 method -
를 ABI 인코딩 하고 가스를 랜덤하게 설정한 다음 private key로 사인합니다.
submitPeriod 이후에는 마찬가지로 contractPeriod 의 timestamp 가 0인지 확인하는 작업이 있는데, 위에서도 나왔지만 timestamp 가 0이라는게 어떤 의미인지 지금까지는 잘 모르겠네요.
결국 요약하면, 위 3개의 핸들러의 표면(index.js) 은
기존에 사용하던 트랜잭션과 블록을 안전하게 로딩 하기 위한 것임을 알 수 있었습니다.
물론 이름처럼 핸들링 하기 위한 코드도 있을 것 같은데, 아래에서 더 살펴보도록 합니다.
다시 돌아와서 최초 index.js 의 코드 시작을 보면 lotion 을 사용하고 있습니다. 로션이란 뭘까요?
lotion :
로션은 자바스크립트로 새로운 블록체인 앱을 만들어 내는 새로운 방법 중 하나로,ABCI 프로토콜을 사용해 텐더민트 위에서 동작합니다.
ABCI 란 Application BlockChain Interface 의 약자로, 블록체인과 앱 사이의 인터페이스입니다.
컨센서스 엔진은 소켓 프로토콜을 사용, ABCI 를 통해
다른 프로세스에서 실행되는 응용 프로그램 상태를 관리 할 수 있게 됩니다
이후 BridgeState 를 사용해서 이것저것 하게 되는데요. 그렇다면 BridgeState 를 알아봅시다.
bridgeState
브릿지의 상태를 관리 할 수 있는 객체로, exitHandler 컨트랙트, bridge 컨트랙트, operator 컨트랙트 그리고 account 키 등 상태 정보가 있습니다.하지만 결국 web3 eth 를 쓰고 있어서 이게 뭔지 정확히 알아야 되겠죠.
최초 init 을 실행하면 마지막으로 싱크된 블록을 확인하고, 컨트랙트 이벤트 워쳐를 실행하고
블록을 이닛합니다. 이게 뭔가 순서가 중요한지 비동기인데 await 으로 동기화 해 주었네요.
컨트랙트 이벤트 워쳐는 새로운 Deposit 이 생겼거나 Exit 가 시작 되었을때,
EpochLength 를 핸들링 합니다.
0 개의 댓글:
댓글 쓰기