Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Create action to run Integration test regularly #313

Merged
merged 79 commits into from
Sep 30, 2024
Merged
Show file tree
Hide file tree
Changes from 60 commits
Commits
Show all changes
79 commits
Select commit Hold shift + click to select a range
6addbae
add run-l2-it-prc.sh as bootnode
ping-ke Jul 24, 2024
2ac1c2f
update run-l2-it script
ping-ke Jul 24, 2024
84e8fc1
add integration test server
ping-ke Jul 25, 2024
c608a4f
add as runable
ping-ke Jul 26, 2024
9af6890
update bootnode
ping-ke Jul 27, 2024
7892851
update action
ping-ke Jul 31, 2024
a126fbb
update schedule
ping-ke Jul 31, 2024
fe2bb58
change on for test
ping-ke Jul 31, 2024
67a9378
update action
ping-ke Aug 1, 2024
08f61bd
fix
ping-ke Aug 1, 2024
eee0dff
bug fix
ping-ke Aug 1, 2024
6c6c2b8
bug fix
ping-ke Aug 1, 2024
cdc76da
debug
ping-ke Aug 2, 2024
7900e09
debug
ping-ke Aug 2, 2024
3c8b012
debug
ping-ke Aug 2, 2024
fd2fb45
debug
ping-ke Aug 2, 2024
2ca87b6
debug
ping-ke Aug 2, 2024
5361da8
debug
ping-ke Aug 2, 2024
e707357
debug
ping-ke Aug 2, 2024
aea4f82
debug
ping-ke Aug 2, 2024
5485429
debug
ping-ke Aug 2, 2024
5785c1f
debug
ping-ke Aug 5, 2024
e82fdca
add ituploader.js and package.json
ping-ke Aug 7, 2024
27f9f51
debug
ping-ke Aug 7, 2024
a7d7dca
small change
ping-ke Aug 7, 2024
77eeb86
bug fix
ping-ke Aug 7, 2024
e2fd746
Merge branch 'integratiointest' of https://github.com/ethstorage/es-n…
ping-ke Aug 7, 2024
7d83bd8
update dependency version
ping-ke Aug 7, 2024
20e9b43
debug
ping-ke Aug 7, 2024
21a955f
debug
ping-ke Aug 7, 2024
5ba14c2
bug fix
ping-ke Aug 7, 2024
8b58af2
bug fix
ping-ke Aug 7, 2024
f1ac853
Merge branch 'main' into integratiointest
ping-ke Aug 7, 2024
f001a67
bug fix
ping-ke Aug 8, 2024
2fe8484
Merge branch 'main' into integratiointest
ping-ke Aug 8, 2024
fc75546
Merge branch 'integratiointest' of https://github.com/ethstorage/es-n…
ping-ke Aug 8, 2024
cdbc141
bug fix
ping-ke Aug 8, 2024
5e5551c
add back deploy contracts
ping-ke Aug 8, 2024
37d14d2
fix
ping-ke Aug 9, 2024
4cb38a5
test
ping-ke Aug 10, 2024
ae01aa7
Merge branch 'main' into integratiointest
ping-ke Aug 14, 2024
b72959c
update run-le-it*.sh
ping-ke Aug 14, 2024
7c479ee
fix
ping-ke Aug 15, 2024
a638bdd
format
ping-ke Aug 15, 2024
c704a02
fix
ping-ke Aug 15, 2024
2a787d5
resolve comments
ping-ke Aug 16, 2024
f718932
add delay after upload done.
ping-ke Aug 16, 2024
be12d49
fix
ping-ke Aug 17, 2024
346ec42
increase delay
ping-ke Aug 17, 2024
dbfb8aa
run every 2 days
ping-ke Aug 19, 2024
48b10b8
resolve comments
ping-ke Aug 19, 2024
3faddd6
resolve comments
ping-ke Aug 19, 2024
8c83bf8
resolve comments
ping-ke Aug 19, 2024
196ed3c
resolve comments
ping-ke Aug 20, 2024
d277af3
change to push
ping-ke Aug 20, 2024
fd5d2ee
resolve comments
ping-ke Aug 21, 2024
a246cce
bug fix
ping-ke Aug 22, 2024
2bd749f
Merge branch 'main' into integratiointest
ping-ke Sep 2, 2024
4189ebe
resolve comments
ping-ke Sep 2, 2024
aa5ee85
resolve comments
ping-ke Sep 2, 2024
41b6c5a
add TODO
ping-ke Sep 6, 2024
63579fb
add TODO
ping-ke Sep 6, 2024
6fd3efe
Merge branch 'main' into integratiointest
ping-ke Sep 9, 2024
09d5f4c
change ituploader to writeBlobs
ping-ke Sep 9, 2024
89e8505
add support multi-shard and verify rpc
ping-ke Sep 12, 2024
0b04b0e
update init.sh
ping-ke Sep 12, 2024
87bbcba
resolve
ping-ke Sep 13, 2024
f4212cd
refactor
ping-ke Sep 16, 2024
596f0c3
debug
ping-ke Sep 17, 2024
cf37b74
debug
ping-ke Sep 17, 2024
9184ff0
resolve comment
ping-ke Sep 17, 2024
e0b93d1
debug
ping-ke Sep 18, 2024
9526222
Merge branch 'main' of https://github.com/ethstorage/es-node into int…
ping-ke Sep 18, 2024
7c4ff3e
resolve comments
ping-ke Sep 18, 2024
4be993b
fix
ping-ke Sep 22, 2024
a5cd7de
fix bug
ping-ke Sep 24, 2024
86f3b31
fix bug
ping-ke Sep 24, 2024
43f4a3a
change integration test to run 3 times every week
ping-ke Sep 30, 2024
8d709fa
Merge branch 'main' into integratiointest
ping-ke Sep 30, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 61 additions & 0 deletions .github/workflows/integration-test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
name: Integration Test
on: [push]

