Skip to content

Commit

Permalink
Merge pull request #13 from scorum/betting
Browse files Browse the repository at this point in the history
Betting
  • Loading branch information
mikluke authored Nov 19, 2018
2 parents de66245 + fe83ebd commit 50db655
Show file tree
Hide file tree
Showing 15 changed files with 1,069 additions and 135 deletions.
24 changes: 24 additions & 0 deletions apis/betting/api_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package betting

import (
"testing"

"github.com/google/uuid"
"github.com/scorum/scorum-go/transport/http"
"github.com/stretchr/testify/require"
)

const nodeHTTPS = "https://testnet.scorum.com"

func TestGetGameWinners(t *testing.T) {
t.Skip("need to start and finish game to get results")
transport := http.NewTransport(nodeHTTPS)
api := NewAPI(transport)

uuid, err := uuid.Parse("3bd3fb0a-4c3c-4103-b736-61849157062a")
require.NoError(t, err)

winners, err := api.GetGameWinners(uuid)
require.NoError(t, err)
require.NotEmpty(t, winners)
}
9 changes: 8 additions & 1 deletion apis/blockchain_history/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,9 +49,16 @@ func (api *API) GetOperationsInBlock(blockNum uint32, opType AppliedOperationTyp
return resp, err
}

// Get sequence of 'limit' blocks from offset
// Get sequence of 'limit' blocks with transactions from offset
func (api *API) GetBlocksHistory(blockNum uint32, limit uint32) (BlockHistory, error) {
var resp BlockHistory
err := api.call("get_blocks_history", []interface{}{blockNum, limit}, &resp)
return resp, err
}

// Get sequence of 'limit' blocks with operations from offset
func (api *API) GetBlocks(blockNum uint32, limit uint32) (Blocks, error) {
var resp Blocks
err := api.call("get_blocks", []interface{}{blockNum, limit}, &resp)
return resp, err
}
31 changes: 30 additions & 1 deletion apis/blockchain_history/api_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,10 @@ package blockchain_history
import (
"testing"

"math"

"github.com/scorum/scorum-go/transport/http"
"github.com/stretchr/testify/require"
"math"
)

const nodeHTTPS = "https://testnet.scorum.com"
Expand Down Expand Up @@ -69,3 +70,31 @@ func TestGetBlocksHistory(t *testing.T) {
})

}

func TestGetBlocks(t *testing.T) {
transport := http.NewTransport(nodeHTTPS)
api := NewAPI(transport)

t.Run("from beginning", func(t *testing.T) {
blocks, err := api.GetBlocks(100, 100)
require.NoError(t, err)
require.Len(t, blocks, 100)
for _, v := range blocks {
require.NotEmpty(t, v.Operations)
}
})

t.Run("from end", func(t *testing.T) {
blocks, err := api.GetBlocks(math.MaxUint32, 100)
require.NoError(t, err)
require.NotEmpty(t, blocks)
for _, v := range blocks {
require.NotEmpty(t, v.Operations)
}
})

t.Run("exceeded limit", func(t *testing.T) {
_, err := api.GetBlocks(math.MaxUint32, 2000)
require.Error(t, err)
})
}
26 changes: 26 additions & 0 deletions apis/blockchain_history/data.go
Original file line number Diff line number Diff line change
Expand Up @@ -87,3 +87,29 @@ func (bh *BlockHistory) UnmarshalJSON(b []byte) (err error) {

return nil
}

type Blocks map[uint32]*types.OperationsBlock

