Code Monkey home page Code Monkey logo

valkyrie's Introduction

Valkyrie Game Aggregator

An open source game aggregator written in Go.

For general information about Valkyrie, please check this out!

Information for developers and other interested parties is found below.

Building

Valkyrie is built from source by running:

go build

Running

You can then run Valkyrie using:

./valkyrie -config path/to/config.yml

Two template config files come with the Valkyrie software. These can be found here.

Custom tasks

Valkyrie uses Task as a task runner, e.g. for building the application. To use the tool please refer to its installation page.

Note: Windows users are recommended to use PowerShell. Custom tasks may be used for build purposes, etc. To run most of these in Windows you need to have installed wsl to enable bash. Another helpful tool is Chocolatey, which can be used on windows to install other programs, like Task.

A Taskfile.yml is located in the project root which describes custom tasks that can be run for the project.

To run the default tasks (generate, lint & test), simply run:

task

To list available tasks run:

task -l

Docker

Valkyrie image is built using:

docker build -t valkyrie .

You can then run the Valkyrie container using:

docker run -v /absolute/path/config.yml:/app/config.yml valkyrie -config config.yml

Helm

A Helm chart is provided to run Valkyrie in Kubernetes.

For instructions how to use the chart please refer to helm/README.md.

Linux service

Valkyrie can be installed as systemd service by these steps:

  • obtaining a linux release package of valkyrie, named like valkyrie-X.X.X-linux-amd64.tar.gz
  • unpacking and setting up a configuration file named config.yml
  • executing ./svc.sh install to setup the service

Swagger

To include swagger ui to view all exposed endpoints in Valkyrie you can use the build tag dev. After starting Valkyrie, simply direct your web browser to localhost:/swagger and take a look at the appropriate endpoints.

go build -tags=dev

Documentation

Check documentation site for the latest and most extensive information.

Architecture

You can view the project following the c4 model by starting a structurizr server on localhost:8090 using task:

task c4model

System landscape view where Valkyrie fits in:

system landscape

Components view of Valkyrie, how the internals connect to each other. components view

Codebase structure

Going through the code there are two folders that are more important than others, <providers> and <pam>. In these you will find the relevant components that makes Valkyrie modular. In <providers> you will find each available game provider module that is integrated with Valkyrie. More in detail how to create a new provider module and the code structure of them can be found here. When starting a Valkyrie instance you provide it with a config yaml file containing what provider modules you want to have enabled. Read more about the configuration file here. In the root <provider>-folder is the implementations of provider/docs/operator_api.yml. It is the specification the operator can use to send request to Valkyrie that will be forwarded toward the provider. You can read more here.

<pam> contains implemented PAMs that are available. Each provider is using pam.PamClient found in /pam/client.go to communicate with the PAM. The available PAMs should implement this interface. Similar to the providers, what PAM is used is based on the configuration file provided at runtime. There is an oapi specification that is used by <genericpam> called pam_api.yml that can be read here. Fulfilling this specification will enable you to use <genericpam>. In the diagram above, <genericpam> and <vplugin> would be the "PAM Client". "PAM Plugin", from the diagram, would be used in the case of <vplugin>. <vplugin> is utilizing hashicorp go-plugin to keep the pam implementation in a separate process from Valkyrie. This enables you to keep your own private implementation of a PAM. More on this can be read here.

+ configs/                # The parsing of configuration yaml
+ example/                # Code examples
  + example-game-provider # An example provider module with information about the different components needed to make your own provider module
+ internal/               # Shared utility packages
+ ops/                    # Logging and tracing
+ pam/
  + generic_pam/          # PAM following pam_api.yaml specification
  + vplugin/              # PAM plugin
    - client.go           # Contains the interface the plugin need to follow
  - generate.go           # used to generate the models defined in pam_api.yml, using oapi-codegen
  - client.go             # Contains interface the pam must fulfil. The interface that is used by the game provider modules.
+ provider/
  + gameProvider_X/       # Game provider modules
  + gameProvider_Y/
  + evolution/
  + redtiger/
  - xyz_controller.go     # Handler functions for operator_api.yml
+ rest/                   # Http client for making requests
+ routes/                 # Setting up the routes for each provider and the operator
+ server/                 # Starting the Valkyrie servers, exposed toward Operator and Providers

"Provider Server" and "Operator Server" from the Component diagram above would be in routes/routes.go where the operator and provider routes are setup. It utilizes provider/registry.go to add the routes to the fiber.App. Each provider needs to implement both "Operator Router" and "Provider Router". They are implemented under {gameProvider}/router.go. For more details on all the "Provider Module"-components the example game provider can be viewed, with documentation through out the example.