jobs:
es-node-integration-test:
runs-on: self-hosted
timeout-minutes: 2880

steps:
- uses: actions/checkout@v3

- name: Set up Go
uses: actions/setup-go@v4
with:
go-version: '1.21'

- name: Use Node.js
uses: actions/setup-node@v3
with:
node-version: '20.x'

- name: Install Foundry
uses: foundry-rs/foundry-toolchain@v1
with:
version: nightly

- name: Deploy Contracts
run: |
cd ../storage-contracts-v1
git checkout main
git pull
npm install
git submodule init && git submodule update
npx hardhat run scripts/deployL2-it.js --network qkc_testnet >> deploy.log
echo ES_NODE_CONTRACT_ADDRESS=`cat .caddr` >> "$GITHUB_ENV"

- name: Build and Run Bootnode Node
run: |
cd ../es-node
make
./run-l2-it-rpc.sh > es-node-it-bootnode.log&
ping-ke marked this conversation as resolved.
Show resolved Hide resolved

- name: Set ENV Parameters
run: |
echo ES_NODE_UPLOADER_PRIVATE_KEY=`cat ../uploader.key` >> "$GITHUB_ENV"
echo ES_NODE_SIGNER_PRIVATE_KEY=`cat ../private.key` >> "$GITHUB_ENV"
echo ES_NODE_STORAGE_MINER=0x5C935469C5592Aeeac3372e922d9bCEabDF8830d >> "$GITHUB_ENV"

- name: Upload Blobs
run: |
cd ./integration_tests/scripts
ping-ke marked this conversation as resolved.
Show resolved Hide resolved
npm install --force
node ituploader.js > upload.log

- name: Test
run: |
./run-l2-it.sh > es-node-it.log&
cp ./integration_tests/scripts/.data ./cmd/integration-test-server/.data
cd ./cmd/integration-test-server
ping-ke marked this conversation as resolved.
Show resolved Hide resolved
go build
./integration-test-server > itserver.log
250 changes: 250 additions & 0 deletions cmd/integration-test-server/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,250 @@
// Copyright 2022-2023, EthStorage.
// For license information, see https://github.com/ethstorage/es-node/blob/main/LICENSE

