[블록체인을 이용한 경력 인증] 노드 주소 관리를 위한 MSP

재호·2022년 8월 9일
0

CABB

목록 보기
4/5

개요

블록 생성 합의를 위한 노드들의 주소 테이블을 관리하는 MSP용 독립 노드를 생성하고자 한다.

새노드 합류

func (addr *Addr) newNodeAccept(writer http.ResponseWriter, req *http.Request) {
	json.NewDecoder(req.Body).Decode(addr)
	// 새로운 노드 접속을 리더 노드에게 알림
	_, err := http.Post("http://"+table[primary]+"/newNodeAlarm", "text/plain", nil)
	if err != nil {
		fmt.Println(err)
	}
	table[addr.NewNode] = addr.Address + ":" + addr.NewNode
	fmt.Printf("[Node:%s] : %s 추가\n", addr.NewNode, table[addr.NewNode])
}

새노드가 합류하면서 MSP에게 이를 알리고 MSP는 새노드의 주소를 주소 테이블에 추가한다. 이후 주소 테이블이 업데이트되었다는 것을 리더 노드에게 알려준다.

MSP가 주소 테이블의 업데이트 사실을 알리면 리더 노드는 다음 합의를 시작하기 전에 MSP에게 업데이트된 주소 테이블을 달라고 요청한다.

주소 테이블 요청

func (addr *Addr) tableUpdateAlarm(writer http.ResponseWriter, req *http.Request) {
	//리더 노드로 부터 ViewID 값 받아서 1 증가시킴
	var view map[string]int64
	json.NewDecoder(req.Body).Decode(&view)
	for _, v := range view {
		fmt.Printf("recieved ViewID: %d\n", v)
	}
	viewJ, _ := json.Marshal(view)

	//어드레스 테이블을 브로드캐스팅 해줌(리더 노드 제외)
	address, _ := json.Marshal(table)
	for k, v := range table {
		if k == primary {
			continue
		}
		_, err := http.Post("http://"+v+"/getTable", "application/json", bytes.NewBuffer(address))
		if err != nil {
			delete(table, k)
			fmt.Printf("[Node:%s] is disconnected\n", k)
		}
	}

	//새로 참가한 노드에게 ViewID 전송
	_, err := http.Post("http://"+table[addr.NewNode]+"/viewID", "application/json", bytes.NewBuffer(viewJ))
	if err != nil {
		fmt.Println(err)
	}

	//위 과정이 모두 끝나면 리더노드에게 어드레스 테이블을 응답데이터로 전송
	writer.Header().Set("Content-Type", "application/json")
	json.NewEncoder(writer).Encode(table)
}

리더 노드는 테이블을 요청하면서 본인의 ViewID를 전송해준다. MSP는 받은 ViewID를 새로 합류한 새 노드에게 전송해준다.

MSP는 리더 노드를 제외한 모든 노드들에게 업데이트된 주소 테이블을 전송해준다.

이후 리더노드에게는 최초 요청에 대한 응답으로써 주소 테이블을 담아 보내준다.

연결 노드 점검

	for {
		check := false
		for k, v := range table {
			if k == primary {
				continue
			}
			_, err := http.Post("http://"+v+"/pingReq", "text/plain", nil)
			if err != nil {
				delete(table, k)
				fmt.Printf("[Node:%s] is deleted\n", k)
				check = true
			}
		}
		if check {
			_, err := http.Post("http://"+table[primary]+"/newNodeAlarm", "text/plain", nil)
			if err != nil {
				fmt.Println(err)
			}
		}
		time.Sleep(sleepDuration)
		fmt.Println("sleep")
	}

일정 시간마다 주소 테이블 속 노드들에게 ping을 날려 연결 상태를 확인하도록 한다.
만약 연결이 끊긴 노드가 있다면 이 노드는 주소 테이블에서 삭제하고 이로 인해 주소 테이블이 업데이트되었다는 사실을 리더 노드에게 알려준다.

Git

https://github.com/JINJAEHO/cabb_merge/blob/main/msp/node.go

profile
Java, Spring, SpringMVC, JPA, MyBatis

0개의 댓글