Skip to content

Commit

Permalink
Merge branch 'staging' into bcalza/ratelim
Browse files Browse the repository at this point in the history
  • Loading branch information
brunocalza committed Jul 25, 2023
2 parents 7e5bac3 + ea1628e commit 30a70c5
Show file tree
Hide file tree
Showing 21 changed files with 946 additions and 137 deletions.
478 changes: 436 additions & 42 deletions README.md

Large diffs are not rendered by default.

5 changes: 3 additions & 2 deletions cmd/api/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -100,8 +100,9 @@ type ChainConfig struct {
Name string `default:""`
ChainID tableland.ChainID `default:"0"`
Registry struct {
EthEndpoint string `default:"eth_endpoint"`
ContractAddress string `default:"contract_address"`
EthEndpoint string `default:"eth_endpoint"`
ContractAddress string `default:"contract_address"`
ProviderAuthToken string `default:"provider_auth_token"`
}
EventFeed struct {
ChainAPIBackoff string `default:"15s"`
Expand Down
12 changes: 11 additions & 1 deletion cmd/api/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import (

"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/ethclient"
ethrpc "github.com/ethereum/go-ethereum/rpc"
"github.com/google/uuid"
_ "github.com/mattn/go-sqlite3"
"github.com/rs/zerolog/log"
Expand Down Expand Up @@ -185,11 +186,20 @@ func createChainIDStack(
return chains.ChainStack{}, fmt.Errorf("creating event feed store: %s", err)
}

conn, err := ethclient.Dial(config.Registry.EthEndpoint)
ethRPCClient, err := ethrpc.Dial(config.Registry.EthEndpoint)
if err != nil {
return chains.ChainStack{}, fmt.Errorf("failed to connect to ethereum endpoint: %s", err)
}

// For the Filecoin (314) chain, we need to set the auth token
// in the header of the request.
if config.ChainID == 314 && config.Registry.ProviderAuthToken != "" {
authToken := fmt.Sprintf("Bearer %s", config.Registry.ProviderAuthToken)
ethRPCClient.SetHeader("Authorization", authToken)
}

conn := ethclient.NewClient(ethRPCClient)

ef, err := efimpl.New(
eventFeedStore,
config.ChainID,
Expand Down
6 changes: 3 additions & 3 deletions cmd/healthbot/balancetracker.go
Original file line number Diff line number Diff line change
Expand Up @@ -162,9 +162,9 @@ func (t *BalanceTracker) initMetrics(chainID int, addr common.Address) error {
func getEthClient(config ChainConfig) (*ethclient.Client, error) {
var url, key string
var ok bool
if config.ChainID == 3141 {
url, ok = client.AnkrURLs[client.ChainID(config.ChainID)]
key = config.AnkrAPIKey
if config.ChainID == 314159 {
url, ok = client.GlifURLs[client.ChainID(config.ChainID)]
key = ""
} else {
url, ok = client.AlchemyURLs[client.ChainID(config.ChainID)]
key = config.AlchemyAPIKey
Expand Down
1 change: 1 addition & 0 deletions cmd/healthbot/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ type ChainConfig struct {
WalletPrivateKey string
AlchemyAPIKey string
AnkrAPIKey string
GlifAPIKey string
Probe struct {
CheckInterval string `default:"15s"`
ReceiptTimeout string `default:"20s"`
Expand Down
7 changes: 4 additions & 3 deletions cmd/healthbot/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,10 +58,11 @@ func main() {
chain.ContractAddr = common.HexToAddress(chainCfg.OverrideClient.ContractAddr)
}

// For Filecoin Hyperspace, we use Ankr endpoint
// For Filecoin Calibration, we use Glif endpoint
opts := []clientV1.NewClientOption{clientV1.NewClientChain(chain)}
if chain.ID == 3141 {
opts = append(opts, clientV1.NewClientAnkrAPIKey(chainCfg.AnkrAPIKey))
if chain.ID == 314159 {
// Glif API key is empty string because currently we are using the free tier (public node)
opts = append(opts, clientV1.NewClientGlifAPIKey(chainCfg.GlifAPIKey))
} else {
opts = append(opts, clientV1.NewClientAlchemyAPIKey(chainCfg.AlchemyAPIKey))
}
Expand Down
2 changes: 1 addition & 1 deletion docker/deployed/mainnet/api/.env_validator.example
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,6 @@ VALIDATOR_ALCHEMY_ARBITRUM_MAINNET_API_KEY=
VALIDATOR_ALCHEMY_ETHEREUM_MAINNET_API_KEY=
VALIDATOR_ALCHEMY_POLYGON_MAINNET_API_KEY=
VALIDATOR_ALCHEMY_OPTIMISM_MAINNET_API_KEY=
VALIDATOR_ANKR_FILECOIN_MAINNET_API_KEY=
VALIDATOR_GLIF_FILECOIN_MAINNET_API_KEY=
VALIDATOR_QUICKNODE_ARBITRUM_NOVA_MAINNET_API_KEY=
METRICS_HUB_API_KEY=
8 changes: 5 additions & 3 deletions docker/deployed/mainnet/api/config.json
Original file line number Diff line number Diff line change
Expand Up @@ -156,8 +156,9 @@
"Name": "Filecoin Mainnet",
"ChainID": 314,
"Registry": {
"EthEndpoint": "https://rpc.ankr.com/filecoin/${VALIDATOR_ANKR_FILECOIN_MAINNET_API_KEY}",
"ContractAddress": "0x59EF8Bf2d6c102B4c42AEf9189e1a9F0ABfD652d"
"EthEndpoint": "https://node.glif.io/fvm-archive/lotus/rpc/v1",
"ContractAddress": "0x59EF8Bf2d6c102B4c42AEf9189e1a9F0ABfD652d",
"ProviderAuthToken": "${VALIDATOR_GLIF_FILECOIN_MAINNET_API_KEY}"
},
"EventFeed": {
"ChainAPIBackoff": "15s",
Expand All @@ -167,7 +168,8 @@
},
"EventProcessor": {
"BlockFailedExecutionBackoff": "10s",
"DedupExecutedTxns": true
"DedupExecutedTxns": true,
"WebhookURL": "https://discord.com/api/webhooks/${VALIDATOR_DISCORD_WEBHOOK_ID}/${VALIDATOR_DISCORD_WEBHOOK_TOKEN}"
},
"HashCalculationStep": 60
}
Expand Down
2 changes: 1 addition & 1 deletion docker/deployed/testnet/api/.env_validator.example
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
VALIDATOR_ALCHEMY_ETHEREUM_SEPOLIA_API_KEY=
VALIDATOR_ANKR_FILECOIN_HYPERSPACE_API_KEY=
VALIDATOR_GLIF_FILECOIN_CALIBRATION_API_KEY=
VALIDATOR_ALCHEMY_POLYGON_MUMBAI_API_KEY=
VALIDATOR_ALCHEMY_ETHEREUM_GOERLI_API_KEY=
VALIDATOR_ALCHEMY_ARBITRUM_GOERLI_API_KEY=
Expand Down
10 changes: 5 additions & 5 deletions docker/deployed/testnet/api/config.json
Original file line number Diff line number Diff line change
Expand Up @@ -129,11 +129,11 @@
"HashCalculationStep": 1800
},
{
"Name": "Filecoin Hyperspace",
"ChainID": 3141,
"Name": "Filecoin Calibration",
"ChainID": 314159,
"Registry": {
"EthEndpoint": "https://rpc.ankr.com/filecoin_testnet/${VALIDATOR_ANKR_FILECOIN_HYPERSPACE_API_KEY}",
"ContractAddress": "0x0B9737ab4B3e5303CB67dB031b509697e31c02d3"
"EthEndpoint": "https://api.calibration.node.glif.io/rpc/v1",
"ContractAddress": "0x030BCf3D50cad04c2e57391B12740982A9308621"
},
"EventFeed": {
"ChainAPIBackoff": "15s",
Expand All @@ -148,4 +148,4 @@
"HashCalculationStep": 60
}
]
}
}
10 changes: 5 additions & 5 deletions docker/deployed/testnet/healthbot/config.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,14 +32,14 @@
}
},
{
"ChainID": 3141,
"WalletPrivateKey": "${HEALTHBOT_FILECOIN_HYPERSPACE_PRIVATE_KEY}",
"AnkrAPIKey": "${HEALTHBOT_ANKR_FILECOIN_HYPERSPACE_API_KEY}",
"ChainID": 314159,
"WalletPrivateKey": "${HEALTHBOT_FILECOIN_CALIBRATION_PRIVATE_KEY}",
"GlifAPIKey": "${HEALTHBOT_GLIF_FILECOIN_CALIBRATION_API_KEY}",
"Probe": {
"CheckInterval": "5m",
"ReceiptTimeout": "300s",
"Tablename": "${HEALTHBOT_FILECOIN_HYPERSPACE_TABLE}"
"Tablename": "${HEALTHBOT_FILECOIN_CALIBRATION_TABLE}"
}
}
]
}
}
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ require (
github.com/sethvargo/go-limiter v0.7.2
github.com/spf13/cobra v1.7.0
github.com/stretchr/testify v1.8.2
github.com/tablelandnetwork/sqlparser v0.0.0-20230518143735-838d223866f6
github.com/tablelandnetwork/sqlparser v0.0.0-20230605164749-c0e6862c37f6
github.com/textileio/cli v1.0.2
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.37.0
go.opentelemetry.io/otel v1.14.0
Expand Down
6 changes: 6 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -1299,6 +1299,12 @@ github.com/tablelandnetwork/sqlparser v0.0.0-20230517143402-3ab9022be0df h1:SUG4
github.com/tablelandnetwork/sqlparser v0.0.0-20230517143402-3ab9022be0df/go.mod h1:S+M/v3Q8X+236kQxMQziFcLId2Cscb1LzW06IUVhljE=
github.com/tablelandnetwork/sqlparser v0.0.0-20230518143735-838d223866f6 h1:f8TRklEZmT4fJd7wE+oktjf4wQndJ5BqkwXOpuHrYBU=
github.com/tablelandnetwork/sqlparser v0.0.0-20230518143735-838d223866f6/go.mod h1:S+M/v3Q8X+236kQxMQziFcLId2Cscb1LzW06IUVhljE=
github.com/tablelandnetwork/sqlparser v0.0.0-20230602174101-e27f9a12da58 h1:vEdQ9rJs5vwJfrwg4HIpVVrXRVJqEzyA2MM9oUehnhc=
github.com/tablelandnetwork/sqlparser v0.0.0-20230602174101-e27f9a12da58/go.mod h1:S+M/v3Q8X+236kQxMQziFcLId2Cscb1LzW06IUVhljE=
github.com/tablelandnetwork/sqlparser v0.0.0-20230605150512-1cb695cd5627 h1:ctGSX+KFDNvMYX25ooerc3saOcfPF6i56oAe+mo1l20=
github.com/tablelandnetwork/sqlparser v0.0.0-20230605150512-1cb695cd5627/go.mod h1:S+M/v3Q8X+236kQxMQziFcLId2Cscb1LzW06IUVhljE=
github.com/tablelandnetwork/sqlparser v0.0.0-20230605164749-c0e6862c37f6 h1:goeC/kQXlqRod2rPwqrVxvEgF3I5S3f0fa538k+Evbw=
github.com/tablelandnetwork/sqlparser v0.0.0-20230605164749-c0e6862c37f6/go.mod h1:S+M/v3Q8X+236kQxMQziFcLId2Cscb1LzW06IUVhljE=
github.com/tchap/go-patricia v2.2.6+incompatible/go.mod h1:bmLyhP68RS6kStMGxByiQ23RP/odRBOTVjwp2cDyi6I=
github.com/textileio/cli v1.0.2 h1:qSp/x4d/9SZ93TxhgZnE5okRKqzqHqrzAwKAPjuPw50=
github.com/textileio/cli v1.0.2/go.mod h1:vTlCvvVyOmXXLwddCcBg3PDavfUsCkRBZoyr6Nu1lkc=
Expand Down
6 changes: 1 addition & 5 deletions internal/router/controllers/controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -282,11 +282,7 @@ func (c *Controller) runReadRequest(
_ = json.NewEncoder(rw).Encode(errors.ServiceError{Message: err.Error()})
return nil, false
}
if len(res.Rows) == 0 {
rw.WriteHeader(http.StatusNotFound)
_ = json.NewEncoder(rw).Encode(errors.ServiceError{Message: "Row not found"})
return nil, false
}

return res, true
}

Expand Down
40 changes: 40 additions & 0 deletions internal/router/controllers/controller_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,46 @@ func TestQuery(t *testing.T) {
}
}

func TestQueryEmptyTable(t *testing.T) {
r := mocks.NewGateway(t)
r.EXPECT().RunReadQuery(mock.Anything, mock.AnythingOfType("string")).Return(
&gateway.TableData{
Columns: []gateway.Column{
{Name: "id"},
{Name: "name"},
},
Rows: [][]*gateway.ColumnValue{},
},
nil,
)

ctrl := NewController(r)

router := mux.NewRouter()
router.HandleFunc("/query", ctrl.GetTableQuery)

ctx := context.WithValue(context.Background(), middlewares.ContextIPAddress, strconv.Itoa(1))
// Table format
req, err := http.NewRequestWithContext(ctx, "GET", "/query?statement=select%20*%20from%20foo%3B&format=table", nil)
require.NoError(t, err)
rr := httptest.NewRecorder()
router.ServeHTTP(rr, req)
require.Equal(t, http.StatusOK, rr.Code)
exp := `{"columns":[{"name":"id"},{"name":"name"}],"rows":[]}` // nolint
require.JSONEq(t, exp, rr.Body.String())

// Unwrapped object format
req, err = http.NewRequest("GET", "/query?statement=select%20*%20from%20foo%3B&format=objects&unwrap=true", nil)
require.NoError(t, err)
rr = httptest.NewRecorder()
router.ServeHTTP(rr, req)
require.Equal(t, http.StatusOK, rr.Code)
exp = ""
wantString := parseJSONLString(exp)
gotString := parseJSONLString(rr.Body.String())
require.Equal(t, wantString, gotString)
}

func TestQueryExtracted(t *testing.T) {
r := mocks.NewGateway(t)
r.EXPECT().RunReadQuery(mock.Anything, mock.AnythingOfType("string")).Return(
Expand Down
69 changes: 37 additions & 32 deletions pkg/client/chains.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,33 +15,33 @@ type ChainID int64

// ChainIDs is all chain ids supported by Tableland.
var ChainIDs = struct {
Ethereum ChainID
Optimism ChainID
Polygon ChainID
Arbitrum ChainID
ArbitrumNova ChainID
Filecoin ChainID
EthereumGoerli ChainID
EthereumSepolia ChainID
OptimismGoerli ChainID
ArbitrumGoerli ChainID
FilecoinHyperspace ChainID
PolygonMumbai ChainID
Local ChainID
Ethereum ChainID
Optimism ChainID
Polygon ChainID
Arbitrum ChainID
ArbitrumNova ChainID
Filecoin ChainID
EthereumGoerli ChainID
EthereumSepolia ChainID
OptimismGoerli ChainID
ArbitrumGoerli ChainID
FilecoinCalibration ChainID
PolygonMumbai ChainID
Local ChainID
}{
Ethereum: 1,
Optimism: 10,
Polygon: 137,
Arbitrum: 42161,
ArbitrumNova: 42170,
Filecoin: 314,
EthereumGoerli: 5,
EthereumSepolia: 11155111,
OptimismGoerli: 420,
ArbitrumGoerli: 421613,
FilecoinHyperspace: 3141,
PolygonMumbai: 80001,
Local: 31337,
Ethereum: 1,
Optimism: 10,
Polygon: 137,
Arbitrum: 42161,
ArbitrumNova: 42170,
Filecoin: 314,
EthereumGoerli: 5,
EthereumSepolia: 11155111,
OptimismGoerli: 420,
ArbitrumGoerli: 421613,
FilecoinCalibration: 314159,
PolygonMumbai: 80001,
Local: 31337,
}

// Chain is a info about a network supported by Talbleland.
Expand Down Expand Up @@ -114,11 +114,11 @@ var Chains = map[ChainID]Chain{
Name: "Arbitrum Goerli",
ContractAddr: common.HexToAddress("0x033f69e8d119205089Ab15D340F5b797732f646b"),
},
ChainIDs.FilecoinHyperspace: {
ChainIDs.FilecoinCalibration: {
Endpoint: testnetURL,
ID: ChainIDs.FilecoinHyperspace,
Name: "Filecoin Hyperspace",
ContractAddr: common.HexToAddress("0x0B9737ab4B3e5303CB67dB031b509697e31c02d3"),
ID: ChainIDs.FilecoinCalibration,
Name: "Filecoin Calibration",
ContractAddr: common.HexToAddress("0x030BCf3D50cad04c2e57391B12740982A9308621"),
},
ChainIDs.PolygonMumbai: {
Endpoint: testnetURL,
Expand Down Expand Up @@ -171,6 +171,11 @@ var LocalURLs = map[ChainID]string{

// AnkrURLs contains the URLs for supported chains on Ankr.
var AnkrURLs = map[ChainID]string{
ChainIDs.FilecoinHyperspace: "https://rpc.ankr.com/filecoin_testnet/%s",
ChainIDs.Filecoin: "https://rpc.ankr.com/filecoin/%s",
ChainIDs.Filecoin: "https://rpc.ankr.com/filecoin/%s",
}

// GlifURLs contains the URLs for supported chains on Glif.
var GlifURLs = map[ChainID]string{
ChainIDs.FilecoinCalibration: "https://api.calibration.node.glif.io/rpc/v1%s",
ChainIDs.Filecoin: "https://api.node.glif.io/rpc/v1%s",
}
Loading

0 comments on commit 30a70c5

Please sign in to comment.