package main

import (
"bufio"
"bytes"
"encoding/json"
"errors"
"flag"
"fmt"
"io"
"math"
"net/http"
"os"
"time"

"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/log"
"github.com/ethstorage/go-ethstorage/cmd/es-utils/utils"
es "github.com/ethstorage/go-ethstorage/ethstorage"
"github.com/ethstorage/go-ethstorage/ethstorage/node"
prv "github.com/ethstorage/go-ethstorage/ethstorage/prover"
)

const (
expectedSaidHelloTime = 10 * time.Minute
expectedStateRefreshTime = 5 * time.Minute
executionTime = 2 * time.Hour

kvEntries = 32768
kvSize = 128 * 1024
dataSize = 126976

blobEmptyFillingMask = byte(0b10000000)

uploadedDataFile = ".data"
shardFile = "../../es-data-it/shard-0.dat"
)

var (
portFlag = flag.Int("port", 9096, "Listener port for the es-node to report node status")
)

var (
errorMessages = make([]string, 0)
lastQueryTime = time.Now()
lastRecord *node.NodeState
hasConnectedPeer = false
testLog = log.New("IntegrationTest")
prover = prv.NewKZGProver(testLog)
)

func HelloHandler(w http.ResponseWriter, r *http.Request) {
body, err := io.ReadAll(r.Body)
if err != nil {
addErrorMessage(fmt.Sprintf("Read Hello body failed with error %s", err.Error()))
return
}
log.Info("Get hello from node", "id", string(body))

if time.Since(lastQueryTime) > expectedSaidHelloTime {
addErrorMessage(fmt.Sprintf("Get Hello message later then expect time %v real value %v", expectedSaidHelloTime, time.Since(lastQueryTime)))
}
lastQueryTime = time.Now()
log.Info("Get Hello request from es-node", "id", string(body))

answer := `{"status":"ok"}`
w.Write([]byte(answer))
}

func ReportStateHandler(w http.ResponseWriter, r *http.Request) {
if time.Since(lastQueryTime) > expectedStateRefreshTime*2 {
addErrorMessage(fmt.Sprintf("Get Hello message later then expect time %v real value %v",
expectedStateRefreshTime*2, time.Since(lastQueryTime)))
}
lastQueryTime = time.Now()

body, err := io.ReadAll(r.Body)
if err != nil {
addErrorMessage(fmt.Sprintf("Read ReportState body failed with error %s", err.Error()))
return
}

state := &node.NodeState{}
err = json.Unmarshal(body, state)
if err != nil {
addErrorMessage(fmt.Sprintf("Parse node state failed with error %s", err.Error()))
w.Write([]byte(fmt.Sprintf(`{"status":"error", "err message":"%s"}`, err.Error())))
return
}

// If no state updated
log.Info("Get state from peer", "peer id", state.Id, "Version", state.Version)
if lastRecord != nil {
checkState(lastRecord, state)
}

lastRecord = state

w.Write([]byte(`{"status":"ok"}`))
}

