From e59d37e61d81a30e344d646e1726822b82fe0940 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Loeuillet?= Date: Tue, 7 Mar 2023 13:20:18 +0100 Subject: [PATCH] =?UTF-8?q?graphql:=20protect=20against=20nil=20pointer=20?= =?UTF-8?q?deref=20on=20cases=20like=20TX=20with=20nil=20=E2=80=A6=20(#704?= =?UTF-8?q?7)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit …To address (contract creation) --- cmd/rpcdaemon/graphql/graph/helpers.go | 5 + .../graphql/graph/schema.resolvers.go | 116 ++++++++++-------- 2 files changed, 71 insertions(+), 50 deletions(-) diff --git a/cmd/rpcdaemon/graphql/graph/helpers.go b/cmd/rpcdaemon/graphql/graph/helpers.go index 812a283b1..5d7b8cd9e 100644 --- a/cmd/rpcdaemon/graphql/graph/helpers.go +++ b/cmd/rpcdaemon/graphql/graph/helpers.go @@ -15,6 +15,10 @@ import ( func convertDataToStringP(abstractMap map[string]interface{}, field string) *string { var result string + if reflect.ValueOf(abstractMap[field]).IsZero() { + return nil + } + switch v := abstractMap[field].(type) { case int64: result = strconv.FormatInt(v, 10) @@ -44,6 +48,7 @@ func convertDataToStringP(abstractMap map[string]interface{}, field string) *str fmt.Println("unhandled/string", reflect.TypeOf(abstractMap[field]), field, abstractMap[field]) result = "unhandled" } + return &result } diff --git a/cmd/rpcdaemon/graphql/graph/schema.resolvers.go b/cmd/rpcdaemon/graphql/graph/schema.resolvers.go index 69022758e..061f27bc2 100644 --- a/cmd/rpcdaemon/graphql/graph/schema.resolvers.go +++ b/cmd/rpcdaemon/graphql/graph/schema.resolvers.go @@ -60,63 +60,79 @@ func (r *queryResolver) Block(ctx context.Context, number *string, hash *string) return nil, err } - absBlk := res["block"] - blk := absBlk.(map[string]interface{}) - block := &model.Block{} - block.Difficulty = *convertDataToStringP(blk, "difficulty") - block.ExtraData = *convertDataToStringP(blk, "extraData") - block.GasLimit = uint64(*convertDataToUint64P(blk, "gasLimit")) - block.GasUsed = *convertDataToUint64P(blk, "gasUsed") - block.Hash = *convertDataToStringP(blk, "hash") - block.Miner = &model.Account{} - block.Miner.Address = strings.ToLower(*convertDataToStringP(blk, "miner")) - block.MixHash = *convertDataToStringP(blk, "mixHash") - block.Nonce = *convertDataToStringP(blk, "nonce") - block.Number = *convertDataToUint64P(blk, "number") - block.Ommers = []*model.Block{} - block.Parent = &model.Block{} - block.Parent.Hash = *convertDataToStringP(blk, "parentHash") - block.ReceiptsRoot = *convertDataToStringP(blk, "receiptsRoot") - block.StateRoot = *convertDataToStringP(blk, "stateRoot") - block.Timestamp = *convertDataToUint64P(blk, "timestamp") // int in the schema but Geth displays in HEX !!! - block.TransactionCount = convertDataToIntP(blk, "transactionCount") - block.TransactionsRoot = *convertDataToStringP(blk, "transactionsRoot") - block.TotalDifficulty = *convertDataToStringP(blk, "totalDifficulty") - block.Transactions = []*model.Transaction{} + absBlk := res["block"] - block.LogsBloom = "0x" + *convertDataToStringP(blk, "logsBloom") - block.OmmerHash = "" // OmmerHash: gointerfaces.ConvertHashToH256(header.UncleHash), + if absBlk != nil { + blk := absBlk.(map[string]interface{}) - /* - Missing Block fields to fill : - - ommerHash - */ + block.Difficulty = *convertDataToStringP(blk, "difficulty") + block.ExtraData = *convertDataToStringP(blk, "extraData") + block.GasLimit = uint64(*convertDataToUint64P(blk, "gasLimit")) + block.GasUsed = *convertDataToUint64P(blk, "gasUsed") + block.Hash = *convertDataToStringP(blk, "hash") + block.Miner = &model.Account{} + address := convertDataToStringP(blk, "miner") + if address != nil { + block.Miner.Address = strings.ToLower(*address) + } + mixHash := convertDataToStringP(blk, "mixHash") + if mixHash != nil { + block.MixHash = *mixHash + } + blockNonce := convertDataToStringP(blk, "nonce") + if blockNonce != nil { + block.Nonce = *blockNonce + } + block.Number = *convertDataToUint64P(blk, "number") + block.Ommers = []*model.Block{} + block.Parent = &model.Block{} + block.Parent.Hash = *convertDataToStringP(blk, "parentHash") + block.ReceiptsRoot = *convertDataToStringP(blk, "receiptsRoot") + block.StateRoot = *convertDataToStringP(blk, "stateRoot") + block.Timestamp = *convertDataToUint64P(blk, "timestamp") // int in the schema but Geth displays in HEX !!! + block.TransactionCount = convertDataToIntP(blk, "transactionCount") + block.TransactionsRoot = *convertDataToStringP(blk, "transactionsRoot") + block.TotalDifficulty = *convertDataToStringP(blk, "totalDifficulty") + block.Transactions = []*model.Transaction{} - absRcp := res["receipts"] - rcp := absRcp.([]map[string]interface{}) - for _, transReceipt := range rcp { - trans := &model.Transaction{} - trans.CumulativeGasUsed = convertDataToUint64P(transReceipt, "cumulativeGasUsed") - trans.InputData = *convertDataToStringP(transReceipt, "data") - trans.EffectiveGasPrice = convertDataToStringP(transReceipt, "effectiveGasPrice") - trans.GasPrice = *convertDataToStringP(transReceipt, "gasPrice") - trans.GasUsed = convertDataToUint64P(transReceipt, "gasUsed") - trans.Hash = *convertDataToStringP(transReceipt, "transactionHash") - trans.Index = convertDataToIntP(transReceipt, "transactionIndex") - trans.Nonce = *convertDataToUint64P(transReceipt, "nonce") - trans.Status = convertDataToUint64P(transReceipt, "status") - trans.Type = convertDataToIntP(transReceipt, "type") - trans.Value = *convertDataToStringP(transReceipt, "value") - trans.Logs = make([]*model.Log, 0) + block.LogsBloom = "0x" + *convertDataToStringP(blk, "logsBloom") + block.OmmerHash = "" // OmmerHash: gointerfaces.ConvertHashToH256(header.UncleHash), - trans.From = &model.Account{} - trans.From.Address = strings.ToLower(*convertDataToStringP(transReceipt, "from")) + /* + Missing Block fields to fill : + - ommerHash + */ - trans.To = &model.Account{} - trans.To.Address = strings.ToLower(*convertDataToStringP(transReceipt, "to")) + absRcp := res["receipts"] + rcp := absRcp.([]map[string]interface{}) + for _, transReceipt := range rcp { + trans := &model.Transaction{} + trans.CumulativeGasUsed = convertDataToUint64P(transReceipt, "cumulativeGasUsed") + trans.InputData = *convertDataToStringP(transReceipt, "data") + trans.EffectiveGasPrice = convertDataToStringP(transReceipt, "effectiveGasPrice") + trans.GasPrice = *convertDataToStringP(transReceipt, "gasPrice") + trans.GasUsed = convertDataToUint64P(transReceipt, "gasUsed") + trans.Hash = *convertDataToStringP(transReceipt, "transactionHash") + trans.Index = convertDataToIntP(transReceipt, "transactionIndex") + trans.Nonce = *convertDataToUint64P(transReceipt, "nonce") + trans.Status = convertDataToUint64P(transReceipt, "status") + trans.Type = convertDataToIntP(transReceipt, "type") + trans.Value = *convertDataToStringP(transReceipt, "value") + trans.Logs = make([]*model.Log, 0) - block.Transactions = append(block.Transactions, trans) + trans.From = &model.Account{} + trans.From.Address = strings.ToLower(*convertDataToStringP(transReceipt, "from")) + + trans.To = &model.Account{} + address := convertDataToStringP(transReceipt, "to") + // To address could be nil in case of contract creation + if address != nil { + trans.To.Address = strings.ToLower(*convertDataToStringP(transReceipt, "to")) + } + + block.Transactions = append(block.Transactions, trans) + } } return block, ctx.Err()