kaistshadow / blockchain-sim

Scalable blockchain simulator/emulator running on shadow simulator
MIT License
9 stars 1 forks source link

FF-12 : Dump file test #278

Closed tkdlqm2 closed 3 years ago

tkdlqm2 commented 3 years ago

FF-12 : Dump file test

Originally posted by @tkdlqm2 in https://github.com/kaistshadow/blockchain-sim/issues/272#issuecomment-803752976

tkdlqm2 commented 3 years ago

테스트 명세서 12 - load data file

Initial coin 셋팅을 위해 필요한 dump data file을 시뮬레이션 시 load 과정이 정상적으로 이루어지는지에 대한 테스트가 필요함. bitcoind 실행 시 "reindex" 플래그를 셋팅함으로서 dump data를 load하겠다는 것이고, 성공적으로 load가 되면, "Reindexing finish" 로그가 print되며 또한 기존의 dump file에 담긴 블록들의 ahsh 값들과 bitcoin 플러그인의 실행 로그 값을 비교.

tkdlqm2 commented 3 years ago
def test_dumpfile_load(plugin_output_files, abs_path):
    print("dump test start ... ")
    condition_count = 0
    the_path = ""
    ready_hash_list = []
    f = open(plugin_output_files, "r")
    while True:
        line = f.readline()
        if not line: break
        result = line.find("Reindexing finished")
        if result != -1:
            condition_count = 1
            f.close()
            break

    if condition_count == 1:
        the_path = utils.get_datadirDumpfile_path(abs_path)
        the_path = the_path + "/coinflip_hash.txt"
        f = open(the_path, "r")
        while True:
            line = f.readline()
            if not line: break
            ready_hash_list.append(line.strip())
        f.close()

        i = 0
        result_hash_list = []
        f = open(plugin_output_files, "r")
        while True:
            line = f.readline()
            if not line:break
            result = line.find("UpdateTip")
            if result != -1:
                if ready_hash_list[i] == line.split(" ")[3].split("=")[1]:
                    i += 1
                    pass
                # 0번째는 제네시스 블록이라 스킵.
                elif i == 0:
                    continue
                else:
                    print("Fail test dump file load ... ")
                    f.close()
                    sys.exit(1)
            if i == 7:
                print("Success test dump file load test ... ")
                f.close()
                break

    else:
        print("Fail load data file test ... (Not Reindexing finished)")
        f.close()
        sys.exit(1)
  1. 플러그인 로그에서 "Reindexing finished" 로그가 없으면 test 실패
  2. coinlip_hash.txt 파일에서 블록 hash 값들을 읽어서, 플러그인의 로그에서 1~7번의 블록 hash 값과 비교
tkdlqm2 commented 3 years ago
def get_datadirDumpfile_path(abs_path):
    the_list = abs_path.split("/")
    the_command = ""
    for i in range(0,len(the_list)):
        the_command = the_command + the_list[i] + "/"
        if the_list[i] == "blockchain-sim":
            the_command = the_command + "/testlibs/datadir_dump"
            break

    return the_command

함수가 실행되는 현재 경로를 인풋값으로 사용하여, "testlibs/datadir_dump/ 디렉토리의 절대 경로를 반환해주는 함수.

def set_plugin_file(node_count, path):
    if(os. path. isdir(path)):
        the_command = "rm -rf data/*"
        exec_shell_cmd(the_command)

    for i in range(0,node_count):
        the_command = "mkdir -p data/bcdnode" + str(i)
        exec_shell_cmd(the_command)

    target_command = get_datadirDumpfile_path(path)
    command = "cp -r " + target_command + "/* " + path + "/data"
    exec_shell_cmd(command)

결국 plugin file을 생성하는 과정에서 dump file setting을 해주는 로직들이 모두 호출이 됨.

tkdlqm2 commented 3 years ago

또 다른 이슈지만, 간단한 이슈라 별도의 이슈로 안빼고, 현재 이슈에서 정리해서 같이 해결함. Initial dump block이 셋팅이 될 시, mining test의 기준이 변경이 되어야함. release 0.1.0에서는 플러그인 로그 값 중 "height=1"의 유무에 따라 test 결과가 결정이 되었음. 하지만 dump block이 있으니 "height=8"로 수정이 되어야함.

tkdlqm2 commented 3 years ago

start_emulation.py 의 콘솔 입력 값 중 "algo"에 대한 처리 프로세스가 merge과정에서 사라졌었음. 그래서 다시 복구함.