func checkState(oldState, newState *node.NodeState) {
if len(oldState.Shards) != len(newState.Shards) {
ping-ke marked this conversation as resolved.
Show resolved Hide resolved
addErrorMessage(fmt.Sprintf("shards count mismatch between two state, new %d, old %d", len(newState.Shards), len(oldState.Shards)))
return
}

for _, shardState := range newState.Shards {
check := false
for _, oldShardState := range oldState.Shards {
if shardState.ShardId != oldShardState.ShardId {
continue
}
check = true
if shardState.SyncState.PeerCount > 0 {
hasConnectedPeer = true
}

if oldShardState.SyncState.SyncProgress < 10000 &&
(shardState.SyncState.BlobsSynced <= oldShardState.SyncState.BlobsSynced ||
shardState.SyncState.SyncProgress <= oldShardState.SyncState.SyncProgress) {
addErrorMessage(fmt.Sprintf("es-node sync progress do not increase in %f minutes, "+
"old synced: %d, new synced %d; old progress: %d, new progress: %d", expectedStateRefreshTime.Minutes(), oldShardState.SyncState.BlobsSynced,
shardState.SyncState.BlobsSynced, oldShardState.SyncState.SyncProgress, shardState.SyncState.SyncProgress))
}
if oldShardState.SyncState.FillEmptyProgress < 10000 &&
(shardState.SyncState.EmptyFilled < oldShardState.SyncState.EmptyFilled ||
shardState.SyncState.FillEmptyProgress < oldShardState.SyncState.FillEmptyProgress) {
addErrorMessage(fmt.Sprintf("es-node fill empty progress do not increase in %f minutes, "+
"old filled: %d, new filled %d; old progress: %d, new progress: %d", expectedStateRefreshTime.Minutes(), oldShardState.SyncState.EmptyFilled,
shardState.SyncState.EmptyFilled, oldShardState.SyncState.FillEmptyProgress, shardState.SyncState.FillEmptyProgress))
}

if oldShardState.SyncState.FillEmptyProgress == 10000 && oldShardState.SyncState.SyncProgress == 10000 &&
(shardState.MiningState.MiningPower == 0 || shardState.MiningState.SamplingTime == 0) {
addErrorMessage("Mining should be start after sync done.")
}
}
if !check {
addErrorMessage(fmt.Sprintf("Shard %d in the new state do not exist in the old state", shardState.ShardId))
}
}
}

func checkFinalState(state *node.NodeState) {
if state == nil {
addErrorMessage("No state submitted during the test")
return
}
if !hasConnectedPeer {
addErrorMessage("es-node peer count should larger than 0")
}

log.Info("Final state", "id", state.Id, "version", state.Version)
for _, shardState := range state.Shards {
if shardState.SyncState.SyncProgress != 10000 {
ping-ke marked this conversation as resolved.
Show resolved Hide resolved
addErrorMessage("Sync should be finished during the test")
}
if shardState.SyncState.FillEmptyProgress != 10000 {
addErrorMessage("Fill should be finished during the test")
}
if shardState.MiningState.SamplingTime == 0 || shardState.MiningState.MiningPower == 0 {
addErrorMessage("Mining should be start after sync done.")
}
if shardState.SubmissionState.LastSucceededTime == 0 || shardState.SubmissionState.Succeeded == 0 {
addErrorMessage("At lease one block should be mined successfully during the test.")
}
if shardState.SubmissionState.Failed > 0 {
addErrorMessage(fmt.Sprintf("%d submission failed during the test.", shardState.SubmissionState.Failed))
}
log.Info("Final state", "id", state.Id, "shard", shardState.ShardId, "miner", shardState.Miner, "sync progress",
shardState.SyncState.SyncProgress, "fill progress", shardState.SyncState.FillEmptyProgress, "mining power",
shardState.MiningState.MiningPower, "sampling time", shardState.MiningState.SamplingTime, "succeeded submission",
shardState.SubmissionState.Succeeded, "failed submission", shardState.SubmissionState.Failed, "dropped submission",
shardState.SubmissionState.Dropped, "last succeeded time", shardState.SubmissionState.LastSucceededTime)
}
}

func verifyData() error {
file, err := os.OpenFile(uploadedDataFile, os.O_RDONLY, 0755)
if err != nil {
return err
}
defer file.Close()

fileScanner := bufio.NewScanner(file)
fileScanner.Buffer(make([]byte, dataSize*2), kvSize*2)
fileScanner.Split(bufio.ScanLines)

df, err := es.OpenDataFile(shardFile)
if err != nil {
return err
}

ds := es.NewDataShard(0, kvSize, kvEntries, kvSize)
ds.AddDataFile(df)

i := uint64(0)
for fileScanner.Scan() {
expectedData := common.Hex2Bytes(fileScanner.Text())
blobs := utils.EncodeBlobs(expectedData)
commit, _ := ds.ReadMeta(i)
data, err := ds.Read(i, kvSize, common.BytesToHash(commit))
if err != nil {
return errors.New(fmt.Sprintf("read %d from shard fail with err: %s", i, err.Error()))
}
if bytes.Compare(blobs[0][:], data) != 0 {
return errors.New(fmt.Sprintf("compare data %d fail, expected data %s; data: %s",
i, common.Bytes2Hex(blobs[0][:256]), common.Bytes2Hex(data[:256])))
}
i++
}
return nil
}

