Skip to content

Commit

Permalink
Fix json block logic
Browse files Browse the repository at this point in the history
  • Loading branch information
bbedward committed Sep 1, 2022
1 parent 2aadf93 commit 2da6016
Show file tree
Hide file tree
Showing 2 changed files with 59 additions and 31 deletions.
71 changes: 46 additions & 25 deletions controller/http_api_c.go
Original file line number Diff line number Diff line change
Expand Up @@ -132,58 +132,79 @@ func (hc *HttpController) HandleAction(c *fiber.Ctx) error {
return c.Status(fiber.StatusOK).JSON(responseMap)
} else if action == "process" {
// Process request
var processRequest models.ProcessRequest
var processRequest map[string]interface{}
if err := json.Unmarshal(c.Request().Body(), &processRequest); err != nil {
return c.Status(fiber.StatusBadRequest).JSON(models.INVALID_REQUEST_ERR)
if err != nil {
return c.Status(fiber.StatusBadRequest).JSON(models.INVALID_REQUEST_ERR)
}
}

if processRequest.Block == nil && processRequest.JsonBlock == nil {
return c.Status(fiber.StatusBadRequest).JSON(models.INVALID_REQUEST_ERR)
var jsonBlock bool
if _, ok := processRequest["json_block"]; ok {
jsonBlock, ok = processRequest["json_block"].(bool)
if !ok {
return c.Status(fiber.StatusBadRequest).JSON(models.INVALID_REQUEST_ERR)
}
}

// Sometimes requests come with a string block representation
if processRequest.JsonBlock == nil {
if err := json.Unmarshal([]byte(*processRequest.Block), &processRequest.JsonBlock); err != nil {
var processRequestStringBlock models.ProcessRequestStringBlock
var processRequestBlock models.ProcessJsonBlock
var processRequestJsonBlock models.ProcessRequestJsonBlock
if jsonBlock {
if err := json.Unmarshal(c.Request().Body(), &processRequestJsonBlock); err != nil {
return c.Status(fiber.StatusBadRequest).JSON(models.INVALID_REQUEST_ERR)
}
} else {
if err := json.Unmarshal(c.Request().Body(), &processRequestStringBlock); err != nil {
return c.Status(fiber.StatusBadRequest).JSON(models.INVALID_REQUEST_ERR)
}
if err := json.Unmarshal([]byte(*processRequestStringBlock.Block), &processRequestBlock); err != nil {
return c.Status(fiber.StatusBadRequest).JSON(models.INVALID_REQUEST_ERR)
}
processRequestJsonBlock = models.ProcessRequestJsonBlock{
Block: &processRequestBlock,
Action: processRequestStringBlock.Action,
SubType: processRequestStringBlock.SubType,
DoWork: processRequestStringBlock.DoWork,
}
}

if processRequest.JsonBlock.Type != "state" {
if processRequestJsonBlock.Block.Type != "state" {
return c.Status(fiber.StatusBadRequest).JSON(models.INVALID_REQUEST_ERR)
}

// Check if we wanna calculate work as part of this request
doWork := false
if processRequest.DoWork != nil && processRequest.JsonBlock.Work == nil {
doWork = *processRequest.DoWork
if processRequestJsonBlock.DoWork != nil && processRequestJsonBlock.Block.Work == nil {
doWork = *processRequestJsonBlock.DoWork
}

// Determine the type of block
if processRequest.SubType == nil {
if strings.ReplaceAll(processRequest.JsonBlock.Link, "0", "") == "" {
if processRequestJsonBlock.SubType == nil {
if strings.ReplaceAll(processRequestJsonBlock.Block.Link, "0", "") == "" {
subtype := "change"
processRequest.SubType = &subtype
processRequestJsonBlock.SubType = &subtype
}
} else if !slices.Contains([]string{"change", "open", "receive", "send"}, *processRequest.SubType) {
} else if !slices.Contains([]string{"change", "open", "receive", "send"}, *processRequestJsonBlock.SubType) {
return c.Status(fiber.StatusBadRequest).JSON(models.INVALID_REQUEST_ERR)
}
// ! TODO - what is the point of this, from old server
// await r.app['rdata'].set(f"link_{block['link']}", "1", expire=3600)

// Open blocks generate work on the public key, others use previous
var workBase string
if processRequest.JsonBlock.Previous == "0" || processRequest.JsonBlock.Previous == "0000000000000000000000000000000000000000000000000000000000000000" {
workbaseBytes, err := utils.AddressToPub(processRequest.JsonBlock.Account)
if processRequestJsonBlock.Block.Previous == "0" || processRequestJsonBlock.Block.Previous == "0000000000000000000000000000000000000000000000000000000000000000" {
workbaseBytes, err := utils.AddressToPub(processRequestJsonBlock.Block.Account)
if err != nil {
return c.Status(fiber.StatusBadRequest).JSON(models.INVALID_REQUEST_ERR)
}
workBase = hex.EncodeToString(workbaseBytes)
subtype := "open"
processRequest.SubType = &subtype
processRequestJsonBlock.SubType = &subtype
} else {
workBase = processRequest.JsonBlock.Previous
workBase = processRequestJsonBlock.Block.Previous
// Since we are here, let's validate the frontier
accountInfo, err := hc.RPCClient.MakeAccountInfoRequest(processRequest.JsonBlock.Account)
accountInfo, err := hc.RPCClient.MakeAccountInfoRequest(processRequestJsonBlock.Block.Account)
if err != nil {
klog.Errorf("Error making account info request %s", err)
return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{
Expand All @@ -192,7 +213,7 @@ func (hc *HttpController) HandleAction(c *fiber.Ctx) error {
}
if _, ok := accountInfo["error"]; !ok {
// Account is opened
if strings.ToLower(fmt.Sprintf("%s", accountInfo["frontier"])) != strings.ToLower(processRequest.JsonBlock.Previous) {
if strings.ToLower(fmt.Sprintf("%s", accountInfo["frontier"])) != strings.ToLower(processRequestJsonBlock.Block.Previous) {
return c.Status(fiber.StatusBadRequest).JSON(models.INVALID_REQUEST_ERR)
}
}
Expand All @@ -202,10 +223,10 @@ func (hc *HttpController) HandleAction(c *fiber.Ctx) error {
var difficultyMultiplier int
if hc.BananoMode {
difficultyMultiplier = 1
} else if processRequest.SubType == nil {
} else if processRequestJsonBlock.SubType == nil {
// ! TODO - would be good to check if this is a send or receive if subtype isn't included
difficultyMultiplier = 64
} else if slices.Contains([]string{"change", "send"}, *processRequest.SubType) {
} else if slices.Contains([]string{"change", "send"}, *processRequestJsonBlock.SubType) {
difficultyMultiplier = 64
} else {
difficultyMultiplier = 1
Expand All @@ -218,18 +239,18 @@ func (hc *HttpController) HandleAction(c *fiber.Ctx) error {
"error": "Error generating work",
})
}
processRequest.JsonBlock.Work = &work
processRequestJsonBlock.Block.Work = &work
}

if processRequest.JsonBlock.Work == nil {
if processRequestJsonBlock.Block.Work == nil {
return c.Status(fiber.StatusBadRequest).JSON(models.INVALID_REQUEST_ERR)
}

// Now G2G to actually broadcast it
finalProcessRequest := map[string]interface{}{
"action": "process",
"json_block": true,
"block": processRequest.JsonBlock,
"block": processRequestJsonBlock.Block,
}
rawResp, err := hc.RPCClient.MakeRequest(finalProcessRequest)
if err != nil {
Expand Down
19 changes: 13 additions & 6 deletions models/process_request.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,17 @@ type ProcessJsonBlock struct {
Representative string `json:"representative"`
}

type ProcessRequest struct {
Action string `json:"action"`
Block *string `json:"block,omitempty"`
JsonBlock *ProcessJsonBlock `json:"json_block,omitempty"`
DoWork *bool `json:"do_work,omitempty"`
SubType *string `json:"subtype,omitempty"`
type ProcessRequestStringBlock struct {
Action string `json:"action"`
Block *string `json:"block,omitempty"`
JsonBlock *bool `json:"json_block,omitempty"`
DoWork *bool `json:"do_work,omitempty"`
SubType *string `json:"subtype,omitempty"`
}

type ProcessRequestJsonBlock struct {
Action string `json:"action"`
Block *ProcessJsonBlock `json:"block,omitempty"`
DoWork *bool `json:"do_work,omitempty"`
SubType *string `json:"subtype,omitempty"`
}

0 comments on commit 2da6016

Please sign in to comment.