tkdlqm2 commented 3 years ago

현재 dump 파일은 "difficulty=3"에 대한 파일임. "difficulty=1", "difficulty=2"에 대한 덤프 파일도 필요함.

tkdlqm2 commented 3 years ago

난이도별 덤프 셋팅은 다음과 같음.

├── dump
│   ├── difficulty_1
│   │   ├── bcdnode0
│   │   └── coinflip_hash.txt
│   ├── difficulty_2
│   │   ├── bcdnode0
│   │   └── coinflip_hash.txt
│   └── difficulty_3
│       ├── bcdnode0
│       └── coinflip_hash.txt

위 디렉토리는 testlibs의 디렉토리 중 하나이며, 시뮬레이션 스크립트를 실행할 때 difficulty 옵션에 맞춰서 준비된 dump가 load됨.

tkdlqm2 commented 3 years ago

coinflip 알고리즘을 기준으로 dump file을 생성할 시, pow 알고리즘까지 호환이 되지 않음. 그렇기에 pow 기준으로 덤프를 각 난이도 별로 생성을 했음. 하지만 한 가지 이슈로 difficulty=1 (main net difficulty) 로 pow 덤프 블록이 생성이 되질 않음.

How to reproduce xml 파일에 difficutly=1, algo=pow 로 설정을 해주고 shadow 실행을 하면, freezing 현상을 볼 수 있음. 정확한 원인을 알기 위해서는 디버깅을 해야함.

hyojin5658 commented 3 years ago

미리 생성 되어 있는 dump file을 사용해서 비트코인을 실행 시킬때, reindexing을 성공적으로 동작하고, 블록 6개를 bootstraping 해온 이후에

마이닝을 실행 하다가, block을 genesis block 까지 disconnect 하고, 새로운 블록을 생성 하는 경우가 있습니다. 정확한 이유는 모르겠지만, 아마도 블록체인 로직에서 fork가 났다고 인식해서 disconnect 하는 경우가 있습니다. 이 문제는 비트코인 로직 분석 한 다음에 수정 할 예정입니다. (아마 난이도/알고리즘 별로 dump 파일을 세분화 해놨기 때문에 문제는 발생하진 않을것 같습니다.)

regtest에서도 load data file 테스트에서 bootstrapping 한 블록에 대해서 체크 하는 로직을 추가하면 좋을 것 같습니다.

hyojin5658 commented 3 years ago

이전 상태는, reindexing 실행 -> updatetip 함수로 load 해온 블록을 메인체인에 추가 image

이후의 상태는 genesis block을 다시 load 하고 마이닝한 새로운 블록을 메인체인에 추가 합니다. image

혹시 실행 하고자 하신 다면, feature/262/TPS 브랜치, ac4499020d2312acf624fe6f2890c0b6e6a44f9d 커밋에서 BLEEPeval/tpstest-app/prototype/test-BitcoinP2P.xml 실행 하시고, 비트코인 로그 확인하시면 됩니다!

tkdlqm2 commented 3 years ago

@hyojin5658

    # check pork
    event_value = 0
    if condition_count == 1:
        f = open(plugin_output_files, "r")
        while True:
            line = f.readline()
            if not line: break
            result = line.find("Disconnect block")
            if result != -1:
                event_value = 1
                continue
            if event_value == 1:
                result = line.find("height=6")
                if result != -1:
                    print("Fail dump file load ... ")
                    print("There are problems about initial block hashes ... ")
                    f.close()
                    sys.exit(1)

        condition_count = 2
        f.close()

test_modules.py 파일에 구현이 되었으며, 테스트 로직은 "Disconnect block" 로그가 발견되면, 다음 라인에서 "height=6"이 포함된 로그가 발견되면 에러 발생으로 간주함. 그 외에 pork 나는 상황은 Discoonect block 로그 이후의 로그에서 Inital block 외에 블록이니 상관없게 처리가 되었음.

tkdlqm2 commented 3 years ago

FF - 3 client connection test

시뮬레이션 시 bitcoin 플러그인과 connection만 될뿐 노드의 역할은 하지 않음. 다만 bitcoin 플러그인으로부터 transaction, propagation, block propagation에 대한 수신을 함.

시뮬레이션 후, 각 노드들의 플러그인 결과 로그에서 client의 ip address 로그를 필터링으로 연결 유무를 확인하여, 로그가 있으면 return 0 아닐 경우 return 1임.