2020-12-04 23:15:12 +00:00
|
|
|
package graffiti
|
|
|
|
|
|
|
|
import (
|
2021-06-10 16:54:24 +00:00
|
|
|
"encoding/hex"
|
2020-12-04 23:15:12 +00:00
|
|
|
"io/ioutil"
|
2021-06-10 16:54:24 +00:00
|
|
|
"strings"
|
2020-12-04 23:15:12 +00:00
|
|
|
|
2021-02-23 00:14:50 +00:00
|
|
|
types "github.com/prysmaticlabs/eth2-types"
|
2021-09-15 22:55:11 +00:00
|
|
|
"github.com/prysmaticlabs/prysm/crypto/hash"
|
2020-12-04 23:15:12 +00:00
|
|
|
"gopkg.in/yaml.v2"
|
|
|
|
)
|
|
|
|
|
2021-06-10 16:54:24 +00:00
|
|
|
const (
|
|
|
|
hexGraffitiPrefix = "hex"
|
|
|
|
hex0xPrefix = "0x"
|
|
|
|
)
|
|
|
|
|
2021-04-23 12:06:05 +00:00
|
|
|
// Graffiti is a graffiti container.
|
2020-12-04 23:15:12 +00:00
|
|
|
type Graffiti struct {
|
2021-02-24 22:50:47 +00:00
|
|
|
Hash [32]byte
|
2021-02-23 00:14:50 +00:00
|
|
|
Default string `yaml:"default,omitempty"`
|
2021-02-24 22:50:47 +00:00
|
|
|
Ordered []string `yaml:"ordered,omitempty"`
|
2021-02-23 00:14:50 +00:00
|
|
|
Random []string `yaml:"random,omitempty"`
|
|
|
|
Specific map[types.ValidatorIndex]string `yaml:"specific,omitempty"`
|
2020-12-04 23:15:12 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// ParseGraffitiFile parses the graffiti file and returns the graffiti struct.
|
|
|
|
func ParseGraffitiFile(f string) (*Graffiti, error) {
|
2021-08-15 15:24:13 +00:00
|
|
|
yamlFile, err := ioutil.ReadFile(f) // #nosec G304
|
2020-12-04 23:15:12 +00:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
g := &Graffiti{}
|
2021-08-01 03:26:24 +00:00
|
|
|
if err := yaml.UnmarshalStrict(yamlFile, g); err != nil {
|
|
|
|
if _, ok := err.(*yaml.TypeError); !ok {
|
|
|
|
return nil, err
|
|
|
|
} else {
|
|
|
|
log.WithError(err).Error("There were some issues parsing graffiti from a yaml file.")
|
|
|
|
}
|
2020-12-04 23:15:12 +00:00
|
|
|
}
|
2021-06-10 16:54:24 +00:00
|
|
|
|
|
|
|
for i, o := range g.Specific {
|
2021-08-11 20:12:22 +00:00
|
|
|
g.Specific[i] = ParseHexGraffiti(o)
|
2021-06-10 16:54:24 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
for i, v := range g.Ordered {
|
|
|
|
g.Ordered[i] = ParseHexGraffiti(v)
|
|
|
|
}
|
|
|
|
|
|
|
|
for i, v := range g.Random {
|
|
|
|
g.Random[i] = ParseHexGraffiti(v)
|
|
|
|
}
|
|
|
|
|
|
|
|
g.Default = ParseHexGraffiti(g.Default)
|
2021-09-15 22:55:11 +00:00
|
|
|
g.Hash = hash.Hash(yamlFile)
|
2021-06-10 16:54:24 +00:00
|
|
|
|
2020-12-04 23:15:12 +00:00
|
|
|
return g, nil
|
|
|
|
}
|
2021-06-10 16:54:24 +00:00
|
|
|
|
|
|
|
// ParseHexGraffiti checks if a graffiti input is being represented in hex and converts it to ASCII if so
|
|
|
|
func ParseHexGraffiti(rawGraffiti string) string {
|
|
|
|
splitGraffiti := strings.SplitN(rawGraffiti, ":", 2)
|
|
|
|
if strings.ToLower(splitGraffiti[0]) == hexGraffitiPrefix {
|
|
|
|
target := splitGraffiti[1]
|
|
|
|
if target == "" {
|
|
|
|
log.WithField("graffiti", rawGraffiti).Debug("Blank hex tag to be interpreted as itself")
|
|
|
|
return rawGraffiti
|
|
|
|
}
|
|
|
|
if len(target) > 3 && target[:2] == hex0xPrefix {
|
|
|
|
target = target[2:]
|
|
|
|
}
|
|
|
|
if target == "" {
|
|
|
|
log.WithField("graffiti", rawGraffiti).Debug("Nothing after 0x prefix, hex tag to be interpreted as itself")
|
|
|
|
return rawGraffiti
|
|
|
|
}
|
|
|
|
graffiti, err := hex.DecodeString(target)
|
|
|
|
if err != nil {
|
|
|
|
log.WithError(err).Debug("Error while decoding hex string")
|
|
|
|
return rawGraffiti
|
|
|
|
}
|
|
|
|
return string(graffiti)
|
|
|
|
}
|
|
|
|
return rawGraffiti
|
|
|
|
}
|