func (bs *Blocks) UnmarshalJSON(b []byte) (err error) {
// unmarshal array
var blocks []json.RawMessage
if err := json.Unmarshal(b, &blocks); err != nil {
return err
}

bhm := make(Blocks, len(blocks))

// foreach block
for _, v := range blocks {
var block types.OperationsBlock
if err := json.Unmarshal(v, &block); err != nil {
return err
}

bhm[block.BlockNum] = &block
}

*bs = bhm

return nil
}
5 changes: 5 additions & 0 deletions client.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (

"github.com/pkg/errors"
"github.com/scorum/scorum-go/apis/account_history"
"github.com/scorum/scorum-go/apis/betting"
"github.com/scorum/scorum-go/apis/blockchain_history"
"github.com/scorum/scorum-go/apis/chain"
"github.com/scorum/scorum-go/apis/database"
Expand Down Expand Up @@ -33,6 +34,9 @@ type Client struct {
// BlockchainHistory represents blockchain_history_api
BlockchainHistory *blockchain_history.API

// Betting represents betting_api
Betting *betting.API

// Chain represents chain_api
Chain *chain.API
}
Expand All @@ -45,6 +49,7 @@ func NewClient(cc caller.CallCloser) *Client {
client.AccountHistory = account_history.NewAPI(client.cc)
client.NetworkBroadcast = network_broadcast.NewAPI(client.cc)
client.BlockchainHistory = blockchain_history.NewAPI(client.cc)
client.Betting = betting.NewAPI(client.cc)
return client
}

Expand Down
64 changes: 63 additions & 1 deletion types/block.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
package types

import "encoding/json"
import (
"encoding/json"
"fmt"

"github.com/bitly/go-simplejson"
)

type BlockHeader struct {
TransactionMerkleRoot string `json:"transaction_merkle_root"`
Expand All @@ -23,3 +28,60 @@ type Block struct {
Extensions []json.RawMessage `json:"extensions"`
Signatures []string `json:"signatures"`
}

type OperationsBlock struct {
BlockNum uint32 `json:"block_num"`
Previous string `json:"previous"`
WitnessSignature string `json:"witness_signature"`
Timestamp string `json:"timestamp"`
Witness string `json:"witness"`
TransactionMerkleRoot string `json:"transaction_merkle_root"`
Operations []OperationInfo `json:"operations"`
Extensions []json.RawMessage `json:"extensions"`
}

type OperationInfo struct {
Operation Operation
Timestamp Time
TransactionID string
}

func (oi *OperationInfo) UnmarshalJSON(b []byte) error {
j, err := simplejson.NewJson(b)
if err != nil {
return err
}

tb, err := j.Get("timestamp").String()
if err != nil {
return err
}

if err := oi.Timestamp.UnmarshalJSON([]byte(fmt.Sprintf(`"%s"`, tb))); err != nil {
return err
}

oi.TransactionID, err = j.Get("trx_id").String()
if err != nil {
return err
}

tuple := j.GetPath("op")

opType, err := tuple.GetIndex(0).String()
if err != nil {
return err
}

data, err := tuple.GetIndex(1).Encode()
if err != nil {
return err
}

oi.Operation, err = unmarshalOperation(opType, data)
if err != nil {
return err
}

return nil
}
53 changes: 53 additions & 0 deletions types/game.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
package types

import (
"encoding/json"
"github.com/pkg/errors"
"reflect"
)

const (
SoccerGameType = 0
HockeyGameType = 1
)

var (
errUnsupportedGameType = errors.New("unsupported game type")
)

type GameType uint8

var GameTypeNames = map[GameType]string{
SoccerGameType: "soccer_game",
HockeyGameType: "hockey_game",
}

func (g GameType) MarshalJSON() ([]byte, error) {
var err error

a := make([]json.RawMessage, 2)
a[0], err = json.Marshal(GameTypeNames[g])
if err != nil {
return nil, err
}
a[1] = json.RawMessage("{}")

return json.Marshal(a)
}

func (g *GameType) UnmarshalJSON(b []byte) error {
var gt []interface{}
if err := json.Unmarshal(b, &gt); err != nil {
return err
}

gName := gt[0].(string)
for k, v := range GameTypeNames {
if v == gName {
reflect.Indirect(reflect.ValueOf(g)).SetUint(uint64(k))
return nil
}
}

return errUnsupportedGameType
}
30 changes: 30 additions & 0 deletions types/game_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package types

import (
"encoding/json"
"github.com/stretchr/testify/require"
"testing"
)

const (
testGameSoccerJSON = `["soccer_game",{}]`
testGameHockeyJSON = `["hockey_game",{}]`
testGameUnsupportedJSON = `["doka2_trade_game",{}]`
)

func TestGameSocckerUnmarshalJSON(t *testing.T) {
var game GameType
require.NoError(t, json.Unmarshal([]byte(testGameSoccerJSON), &game))
require.EqualValues(t, 0, game)
}

func TestGameHockeyUnmarshalJSON(t *testing.T) {
var game GameType
require.NoError(t, json.Unmarshal([]byte(testGameHockeyJSON), &game))
require.EqualValues(t, 1, game)
}

func TestUnsupportedUnmarshalJSON(t *testing.T) {
var game GameType
require.Error(t, json.Unmarshal([]byte(testGameUnsupportedJSON), &game))
}
Loading

0 comments on commit 50db655

Please sign in to comment.