func addErrorMessage(errMessage string) {
log.Warn("Add error message", "msg", errMessage)
errorMessages = append(errorMessages, errMessage+"\n")
}

func listenAndServe(port int) error {
http.HandleFunc("/hello", HelloHandler)
ping-ke marked this conversation as resolved.
Show resolved Hide resolved
http.HandleFunc("/reportstate", ReportStateHandler)
return http.ListenAndServe(fmt.Sprintf(":%d", port), nil)
}

func main() {
// Parse the flags and set up the logger to print everything requested
flag.Parse()
log.Root().SetHandler(log.LvlFilterHandler(log.Lvl(3), log.StreamHandler(os.Stderr, log.TerminalFormat(true))))

if *portFlag < 0 || *portFlag > math.MaxUint16 {
log.Crit("Invalid port")
}

go listenAndServe(*portFlag)

time.Sleep(executionTime)
checkFinalState(lastRecord)
if err := verifyData(); err != nil {
addErrorMessage(err.Error())
}

if len(errorMessages) > 0 {
log.Crit(fmt.Sprintf("integration test fail %v", errorMessages))
}
}
2 changes: 1 addition & 1 deletion ethstorage/p2p/node.go
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ func (n *NodeP2P) init(resourcesCtx context.Context, rollupCfg *rollup.EsConfig,
// As the node host enable NATService, which will create a new connection with another
// peer id and its Addrs will not be set to Peerstore, so if len of peer Addrs is 0,
// then ignore this connection.
log.Debug("No addresses to get shard list, return without close conn", "peer", remotePeerId)
log.Debug("No addresses to get shard list, return without close conn", "peer", remotePeerId, "remote address", conn.RemoteMultiaddr().String())
return
}
css, err := n.Host().Peerstore().Get(remotePeerId, protocol.EthStorageENRKey)
Expand Down
3 changes: 0 additions & 3 deletions ethstorage/p2p/protocol/syncclient.go
Original file line number Diff line number Diff line change
Expand Up @@ -895,12 +895,9 @@ func (s *SyncClient) assignFillEmptyBlobTasks() {
s.notifyUpdate()
s.wg.Done()
}()
t := time.Now()
next, err := s.FillFileWithEmptyBlob(start, limit)
if err != nil {
log.Warn("Fill in empty fail", "err", err.Error())
} else {
log.Debug("Fill in empty done", "time", time.Now().Sub(t).Seconds())
}
filled := next - start

Expand Down
5 changes: 4 additions & 1 deletion init.sh
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ zkp_impl=1
# ZK prover mode, 1: one proof per sample, 2: one proof for multiple samples.
# Note: currently only zk prover mode 2 is supported
zkp_mode=2
data_dir="./es-data"

remaining_args=""

Expand All @@ -23,6 +24,9 @@ while [ $# -gt 0 ]; do
elif [[ $1 == --miner.zk-prover-mode ]]; then
zkp_mode=$2
shift 2
elif [[ $1 == --datadir ]]; then
data_dir=$2
shift 2
else
remaining_args="$remaining_args $1"
shift
Expand Down Expand Up @@ -99,7 +103,6 @@ if [ "$zkp_impl" = 1 ]; then

fi

data_dir="./es-data"
storage_file_0="$data_dir/shard-0.dat"

es_node_init="$executable init --shard_index 0 \
Expand Down
Loading
Loading