CI

Valkyrie uses GitHub actions for continuous integration, which is described under workflows.

Pull requests will trigger Lint and Test jobs which are expected to pass before merging.

Commits to main branch will rerun Lint and Test, and if successful it will also build a pre-release version (x.y.z-pre.revno), which is uploaded to Docker Hub.

Releasing

  1. Choose a suitable release version following the Semantic Versioning format
  2. Before creating the release, make sure to update CHANGELOG.md, moving the entries from Unreleased to your release version and describe any new notable changes since the previous release.
  3. Finally, trigger the Release workflow in GitHub Actions and specify the version as argument.

The GitHub actions workflow will perform the following steps:

  • Run the full CI suite
  • Build and push container to Docker Hub
  • Build and push helm chart to Docker Hub
  • Build binaries for various platforms and upload to GitHub releases
  • Tag the version in git

Performance

Valkyrie aims to be lightweight and fast. While running single instances of Valkyrie and a PAM, we are able to generate and process the following number of bet requests (a.k.a debit/withdraw/stake) for the respective provider implementations (all run locally on an 2021 MacBook Pro w/ M1 MAX CPU, no tracing enabled and INFO log level).

Provider Requests/sec
Evolution 40700
Red Tiger 21000
Caleta 29200

Contribution guidelines

Read contribution guidelines here

Contact

If you have questions regarding an integration you can either post a question on GitHub or contact us on Discord.

valkyrie's People

Contributors

dependabot[bot] avatar genesisporridge avatar gnirb avatar goodnightanderson avatar gustavste avatar tommythe avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

valkyrie's Issues

Add some validation before release job to avoid failed releases

A release build is triggered by pushing a tag, but if the build fails its already to late to clean up the tag. Someone might have depended on it or even worse, it might be indexed by https://pkg.go.dev/

Discussed options:

  • create branch before tagging release and try to build everything beforehand validating that it works
  • create nightly build that tries to build everything

Pam Config

Hi Guys! I am thinking about changing PamConfig type for more definite, with concrete structure https://github.com/valkyrie-fnd/valkyrie/blob/main/configs/valkyrie_config.go#L92. Because of current PamConfig has type any for config values, environment variables cannot be resolved inside of config subsections, so it leads to some difficulties on parsing config via reflection. I think it would be better to use concrete config structure instead of using type any for config values. What do think about such suggestion?

Investigate golang dependency scanners

Alternatives:

Dependency Vulnerability IDs Package Highest Severity↓ CVE Count Confidence Evidence Count
github.com/go-openapi/jsonpointer:0.19.6 cpe:2.3:a:json-pointer_project:json-pointer:0.19.6:::::::* pkg:golang/github.com/go-openapi/[email protected] CRITICAL 1 High 6
github.com/decred/dcrd/crypto/blake256:1.0.0 cpe:2.3:a:decred:dcrd:1.0.0:::::::* pkg:golang/github.com/decred/dcrd/crypto/[email protected] HIGH 1 Low 6
github.com/ghodss/yaml:1.0.0 cpe:2.3:a:yaml_project:yaml:1.0.0:::::::* pkg:golang/github.com/ghodss/[email protected] HIGH 2 High 6
github.com/invopop/yaml:0.1.0 cpe:2.3:a:yaml_project:yaml:0.1.0:::::::* pkg:golang/github.com/invopop/[email protected] HIGH 2 High 6
github.com/prometheus/client_model:0.0.0-20190812154241-14fe0d1b01d4 cpe:2.3:a:prometheus:prometheus:0.0.0:::::::* pkg:golang/github.com/prometheus/[email protected] MEDIUM 1 Low 6

Idempotent requests are retried at connection close in rest/client.go

Describe the bug
To keep control over transaction logic, automatic retries should be avoided in rest client. In case of idempotent requests, fasthttp executes a number of automatic attempts unless a particular setting is added in creation of the http client in case of connection close response from the server.

To Reproduce
Steps to reproduce the behavior:

  1. Make sure the PAM returns "connection close" twice at a transaction request from a provider module
  2. Enter a bet transaction to the provider endpoint
  3. The transaction is however processed without error

Expected behavior
Expected response to caller should be an error since only one re-send attempt should be made.

Screenshots
N/A.

Desktop (please complete the following information):

  • OS: Windows 11
  • Browser: N/A
  • Version: N/A

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.