Skip to content

Commit

Permalink
Export RpcDaemon settings
Browse files Browse the repository at this point in the history
  • Loading branch information
canepat authored Apr 19, 2024
2 parents 2e4f273 + f5d7941 commit 1fa3163
Show file tree
Hide file tree
Showing 3 changed files with 118 additions and 6 deletions.
118 changes: 114 additions & 4 deletions bindings.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import (
"errors"
"fmt"
"math/big"
"strings"
"unsafe"
)

Expand Down Expand Up @@ -54,16 +55,31 @@ const (
var ErrInterrupted = errors.New("interrupted")
var ErrInvalidBlock = errors.New("invalid block")

type SilkwormLogLevel uint8

const (
LogLevelNone SilkwormLogLevel = iota
LogLevelCritical
LogLevelError
LogLevelWarning
LogLevelInfo
LogLevelDebug
LogLevelTrace
)

type Silkworm struct {
handle C.SilkwormHandle
}

func New(dataDirPath string, libMdbxVersion string) (*Silkworm, error) {
func New(dataDirPath string, libMdbxVersion string, numIOContexts uint32, logVerbosity SilkwormLogLevel) (*Silkworm, error) {
silkworm := &Silkworm{
handle: nil,
}

settings := &C.struct_SilkwormSettings{}
settings := &C.struct_SilkwormSettings{
log_verbosity: C.SilkwormLogLevel(logVerbosity),
num_contexts: C.uint32_t(numIOContexts),
}

if !C.go_string_copy(dataDirPath, &settings.data_dir_path[0], C.SILKWORM_PATH_SIZE) {
return nil, errors.New("silkworm.New failed to copy dataDirPath")
Expand All @@ -77,6 +93,10 @@ func New(dataDirPath string, libMdbxVersion string) (*Silkworm, error) {
if status == SILKWORM_OK {
return silkworm, nil
}
if status == SILKWORM_INCOMPATIBLE_LIBMDBX {
silkwormMdbxVersion := C.GoString(C.silkworm_libmdbx_version())
return nil, fmt.Errorf("silkworm_init error incompatible MDBX: E=%s S=%s", libMdbxVersion, silkwormMdbxVersion)
}
return nil, fmt.Errorf("silkworm_init error %d", status)
}

Expand Down Expand Up @@ -165,9 +185,99 @@ func (s *Silkworm) LibMdbxVersion() string {
return C.GoString(C.silkworm_libmdbx_version())
}

func (s *Silkworm) StartRpcDaemon(dbEnvCHandle unsafe.Pointer) error {
type RpcInterfaceLogSettings struct {
Enabled bool
ContainerFolder string
MaxFileSizeMB uint16
MaxFiles uint16
DumpResponse bool
}

func makeCRpcInterfaceLogSettings(settings RpcInterfaceLogSettings) (*C.struct_SilkwormRpcInterfaceLogSettings, error) {
cSettings := &C.struct_SilkwormRpcInterfaceLogSettings{
enabled: C.bool(settings.Enabled),
max_file_size_mb: C.uint16_t(settings.MaxFileSizeMB),
max_files: C.uint16_t(settings.MaxFiles),
dump_response: C.bool(settings.DumpResponse),
}
if !C.go_string_copy(settings.ContainerFolder, &cSettings.container_folder[0], C.SILKWORM_PATH_SIZE) {
return nil, errors.New("makeCRpcInterfaceLogSettings failed to copy ContainerFolder")
}
return cSettings, nil
}

type RpcDaemonSettings struct {
EthLogSettings RpcInterfaceLogSettings
EthAPIHost string
EthAPIPort int
EthAPISpec []string
NumWorkers uint32
CORSDomains []string
JWTFilePath string
JSONRPCCompatibility bool
WebSocketEnabled bool
WebSocketCompression bool
HTTPCompression bool
}

func joinStrings(values []string) string {
return strings.Join(values[:], ",")
}

func copyCORSDomains(list []string, cList *[C.SILKWORM_RPC_SETTINGS_CORS_DOMAINS_MAX][C.SILKWORM_RPC_SETTINGS_CORS_DOMAIN_SIZE]C.char) error {
listLen := len(list)
if listLen > C.SILKWORM_RPC_SETTINGS_CORS_DOMAINS_MAX {
return errors.New("copyCORSDomains: CORS domain list has too many items")
}
// Mark the list end with an empty string
if listLen < C.SILKWORM_RPC_SETTINGS_CORS_DOMAINS_MAX {
cList[listLen][0] = 0
}
for i, domain := range list {
if !C.go_string_copy(domain, &cList[i][0], C.SILKWORM_RPC_SETTINGS_CORS_DOMAIN_SIZE) {
return fmt.Errorf("copyCORSDomains: failed to copy CORS domain %d", i)
}
}
return nil
}

func makeCRpcDaemonSettings(settings RpcDaemonSettings) (*C.struct_SilkwormRpcSettings, error) {
eth_log_settings, err := makeCRpcInterfaceLogSettings(settings.EthLogSettings)
if err != nil {
return nil, err
}
cSettings := &C.struct_SilkwormRpcSettings{
eth_if_log_settings: *eth_log_settings,
eth_api_port: C.uint16_t(settings.EthAPIPort),
num_workers: C.uint32_t(settings.NumWorkers),
erigon_json_rpc_compatibility: C.bool(settings.JSONRPCCompatibility),
ws_enabled: C.bool(settings.WebSocketEnabled),
ws_compression: C.bool(settings.WebSocketCompression),
http_compression: C.bool(settings.HTTPCompression),
skip_internal_protocol_check: C.bool(false), // We do check internal protocol versions at startup for sanity
}
if !C.go_string_copy(settings.EthAPIHost, &cSettings.eth_api_host[0], C.SILKWORM_RPC_SETTINGS_HOST_SIZE) {
return nil, errors.New("makeCRpcDaemonSettings failed to copy EthAPIHost")
}
if !C.go_string_copy(joinStrings(settings.EthAPISpec), &cSettings.eth_api_spec[0], C.SILKWORM_RPC_SETTINGS_API_NAMESPACE_SPEC_SIZE) {
return nil, errors.New("makeCRpcDaemonSettings failed to copy EthAPISpec")
}
if err := copyCORSDomains(settings.CORSDomains, &cSettings.cors_domains); err != nil {
return nil, fmt.Errorf("makeCRpcDaemonSettings failed to copy CORSDomains: %w", err)
}
if !C.go_string_copy(settings.JWTFilePath, &cSettings.jwt_file_path[0], C.SILKWORM_PATH_SIZE) {
return nil, errors.New("makeCRpcDaemonSettings failed to copy JWTFilePath")
}
return cSettings, nil
}

func (s *Silkworm) StartRpcDaemon(dbEnvCHandle unsafe.Pointer, settings RpcDaemonSettings) error {
cEnv := (*C.MDBX_env)(dbEnvCHandle)
status := C.silkworm_start_rpcdaemon(s.handle, cEnv)
cSettings, err := makeCRpcDaemonSettings(settings)
if err != nil {
return err
}
status := C.silkworm_start_rpcdaemon(s.handle, cEnv, cSettings)
// Handle successful execution
if status == SILKWORM_OK {
return nil
Expand Down
4 changes: 3 additions & 1 deletion bindings_stub.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,12 @@ import (
var ErrInterrupted = errors.New("interrupted")
var ErrInvalidBlock = errors.New("invalid block")

type SilkwormLogLevel uint8

type Silkworm struct {
}

func New(dataDirPath string, libMdbxVersion string) (*Silkworm, error) {
func New(dataDirPath string, libMdbxVersion string, numIOContexts uint32, logVerbosity SilkwormLogLevel) (*Silkworm, error) {
return nil, errors.New("silkworm is not supported")
}

Expand Down
2 changes: 1 addition & 1 deletion bindings_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import (
)

func TestInit(t *testing.T) {
silkworm, err := New(t.TempDir(), "")
silkworm, err := New(t.TempDir(), "", 10, 0)
if err != nil {
t.Error(err)
}
Expand Down

0 comments on commit 1fa3163

Please sign in to comment.