diff --git a/.github/workflows/cilint.yml b/.github/workflows/cilint.yml new file mode 100644 index 0000000..74fe256 --- /dev/null +++ b/.github/workflows/cilint.yml @@ -0,0 +1,42 @@ +name: golangci-lint + +on: + pull_request: + push: + branches: + - "main" + - "dev" + +env: + GO_VERSION: stable + GOLANGCI_LINT_VERSION: v1.60 + +jobs: + detect-modules: + runs-on: ubuntu-latest + outputs: + modules: ${{ steps.set-modules.outputs.modules }} + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-go@v5 + with: + go-version: ${{ env.GO_VERSION }} + - id: set-modules + run: echo "modules=$(go list -m -json | jq -s '.' | jq -c '[.[].Dir]')" >> $GITHUB_OUTPUT + + golangci-lint: + needs: detect-modules + runs-on: ubuntu-latest + strategy: + matrix: + modules: ${{ fromJSON(needs.detect-modules.outputs.modules) }} + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-go@v5 + with: + go-version: ${{ env.GO_VERSION }} + - name: golangci-lint ${{ matrix.modules }} + uses: golangci/golangci-lint-action@v6 + with: + version: ${{ env.GOLANGCI_LINT_VERSION }} + working-directory: ${{ matrix.modules }} \ No newline at end of file diff --git a/.github/workflows/go.yml b/.github/workflows/go.yml new file mode 100644 index 0000000..81fedb8 --- /dev/null +++ b/.github/workflows/go.yml @@ -0,0 +1,38 @@ +name: ci + +on: + push: + branches: ["main","dev"] + + pull_request: + branches: ["main","dev"] + + + issues: + types: + - opened + - labeled + +jobs: + + build: + runs-on: ubuntu-latest + strategy: + matrix: + go-version: ['1.22.3'] + + steps: + - uses: actions/checkout@v4 + - name: Setup Go ${{ matrix.go-version }} + uses: actions/setup-go@v4 + with: + go-version: ${{ matrix.go-version }} + cache: false + + - name: Build + run: go build -v ./... + + - name: Test + run: go test -v ./... + env: + GOOS: linux diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml new file mode 100644 index 0000000..80148cd --- /dev/null +++ b/.github/workflows/test.yml @@ -0,0 +1,41 @@ +name: Run Tests on PR + +on: + pull_request: + push: + branches: + - main + - dev + +env: + GO_VERSION: stable + GOLANGCI_LINT_VERSION: v1.60 + +jobs: + test: + runs-on: ubuntu-latest + + steps: + - name: Checkout code + uses: actions/checkout@v3 + + - name: Go set up + uses: actions/setup-go@v4 + with: + go-version: ${{ env.GO_VERSION }} + + - name: Cache Go modules + uses: actions/cache@v3 + with: + path: | + ~/go/pkg/mod + ~/.cache/go-build + key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }} + restore-keys: | + ${{ runner.os }}-go- + + - name: Install dependencies + run: go mod tidy + + - name: Run tests + run: go test ./... -v diff --git a/README.md b/README.md index 7c49188..fb605e8 100644 --- a/README.md +++ b/README.md @@ -4,6 +4,4 @@ NOTE: The functions need not have correct parameters and return data types yet ## Suggestions -- `Option` can be implemented by taking a pointer to a `uint8` value ? -- we can create a `constants.go` if needed. -- if we need to modify some struct datatype , we can have a method taking it as a pointer and modify , instead of returning after making a new copy + diff --git a/common/errors.go b/common/errors.go index 8cebb32..d9b2898 100644 --- a/common/errors.go +++ b/common/errors.go @@ -1,10 +1,47 @@ package common +import "fmt" + type BlockNotFoundError struct { + Block BlockTag +} + +func NewBlockNotFoundError(block BlockTag) BlockNotFoundError { + return BlockNotFoundError{Block: block} +} + +func (e BlockNotFoundError) Error() string { + return fmt.Sprintf("block not available: %s", e.Block) } + +// need to confirm how such primitive types will be imported +type hash [32]byte; + type SlotNotFoundError struct { + slot hash +} + +func NewSlotNotFoundError(slot hash) SlotNotFoundError { + return SlotNotFoundError{slot: slot} +} + +func (e SlotNotFoundError) Error() string { + return fmt.Sprintf("slot not available: %s", e.slot) } type RpcError struct { + method string + error error +} + +func NewRpcError(method string, err error) RpcError { + return RpcError{ + method: method, + error: err, + } +} + +func (e RpcError) Error() string { + return fmt.Sprintf("rpc error on method: %s, message: %s", e.method, e.error.Error()) } diff --git a/common/utils.go b/common/utils.go index 4d71c0d..deb1423 100644 --- a/common/utils.go +++ b/common/utils.go @@ -1,19 +1,49 @@ package common +import ( + "encoding/hex" + "encoding/json" + "fmt" + "strings" + + "github.com/ethereum/go-ethereum/common" +) + // if we need to export the functions , just make their first letter capitalised -func hex_str_to_bytes() { +func Hex_str_to_bytes(s string) ([]byte, error) { + s = strings.TrimPrefix(s, "0x") + + bytesArray, err := hex.DecodeString(s) + + if err != nil { + return nil, err + } + + return bytesArray, nil } -func address_to_hex_string() { +func Address_to_hex_string(addr common.Address) string { + bytesArray := addr.Bytes() + return fmt.Sprintf("0x%x", hex.EncodeToString(bytesArray)) } -func u64_to_hex_string() { +func U64_to_hex_string(val uint64) string { + return fmt.Sprintf("0x%x", val) } -func bytes_deserialize() { +func Bytes_deserialize(data []byte) ([]byte, error) { + var hexString string + if err := json.Unmarshal(data, &hexString); err != nil { + return nil, err + } + return Hex_str_to_bytes(hexString) } -func bytes_serialize() { - +func Bytes_serialize(bytes []byte) ([]byte, error) { + if bytes == nil { + return json.Marshal(nil) + } + hexString := hex.EncodeToString(bytes) + return json.Marshal(hexString) } diff --git a/config/types.go b/config/types.go index 1ff2cd6..77c0d72 100644 --- a/config/types.go +++ b/config/types.go @@ -1,16 +1,79 @@ package config -type ChainConfig struct{ +import ( + "encoding/hex" + "encoding/json" +) +type ChainConfig struct { + ChainID uint64 `json:"chain_id"` + GenesisTime uint64 `json:"genesis_time"` + GenesisRoot []byte `json:"genesis_root"` } -type Fork struct{ - epoch uint64 - fork_version []uint8 + +type Fork struct { + Epoch uint64 `json:"epoch"` + ForkVersion []byte `json:"fork_version"` +} + +type Forks struct { + Genesis Fork `json:"genesis"` + Altair Fork `json:"altair"` + Bellatrix Fork `json:"bellatrix"` + Capella Fork `json:"capella"` + Deneb Fork `json:"deneb"` +} + +func (c ChainConfig) MarshalJSON() ([]byte, error) { + type Alias ChainConfig + return json.Marshal(&struct { + Alias + GenesisRoot string `json:"genesis_root"` + }{ + Alias: (Alias)(c), + GenesisRoot: hex.EncodeToString(c.GenesisRoot), + }) +} + +func (c *ChainConfig) UnmarshalJSON(data []byte) error { + type Alias ChainConfig + aux := &struct { + *Alias + GenesisRoot string `json:"genesis_root"` + }{ + Alias: (*Alias)(c), + } + if err := json.Unmarshal(data, &aux); err != nil { + return err + } + var err error + c.GenesisRoot, err = hex.DecodeString(aux.GenesisRoot) + return err +} + +func (f Fork) MarshalJSON() ([]byte, error) { + type Alias Fork + return json.Marshal(&struct { + Alias + ForkVersion string `json:"fork_version"` + }{ + Alias: (Alias)(f), + ForkVersion: hex.EncodeToString(f.ForkVersion), + }) +} + +func (f *Fork) UnmarshalJSON(data []byte) error { + type Alias Fork + aux := &struct { + *Alias + ForkVersion string `json:"fork_version"` + }{ + Alias: (*Alias)(f), + } + if err := json.Unmarshal(data, &aux); err != nil { + return err + } + var err error + f.ForkVersion, err = hex.DecodeString(aux.ForkVersion) + return err } -type Forks struct{ - genesis Fork - altair Fork - bellatrix Fork - capella Fork - deneb Fork -} \ No newline at end of file diff --git a/config/utils.go b/config/utils.go index c35ef0a..7bc46da 100644 --- a/config/utils.go +++ b/config/utils.go @@ -1,9 +1,40 @@ package config +import ( + "encoding/hex" + "encoding/json" -func bytes_serialise(){ + "github.com/BlocSoc-iitr/selene/common" +) + +func bytes_serialise(bytes []byte) ([]byte, error) { + + if bytes == nil { + return json.Marshal(nil) + } + bytesString := hex.EncodeToString(bytes) + result, err := json.Marshal(bytesString) + if err != nil { + return nil, err + } + return result, nil + +} + +func bytes_deserialise(data []byte) ([]byte, error) { + var bytesOpt *string + if err := json.Unmarshal(data, &bytesOpt); err != nil { + return nil, err + } + + if bytesOpt == nil { + return nil, nil + } else { + bytes, err := common.Hex_str_to_bytes(*bytesOpt) + if err != nil { + return nil, err + } + return bytes, nil + } } -func bytes_deserialise(){ - -} \ No newline at end of file