From 42e9b908ccaaccd0678f9c0ceb2f199e080dbcef Mon Sep 17 00:00:00 2001 From: Anjan Roy Date: Sun, 24 Jan 2021 11:17:48 +0530 Subject: [PATCH 1/7] attempting to pass router context to graphql handler context --- app/rest/graph/data.go | 20 ++++++++++++++++++++ app/rest/rest.go | 38 ++++++++++++++++++++++++-------------- 2 files changed, 44 insertions(+), 14 deletions(-) diff --git a/app/rest/graph/data.go b/app/rest/graph/data.go index b882ef7f..d84b0853 100644 --- a/app/rest/graph/data.go +++ b/app/rest/graph/data.go @@ -1,6 +1,7 @@ package graph import ( + "context" "encoding/hex" "errors" "fmt" @@ -8,6 +9,7 @@ import ( "strings" "github.com/ethereum/go-ethereum/common" + "github.com/gin-gonic/gin" "github.com/itzmeanjan/ette/app/data" "github.com/itzmeanjan/ette/app/rest/graph/model" "github.com/lib/pq" @@ -22,6 +24,24 @@ func GetDatabaseConnection(conn *gorm.DB) { db = conn } +// Attempting to recover router context i.e. which holds client `APIKey` in request header, +// in graphql handler context, so that we can do some accounting job +func ginContextFromContext(ctx context.Context) (*gin.Context, error) { + + ginContext := ctx.Value("RouterContextInGraphQL") + if ginContext == nil { + return nil, errors.New("Failed to retrieve router context") + } + + gc, ok := ginContext.(*gin.Context) + if !ok { + return nil, errors.New("Type assert of router context failed") + } + + return gc, nil + +} + // Converting block data to graphQL compatible data structure func getGraphQLCompatibleBlock(block *data.Block) (*model.Block, error) { if block == nil { diff --git a/app/rest/rest.go b/app/rest/rest.go index ebc6a87e..0f6ed732 100644 --- a/app/rest/rest.go +++ b/app/rest/rest.go @@ -1305,22 +1305,32 @@ func RunHTTPServer(_db *gorm.DB, _status *d.StatusHolder, _redisClient *redis.Cl } }) - router.POST("/v1/graphql", validateAPIKey, func(c *gin.Context) { - - gql := handler.NewDefaultServer(generated.NewExecutableSchema(generated.Config{ - Resolvers: &graph.Resolver{}, - })) - - if gql == nil { - c.JSON(http.StatusInternalServerError, gin.H{ - "msg": "Failed to handle graphQL query", - }) - return - } + router.POST("/v1/graphql", validateAPIKey, + // Attempting to pass router context, which holds `APIKey` + // to graphql handler, so that some accounting job can + // be done, before delivering requested piece of data to client + func(c *gin.Context) { + ctx := context.WithValue(c.Request.Context(), "RouterContextInGraphQL", c) + c.Request = c.Request.WithContext(ctx) + c.Next() + }, + + func(c *gin.Context) { + + gql := handler.NewDefaultServer(generated.NewExecutableSchema(generated.Config{ + Resolvers: &graph.Resolver{}, + })) + + if gql == nil { + c.JSON(http.StatusInternalServerError, gin.H{ + "msg": "Failed to handle graphQL query", + }) + return + } - gql.ServeHTTP(c.Writer, c.Request) + gql.ServeHTTP(c.Writer, c.Request) - }) + }) router.GET("/v1/graphql-playground", func(c *gin.Context) { From 13c33bbbb33cc58f6b8011af1eaf5faafe3a37d3 Mon Sep 17 00:00:00 2001 From: Anjan Roy Date: Sun, 24 Jan 2021 11:23:18 +0530 Subject: [PATCH 2/7] passing context to all handler functions --- app/rest/graph/data.go | 18 +++++------ app/rest/graph/schema.resolvers.go | 50 +++++++++++++++--------------- 2 files changed, 34 insertions(+), 34 deletions(-) diff --git a/app/rest/graph/data.go b/app/rest/graph/data.go index d84b0853..677bb6ab 100644 --- a/app/rest/graph/data.go +++ b/app/rest/graph/data.go @@ -43,7 +43,7 @@ func ginContextFromContext(ctx context.Context) (*gin.Context, error) { } // Converting block data to graphQL compatible data structure -func getGraphQLCompatibleBlock(block *data.Block) (*model.Block, error) { +func getGraphQLCompatibleBlock(ctx context.Context, block *data.Block) (*model.Block, error) { if block == nil { return nil, errors.New("Found nothing") } @@ -65,7 +65,7 @@ func getGraphQLCompatibleBlock(block *data.Block) (*model.Block, error) { } // Converting block array to graphQL compatible data structure -func getGraphQLCompatibleBlocks(blocks *data.Blocks) ([]*model.Block, error) { +func getGraphQLCompatibleBlocks(ctx context.Context, blocks *data.Blocks) ([]*model.Block, error) { if blocks == nil { return nil, errors.New("Found nothing") } @@ -77,7 +77,7 @@ func getGraphQLCompatibleBlocks(blocks *data.Blocks) ([]*model.Block, error) { _blocks := make([]*model.Block, len(blocks.Blocks)) for k, v := range blocks.Blocks { - _v, _ := getGraphQLCompatibleBlock(v) + _v, _ := getGraphQLCompatibleBlock(ctx, v) _blocks[k] = _v } @@ -85,7 +85,7 @@ func getGraphQLCompatibleBlocks(blocks *data.Blocks) ([]*model.Block, error) { } // Converting transaction data to graphQL compatible data structure -func getGraphQLCompatibleTransaction(tx *data.Transaction) (*model.Transaction, error) { +func getGraphQLCompatibleTransaction(ctx context.Context, tx *data.Transaction) (*model.Transaction, error) { if tx == nil { return nil, errors.New("Found nothing") } @@ -129,7 +129,7 @@ func getGraphQLCompatibleTransaction(tx *data.Transaction) (*model.Transaction, } // Converting transaction array to graphQL compatible data structure -func getGraphQLCompatibleTransactions(tx *data.Transactions) ([]*model.Transaction, error) { +func getGraphQLCompatibleTransactions(ctx context.Context, tx *data.Transactions) ([]*model.Transaction, error) { if tx == nil { return nil, errors.New("Found nothing") } @@ -141,7 +141,7 @@ func getGraphQLCompatibleTransactions(tx *data.Transactions) ([]*model.Transacti _tx := make([]*model.Transaction, len(tx.Transactions)) for k, v := range tx.Transactions { - _v, _ := getGraphQLCompatibleTransaction(v) + _v, _ := getGraphQLCompatibleTransaction(ctx, v) _tx[k] = _v } @@ -149,7 +149,7 @@ func getGraphQLCompatibleTransactions(tx *data.Transactions) ([]*model.Transacti } // Converting event data to graphQL compatible data structure -func getGraphQLCompatibleEvent(event *data.Event) (*model.Event, error) { +func getGraphQLCompatibleEvent(ctx context.Context, event *data.Event) (*model.Event, error) { if event == nil { return nil, errors.New("Found nothing") } @@ -170,7 +170,7 @@ func getGraphQLCompatibleEvent(event *data.Event) (*model.Event, error) { } // Converting event array to graphQL compatible data structure -func getGraphQLCompatibleEvents(events *data.Events) ([]*model.Event, error) { +func getGraphQLCompatibleEvents(ctx context.Context, events *data.Events) ([]*model.Event, error) { if events == nil { return nil, errors.New("Found nothing") } @@ -182,7 +182,7 @@ func getGraphQLCompatibleEvents(events *data.Events) ([]*model.Event, error) { _events := make([]*model.Event, len(events.Events)) for k, v := range events.Events { - _v, _ := getGraphQLCompatibleEvent(v) + _v, _ := getGraphQLCompatibleEvent(ctx, v) _events[k] = _v } diff --git a/app/rest/graph/schema.resolvers.go b/app/rest/graph/schema.resolvers.go index 0d174099..f33f7b9e 100644 --- a/app/rest/graph/schema.resolvers.go +++ b/app/rest/graph/schema.resolvers.go @@ -21,7 +21,7 @@ func (r *queryResolver) BlockByHash(ctx context.Context, hash string) (*model.Bl return nil, errors.New("Bad Block Hash") } - return getGraphQLCompatibleBlock(_db.GetBlockByHash(db, common.HexToHash(hash))) + return getGraphQLCompatibleBlock(ctx, _db.GetBlockByHash(db, common.HexToHash(hash))) } func (r *queryResolver) BlockByNumber(ctx context.Context, number string) (*model.Block, error) { @@ -30,7 +30,7 @@ func (r *queryResolver) BlockByNumber(ctx context.Context, number string) (*mode return nil, errors.New("Bad Block Number") } - return getGraphQLCompatibleBlock(_db.GetBlockByNumber(db, _number)) + return getGraphQLCompatibleBlock(ctx, _db.GetBlockByNumber(db, _number)) } func (r *queryResolver) BlocksByNumberRange(ctx context.Context, from string, to string) ([]*model.Block, error) { @@ -39,7 +39,7 @@ func (r *queryResolver) BlocksByNumberRange(ctx context.Context, from string, to return nil, errors.New("Bad Block Number Range") } - return getGraphQLCompatibleBlocks(_db.GetBlocksByNumberRange(db, _from, _to)) + return getGraphQLCompatibleBlocks(ctx, _db.GetBlocksByNumberRange(db, _from, _to)) } func (r *queryResolver) BlocksByTimeRange(ctx context.Context, from string, to string) ([]*model.Block, error) { @@ -48,7 +48,7 @@ func (r *queryResolver) BlocksByTimeRange(ctx context.Context, from string, to s return nil, errors.New("Bad Block Timestamp Range") } - return getGraphQLCompatibleBlocks(_db.GetBlocksByTimeRange(db, _from, _to)) + return getGraphQLCompatibleBlocks(ctx, _db.GetBlocksByTimeRange(db, _from, _to)) } func (r *queryResolver) TransactionsByBlockHash(ctx context.Context, hash string) ([]*model.Transaction, error) { @@ -56,7 +56,7 @@ func (r *queryResolver) TransactionsByBlockHash(ctx context.Context, hash string return nil, errors.New("Bad Block Hash") } - return getGraphQLCompatibleTransactions(_db.GetTransactionsByBlockHash(db, common.HexToHash(hash))) + return getGraphQLCompatibleTransactions(ctx, _db.GetTransactionsByBlockHash(db, common.HexToHash(hash))) } func (r *queryResolver) TransactionsByBlockNumber(ctx context.Context, number string) ([]*model.Transaction, error) { @@ -65,7 +65,7 @@ func (r *queryResolver) TransactionsByBlockNumber(ctx context.Context, number st return nil, errors.New("Bad Block Number") } - return getGraphQLCompatibleTransactions(_db.GetTransactionsByBlockNumber(db, _number)) + return getGraphQLCompatibleTransactions(ctx, _db.GetTransactionsByBlockNumber(db, _number)) } func (r *queryResolver) Transaction(ctx context.Context, hash string) (*model.Transaction, error) { @@ -73,7 +73,7 @@ func (r *queryResolver) Transaction(ctx context.Context, hash string) (*model.Tr return nil, errors.New("Bad Transaction Hash") } - return getGraphQLCompatibleTransaction(_db.GetTransactionByHash(db, common.HexToHash(hash))) + return getGraphQLCompatibleTransaction(ctx, _db.GetTransactionByHash(db, common.HexToHash(hash))) } func (r *queryResolver) TransactionsFromAccountByNumberRange(ctx context.Context, account string, from string, to string) ([]*model.Transaction, error) { @@ -86,7 +86,7 @@ func (r *queryResolver) TransactionsFromAccountByNumberRange(ctx context.Context return nil, errors.New("Bad Block Number Range") } - return getGraphQLCompatibleTransactions(_db.GetTransactionsFromAccountByBlockNumberRange(db, common.HexToAddress(account), _from, _to)) + return getGraphQLCompatibleTransactions(ctx, _db.GetTransactionsFromAccountByBlockNumberRange(db, common.HexToAddress(account), _from, _to)) } func (r *queryResolver) TransactionsFromAccountByTimeRange(ctx context.Context, account string, from string, to string) ([]*model.Transaction, error) { @@ -99,7 +99,7 @@ func (r *queryResolver) TransactionsFromAccountByTimeRange(ctx context.Context, return nil, errors.New("Bad Block Timestamp Range") } - return getGraphQLCompatibleTransactions(_db.GetTransactionsFromAccountByBlockTimeRange(db, common.HexToAddress(account), _from, _to)) + return getGraphQLCompatibleTransactions(ctx, _db.GetTransactionsFromAccountByBlockTimeRange(db, common.HexToAddress(account), _from, _to)) } func (r *queryResolver) TransactionsToAccountByNumberRange(ctx context.Context, account string, from string, to string) ([]*model.Transaction, error) { @@ -112,7 +112,7 @@ func (r *queryResolver) TransactionsToAccountByNumberRange(ctx context.Context, return nil, errors.New("Bad Block Number Range") } - return getGraphQLCompatibleTransactions(_db.GetTransactionsToAccountByBlockNumberRange(db, common.HexToAddress(account), _from, _to)) + return getGraphQLCompatibleTransactions(ctx, _db.GetTransactionsToAccountByBlockNumberRange(db, common.HexToAddress(account), _from, _to)) } func (r *queryResolver) TransactionsToAccountByTimeRange(ctx context.Context, account string, from string, to string) ([]*model.Transaction, error) { @@ -125,7 +125,7 @@ func (r *queryResolver) TransactionsToAccountByTimeRange(ctx context.Context, ac return nil, errors.New("Bad Block Timestamp Range") } - return getGraphQLCompatibleTransactions(_db.GetTransactionsToAccountByBlockTimeRange(db, common.HexToAddress(account), _from, _to)) + return getGraphQLCompatibleTransactions(ctx, _db.GetTransactionsToAccountByBlockTimeRange(db, common.HexToAddress(account), _from, _to)) } func (r *queryResolver) TransactionsBetweenAccountsByNumberRange(ctx context.Context, fromAccount string, toAccount string, from string, to string) ([]*model.Transaction, error) { @@ -142,7 +142,7 @@ func (r *queryResolver) TransactionsBetweenAccountsByNumberRange(ctx context.Con return nil, errors.New("Bad Block Number Range") } - return getGraphQLCompatibleTransactions(_db.GetTransactionsBetweenAccountsByBlockNumberRange(db, common.HexToAddress(fromAccount), common.HexToAddress(toAccount), _from, _to)) + return getGraphQLCompatibleTransactions(ctx, _db.GetTransactionsBetweenAccountsByBlockNumberRange(db, common.HexToAddress(fromAccount), common.HexToAddress(toAccount), _from, _to)) } func (r *queryResolver) TransactionsBetweenAccountsByTimeRange(ctx context.Context, fromAccount string, toAccount string, from string, to string) ([]*model.Transaction, error) { @@ -159,7 +159,7 @@ func (r *queryResolver) TransactionsBetweenAccountsByTimeRange(ctx context.Conte return nil, errors.New("Bad Block Timestamp Range") } - return getGraphQLCompatibleTransactions(_db.GetTransactionsBetweenAccountsByBlockTimeRange(db, common.HexToAddress(fromAccount), common.HexToAddress(toAccount), _from, _to)) + return getGraphQLCompatibleTransactions(ctx, _db.GetTransactionsBetweenAccountsByBlockTimeRange(db, common.HexToAddress(fromAccount), common.HexToAddress(toAccount), _from, _to)) } func (r *queryResolver) ContractsCreatedFromAccountByNumberRange(ctx context.Context, account string, from string, to string) ([]*model.Transaction, error) { @@ -172,7 +172,7 @@ func (r *queryResolver) ContractsCreatedFromAccountByNumberRange(ctx context.Con return nil, errors.New("Bad Block Number Range") } - return getGraphQLCompatibleTransactions(_db.GetContractCreationTransactionsFromAccountByBlockNumberRange(db, common.HexToAddress(account), _from, _to)) + return getGraphQLCompatibleTransactions(ctx, _db.GetContractCreationTransactionsFromAccountByBlockNumberRange(db, common.HexToAddress(account), _from, _to)) } func (r *queryResolver) ContractsCreatedFromAccountByTimeRange(ctx context.Context, account string, from string, to string) ([]*model.Transaction, error) { @@ -185,7 +185,7 @@ func (r *queryResolver) ContractsCreatedFromAccountByTimeRange(ctx context.Conte return nil, errors.New("Bad Block Timestamp Range") } - return getGraphQLCompatibleTransactions(_db.GetContractCreationTransactionsFromAccountByBlockTimeRange(db, common.HexToAddress(account), _from, _to)) + return getGraphQLCompatibleTransactions(ctx, _db.GetContractCreationTransactionsFromAccountByBlockTimeRange(db, common.HexToAddress(account), _from, _to)) } func (r *queryResolver) TransactionFromAccountWithNonce(ctx context.Context, account string, nonce string) (*model.Transaction, error) { @@ -198,7 +198,7 @@ func (r *queryResolver) TransactionFromAccountWithNonce(ctx context.Context, acc return nil, errors.New("Bad Account Nonce") } - return getGraphQLCompatibleTransaction(_db.GetTransactionFromAccountWithNonce(db, common.HexToAddress(account), _nonce)) + return getGraphQLCompatibleTransaction(ctx, _db.GetTransactionFromAccountWithNonce(db, common.HexToAddress(account), _nonce)) } func (r *queryResolver) EventsFromContractByNumberRange(ctx context.Context, contract string, from string, to string) ([]*model.Event, error) { @@ -211,7 +211,7 @@ func (r *queryResolver) EventsFromContractByNumberRange(ctx context.Context, con return nil, errors.New("Bad Block Number Range") } - return getGraphQLCompatibleEvents(_db.GetEventsFromContractByBlockNumberRange(db, common.HexToAddress(contract), _from, _to)) + return getGraphQLCompatibleEvents(ctx, _db.GetEventsFromContractByBlockNumberRange(db, common.HexToAddress(contract), _from, _to)) } func (r *queryResolver) EventsFromContractByTimeRange(ctx context.Context, contract string, from string, to string) ([]*model.Event, error) { @@ -224,7 +224,7 @@ func (r *queryResolver) EventsFromContractByTimeRange(ctx context.Context, contr return nil, errors.New("Bad Block Timestamp Range") } - return getGraphQLCompatibleEvents(_db.GetEventsFromContractByBlockTimeRange(db, common.HexToAddress(contract), _from, _to)) + return getGraphQLCompatibleEvents(ctx, _db.GetEventsFromContractByBlockTimeRange(db, common.HexToAddress(contract), _from, _to)) } func (r *queryResolver) EventsByBlockHash(ctx context.Context, hash string) ([]*model.Event, error) { @@ -232,7 +232,7 @@ func (r *queryResolver) EventsByBlockHash(ctx context.Context, hash string) ([]* return nil, errors.New("Bad Block Hash") } - return getGraphQLCompatibleEvents(_db.GetEventsByBlockHash(db, common.HexToHash(hash))) + return getGraphQLCompatibleEvents(ctx, _db.GetEventsByBlockHash(db, common.HexToHash(hash))) } func (r *queryResolver) EventsByTxHash(ctx context.Context, hash string) ([]*model.Event, error) { @@ -240,7 +240,7 @@ func (r *queryResolver) EventsByTxHash(ctx context.Context, hash string) ([]*mod return nil, errors.New("Bad Transaction Hash") } - return getGraphQLCompatibleEvents(_db.GetEventsByTransactionHash(db, common.HexToHash(hash))) + return getGraphQLCompatibleEvents(ctx, _db.GetEventsByTransactionHash(db, common.HexToHash(hash))) } func (r *queryResolver) EventsFromContractWithTopicsByNumberRange(ctx context.Context, contract string, from string, to string, topics []string) ([]*model.Event, error) { @@ -253,7 +253,7 @@ func (r *queryResolver) EventsFromContractWithTopicsByNumberRange(ctx context.Co return nil, errors.New("Bad Block Number Range") } - return getGraphQLCompatibleEvents(_db.GetEventsFromContractWithTopicsByBlockNumberRange(db, common.HexToAddress(contract), _from, _to, getTopics(topics...)...)) + return getGraphQLCompatibleEvents(ctx, _db.GetEventsFromContractWithTopicsByBlockNumberRange(db, common.HexToAddress(contract), _from, _to, getTopics(topics...)...)) } func (r *queryResolver) EventsFromContractWithTopicsByTimeRange(ctx context.Context, contract string, from string, to string, topics []string) ([]*model.Event, error) { @@ -266,7 +266,7 @@ func (r *queryResolver) EventsFromContractWithTopicsByTimeRange(ctx context.Cont return nil, errors.New("Bad Block Timestamp Range") } - return getGraphQLCompatibleEvents(_db.GetEventsFromContractWithTopicsByBlockTimeRange(db, common.HexToAddress(contract), _from, _to, getTopics(topics...)...)) + return getGraphQLCompatibleEvents(ctx, _db.GetEventsFromContractWithTopicsByBlockTimeRange(db, common.HexToAddress(contract), _from, _to, getTopics(topics...)...)) } func (r *queryResolver) LastXEventsFromContract(ctx context.Context, contract string, x int) ([]*model.Event, error) { @@ -278,7 +278,7 @@ func (r *queryResolver) LastXEventsFromContract(ctx context.Context, contract st return nil, errors.New("Too Many Events Requested") } - return getGraphQLCompatibleEvents(_db.GetLastXEventsFromContract(db, common.HexToAddress(contract), x)) + return getGraphQLCompatibleEvents(ctx, _db.GetLastXEventsFromContract(db, common.HexToAddress(contract), x)) } func (r *queryResolver) EventByBlockHashAndLogIndex(ctx context.Context, hash string, index string) (*model.Event, error) { @@ -292,7 +292,7 @@ func (r *queryResolver) EventByBlockHashAndLogIndex(ctx context.Context, hash st return nil, errors.New("Bad Log Index") } - return getGraphQLCompatibleEvent(_db.GetEventByBlockHashAndLogIndex(db, common.HexToHash(hash), uint(_index))) + return getGraphQLCompatibleEvent(ctx, _db.GetEventByBlockHashAndLogIndex(db, common.HexToHash(hash), uint(_index))) } @@ -308,7 +308,7 @@ func (r *queryResolver) EventByBlockNumberAndLogIndex(ctx context.Context, numbe return nil, errors.New("Bad Log Index") } - return getGraphQLCompatibleEvent(_db.GetEventByBlockNumberAndLogIndex(db, _number, uint(_index))) + return getGraphQLCompatibleEvent(ctx, _db.GetEventByBlockNumberAndLogIndex(db, _number, uint(_index))) } From 0b6ac9e9819ef4663057c4892214551cea402770 Mon Sep 17 00:00:00 2001 From: Anjan Roy Date: Sun, 24 Jan 2021 11:28:20 +0530 Subject: [PATCH 3/7] attempts to get APIKey from recovered context --- app/rest/graph/data.go | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/app/rest/graph/data.go b/app/rest/graph/data.go index 677bb6ab..8853f942 100644 --- a/app/rest/graph/data.go +++ b/app/rest/graph/data.go @@ -26,7 +26,7 @@ func GetDatabaseConnection(conn *gorm.DB) { // Attempting to recover router context i.e. which holds client `APIKey` in request header, // in graphql handler context, so that we can do some accounting job -func ginContextFromContext(ctx context.Context) (*gin.Context, error) { +func routerContextFromGraphQLContext(ctx context.Context) (*gin.Context, error) { ginContext := ctx.Value("RouterContextInGraphQL") if ginContext == nil { @@ -42,6 +42,20 @@ func ginContextFromContext(ctx context.Context) (*gin.Context, error) { } +// Attempts to extract out `APIKey` used passed along +// with request, in graphql handler function, to be used for +// doing some book keeping work +func getAPIKey(ctx context.Context) string { + + routerCtx, err := routerContextFromGraphQLContext(ctx) + if err != nil { + return "" + } + + return routerCtx.GetHeader("APIKey") + +} + // Converting block data to graphQL compatible data structure func getGraphQLCompatibleBlock(ctx context.Context, block *data.Block) (*model.Block, error) { if block == nil { From ed19607a994e584dc18698c22e3f94df1b4d6a6f Mon Sep 17 00:00:00 2001 From: Anjan Roy Date: Sun, 24 Jan 2021 11:37:54 +0530 Subject: [PATCH 4/7] attempts to do book keeping regarding data delivery --- app/rest/graph/data.go | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/app/rest/graph/data.go b/app/rest/graph/data.go index 8853f942..28b2c9ec 100644 --- a/app/rest/graph/data.go +++ b/app/rest/graph/data.go @@ -5,12 +5,14 @@ import ( "encoding/hex" "errors" "fmt" + "log" "strconv" "strings" "github.com/ethereum/go-ethereum/common" "github.com/gin-gonic/gin" "github.com/itzmeanjan/ette/app/data" + _db "github.com/itzmeanjan/ette/app/db" "github.com/itzmeanjan/ette/app/rest/graph/model" "github.com/lib/pq" "gorm.io/gorm" @@ -49,13 +51,31 @@ func getAPIKey(ctx context.Context) string { routerCtx, err := routerContextFromGraphQLContext(ctx) if err != nil { + + log.Printf("[!] Failed to get `APIKey` : %s\n", err.Error()) return "" + } return routerCtx.GetHeader("APIKey") } +// Attempts to recover `APIKey` from router context, which is +// then used for looking up user, so that data delivery information can +// be persisted into DB +func doBookKeeping(ctx context.Context, _data []byte) error { + + user := _db.GetUserFromAPIKey(db, getAPIKey(ctx)) + if user == nil { + return errors.New("Failed to get user from `APIKey`") + } + + _db.PutDataDeliveryInfo(db, user.Address, "/v1/graphql", uint64(len(_data))) + return nil + +} + // Converting block data to graphQL compatible data structure func getGraphQLCompatibleBlock(ctx context.Context, block *data.Block) (*model.Block, error) { if block == nil { From 9db90e843cc7beb9121a4a8a407e98ab8c7340cd Mon Sep 17 00:00:00 2001 From: Anjan Roy Date: Sun, 24 Jan 2021 11:46:41 +0530 Subject: [PATCH 5/7] book keeping attached in block processor --- app/rest/graph/data.go | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/app/rest/graph/data.go b/app/rest/graph/data.go index 28b2c9ec..3195b538 100644 --- a/app/rest/graph/data.go +++ b/app/rest/graph/data.go @@ -3,6 +3,7 @@ package graph import ( "context" "encoding/hex" + "encoding/json" "errors" "fmt" "log" @@ -78,11 +79,12 @@ func doBookKeeping(ctx context.Context, _data []byte) error { // Converting block data to graphQL compatible data structure func getGraphQLCompatibleBlock(ctx context.Context, block *data.Block) (*model.Block, error) { + if block == nil { return nil, errors.New("Found nothing") } - return &model.Block{ + _block := &model.Block{ Hash: block.Hash, Number: fmt.Sprintf("%d", block.Number), Time: fmt.Sprintf("%d", block.Time), @@ -95,7 +97,21 @@ func getGraphQLCompatibleBlock(ctx context.Context, block *data.Block) (*model.B Size: block.Size, TxRootHash: block.TransactionRootHash, ReceiptRootHash: block.ReceiptRootHash, - }, nil + } + + // marshalling to JSON, so that length of data can be + // computed in bytes, to used for book keeping purposes + _data, err := json.Marshal(_block) + if err != nil { + return nil, errors.New("JSON marshalling failed") + } + + if err := doBookKeeping(ctx, _data); err != nil { + return nil, errors.New("Book keeping failed") + } + + return _block, nil + } // Converting block array to graphQL compatible data structure From 305a74aefee60b7e8db90b30555ab87037a3e978 Mon Sep 17 00:00:00 2001 From: Anjan Roy Date: Sun, 24 Jan 2021 12:00:20 +0530 Subject: [PATCH 6/7] book keeping being done from all graphql handler functions --- app/rest/graph/data.go | 76 ++++++++++++++++++++++++++++-------------- 1 file changed, 51 insertions(+), 25 deletions(-) diff --git a/app/rest/graph/data.go b/app/rest/graph/data.go index 3195b538..2331eaf6 100644 --- a/app/rest/graph/data.go +++ b/app/rest/graph/data.go @@ -3,7 +3,6 @@ package graph import ( "context" "encoding/hex" - "encoding/json" "errors" "fmt" "log" @@ -67,6 +66,10 @@ func getAPIKey(ctx context.Context) string { // be persisted into DB func doBookKeeping(ctx context.Context, _data []byte) error { + if _data == nil { + return errors.New("JSON marshalling failed") + } + user := _db.GetUserFromAPIKey(db, getAPIKey(ctx)) if user == nil { return errors.New("Failed to get user from `APIKey`") @@ -78,13 +81,21 @@ func doBookKeeping(ctx context.Context, _data []byte) error { } // Converting block data to graphQL compatible data structure -func getGraphQLCompatibleBlock(ctx context.Context, block *data.Block) (*model.Block, error) { +func getGraphQLCompatibleBlock(ctx context.Context, block *data.Block, bookKeeping bool) (*model.Block, error) { if block == nil { return nil, errors.New("Found nothing") } - _block := &model.Block{ + // to be `false` when calling from `getGraphQLCompatibleBlocks(...)` + // because that function will then take care of it's own book keeping logic + if bookKeeping { + if err := doBookKeeping(ctx, block.ToJSON()); err != nil { + return nil, errors.New("Book keeping failed") + } + } + + return &model.Block{ Hash: block.Hash, Number: fmt.Sprintf("%d", block.Number), Time: fmt.Sprintf("%d", block.Time), @@ -97,25 +108,12 @@ func getGraphQLCompatibleBlock(ctx context.Context, block *data.Block) (*model.B Size: block.Size, TxRootHash: block.TransactionRootHash, ReceiptRootHash: block.ReceiptRootHash, - } - - // marshalling to JSON, so that length of data can be - // computed in bytes, to used for book keeping purposes - _data, err := json.Marshal(_block) - if err != nil { - return nil, errors.New("JSON marshalling failed") - } - - if err := doBookKeeping(ctx, _data); err != nil { - return nil, errors.New("Book keeping failed") - } - - return _block, nil + }, nil } // Converting block array to graphQL compatible data structure -func getGraphQLCompatibleBlocks(ctx context.Context, blocks *data.Blocks) ([]*model.Block, error) { +func getGraphQLCompatibleBlocks(ctx context.Context, blocks *data.Blocks, bookKeeping bool) ([]*model.Block, error) { if blocks == nil { return nil, errors.New("Found nothing") } @@ -124,10 +122,14 @@ func getGraphQLCompatibleBlocks(ctx context.Context, blocks *data.Blocks) ([]*mo return nil, errors.New("Found nothing") } + if err := doBookKeeping(ctx, blocks.ToJSON()); err != nil { + return nil, errors.New("Book keeping failed") + } + _blocks := make([]*model.Block, len(blocks.Blocks)) for k, v := range blocks.Blocks { - _v, _ := getGraphQLCompatibleBlock(ctx, v) + _v, _ := getGraphQLCompatibleBlock(ctx, v, false) _blocks[k] = _v } @@ -135,7 +137,7 @@ func getGraphQLCompatibleBlocks(ctx context.Context, blocks *data.Blocks) ([]*mo } // Converting transaction data to graphQL compatible data structure -func getGraphQLCompatibleTransaction(ctx context.Context, tx *data.Transaction) (*model.Transaction, error) { +func getGraphQLCompatibleTransaction(ctx context.Context, tx *data.Transaction, bookKeeping bool) (*model.Transaction, error) { if tx == nil { return nil, errors.New("Found nothing") } @@ -145,6 +147,14 @@ func getGraphQLCompatibleTransaction(ctx context.Context, tx *data.Transaction) data = fmt.Sprintf("0x%s", _h) } + // to be `false` when calling from `getGraphQLCompatibleTransactions(...)` + // because that function will then take care of it's own book keeping logic + if bookKeeping { + if err := doBookKeeping(ctx, tx.ToJSON()); err != nil { + return nil, errors.New("Book keeping failed") + } + } + if !strings.HasPrefix(tx.Contract, "0x") { return &model.Transaction{ Hash: tx.Hash, @@ -179,7 +189,7 @@ func getGraphQLCompatibleTransaction(ctx context.Context, tx *data.Transaction) } // Converting transaction array to graphQL compatible data structure -func getGraphQLCompatibleTransactions(ctx context.Context, tx *data.Transactions) ([]*model.Transaction, error) { +func getGraphQLCompatibleTransactions(ctx context.Context, tx *data.Transactions, bookKeeping bool) ([]*model.Transaction, error) { if tx == nil { return nil, errors.New("Found nothing") } @@ -188,10 +198,14 @@ func getGraphQLCompatibleTransactions(ctx context.Context, tx *data.Transactions return nil, errors.New("Found nothing") } + if err := doBookKeeping(ctx, tx.ToJSON()); err != nil { + return nil, errors.New("Book keeping failed") + } + _tx := make([]*model.Transaction, len(tx.Transactions)) for k, v := range tx.Transactions { - _v, _ := getGraphQLCompatibleTransaction(ctx, v) + _v, _ := getGraphQLCompatibleTransaction(ctx, v, false) _tx[k] = _v } @@ -199,7 +213,7 @@ func getGraphQLCompatibleTransactions(ctx context.Context, tx *data.Transactions } // Converting event data to graphQL compatible data structure -func getGraphQLCompatibleEvent(ctx context.Context, event *data.Event) (*model.Event, error) { +func getGraphQLCompatibleEvent(ctx context.Context, event *data.Event, bookKeeping bool) (*model.Event, error) { if event == nil { return nil, errors.New("Found nothing") } @@ -209,6 +223,14 @@ func getGraphQLCompatibleEvent(ctx context.Context, event *data.Event) (*model.E data = fmt.Sprintf("0x%s", _h) } + // to be `false` when calling from `getGraphQLCompatibleEvents(...)` + // because that function will then take care of it's own book keeping logic + if bookKeeping { + if err := doBookKeeping(ctx, event.ToJSON()); err != nil { + return nil, errors.New("Book keeping failed") + } + } + return &model.Event{ Origin: event.Origin, Index: fmt.Sprintf("%d", event.Index), @@ -220,7 +242,7 @@ func getGraphQLCompatibleEvent(ctx context.Context, event *data.Event) (*model.E } // Converting event array to graphQL compatible data structure -func getGraphQLCompatibleEvents(ctx context.Context, events *data.Events) ([]*model.Event, error) { +func getGraphQLCompatibleEvents(ctx context.Context, events *data.Events, bookKeeping bool) ([]*model.Event, error) { if events == nil { return nil, errors.New("Found nothing") } @@ -229,10 +251,14 @@ func getGraphQLCompatibleEvents(ctx context.Context, events *data.Events) ([]*mo return nil, errors.New("Found nothing") } + if err := doBookKeeping(ctx, events.ToJSON()); err != nil { + return nil, errors.New("Book keeping failed") + } + _events := make([]*model.Event, len(events.Events)) for k, v := range events.Events { - _v, _ := getGraphQLCompatibleEvent(ctx, v) + _v, _ := getGraphQLCompatibleEvent(ctx, v, false) _events[k] = _v } From ec88f3ddf94c291b80356b422e1738cd7ab804e1 Mon Sep 17 00:00:00 2001 From: Anjan Roy Date: Sun, 24 Jan 2021 12:03:55 +0530 Subject: [PATCH 7/7] function signature corrected --- app/rest/graph/data.go | 6 +++--- app/rest/graph/schema.resolvers.go | 12 ++++++------ 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/app/rest/graph/data.go b/app/rest/graph/data.go index 2331eaf6..16e55cbf 100644 --- a/app/rest/graph/data.go +++ b/app/rest/graph/data.go @@ -113,7 +113,7 @@ func getGraphQLCompatibleBlock(ctx context.Context, block *data.Block, bookKeepi } // Converting block array to graphQL compatible data structure -func getGraphQLCompatibleBlocks(ctx context.Context, blocks *data.Blocks, bookKeeping bool) ([]*model.Block, error) { +func getGraphQLCompatibleBlocks(ctx context.Context, blocks *data.Blocks) ([]*model.Block, error) { if blocks == nil { return nil, errors.New("Found nothing") } @@ -189,7 +189,7 @@ func getGraphQLCompatibleTransaction(ctx context.Context, tx *data.Transaction, } // Converting transaction array to graphQL compatible data structure -func getGraphQLCompatibleTransactions(ctx context.Context, tx *data.Transactions, bookKeeping bool) ([]*model.Transaction, error) { +func getGraphQLCompatibleTransactions(ctx context.Context, tx *data.Transactions) ([]*model.Transaction, error) { if tx == nil { return nil, errors.New("Found nothing") } @@ -242,7 +242,7 @@ func getGraphQLCompatibleEvent(ctx context.Context, event *data.Event, bookKeepi } // Converting event array to graphQL compatible data structure -func getGraphQLCompatibleEvents(ctx context.Context, events *data.Events, bookKeeping bool) ([]*model.Event, error) { +func getGraphQLCompatibleEvents(ctx context.Context, events *data.Events) ([]*model.Event, error) { if events == nil { return nil, errors.New("Found nothing") } diff --git a/app/rest/graph/schema.resolvers.go b/app/rest/graph/schema.resolvers.go index f33f7b9e..88382048 100644 --- a/app/rest/graph/schema.resolvers.go +++ b/app/rest/graph/schema.resolvers.go @@ -21,7 +21,7 @@ func (r *queryResolver) BlockByHash(ctx context.Context, hash string) (*model.Bl return nil, errors.New("Bad Block Hash") } - return getGraphQLCompatibleBlock(ctx, _db.GetBlockByHash(db, common.HexToHash(hash))) + return getGraphQLCompatibleBlock(ctx, _db.GetBlockByHash(db, common.HexToHash(hash)), true) } func (r *queryResolver) BlockByNumber(ctx context.Context, number string) (*model.Block, error) { @@ -30,7 +30,7 @@ func (r *queryResolver) BlockByNumber(ctx context.Context, number string) (*mode return nil, errors.New("Bad Block Number") } - return getGraphQLCompatibleBlock(ctx, _db.GetBlockByNumber(db, _number)) + return getGraphQLCompatibleBlock(ctx, _db.GetBlockByNumber(db, _number), true) } func (r *queryResolver) BlocksByNumberRange(ctx context.Context, from string, to string) ([]*model.Block, error) { @@ -73,7 +73,7 @@ func (r *queryResolver) Transaction(ctx context.Context, hash string) (*model.Tr return nil, errors.New("Bad Transaction Hash") } - return getGraphQLCompatibleTransaction(ctx, _db.GetTransactionByHash(db, common.HexToHash(hash))) + return getGraphQLCompatibleTransaction(ctx, _db.GetTransactionByHash(db, common.HexToHash(hash)), true) } func (r *queryResolver) TransactionsFromAccountByNumberRange(ctx context.Context, account string, from string, to string) ([]*model.Transaction, error) { @@ -198,7 +198,7 @@ func (r *queryResolver) TransactionFromAccountWithNonce(ctx context.Context, acc return nil, errors.New("Bad Account Nonce") } - return getGraphQLCompatibleTransaction(ctx, _db.GetTransactionFromAccountWithNonce(db, common.HexToAddress(account), _nonce)) + return getGraphQLCompatibleTransaction(ctx, _db.GetTransactionFromAccountWithNonce(db, common.HexToAddress(account), _nonce), true) } func (r *queryResolver) EventsFromContractByNumberRange(ctx context.Context, contract string, from string, to string) ([]*model.Event, error) { @@ -292,7 +292,7 @@ func (r *queryResolver) EventByBlockHashAndLogIndex(ctx context.Context, hash st return nil, errors.New("Bad Log Index") } - return getGraphQLCompatibleEvent(ctx, _db.GetEventByBlockHashAndLogIndex(db, common.HexToHash(hash), uint(_index))) + return getGraphQLCompatibleEvent(ctx, _db.GetEventByBlockHashAndLogIndex(db, common.HexToHash(hash), uint(_index)), true) } @@ -308,7 +308,7 @@ func (r *queryResolver) EventByBlockNumberAndLogIndex(ctx context.Context, numbe return nil, errors.New("Bad Log Index") } - return getGraphQLCompatibleEvent(ctx, _db.GetEventByBlockNumberAndLogIndex(db, _number, uint(_index))) + return getGraphQLCompatibleEvent(ctx, _db.GetEventByBlockNumberAndLogIndex(db, _number, uint(_index)), true) }