Skip to content

Commit

Permalink
fix snake case issues and add golden image state
Browse files Browse the repository at this point in the history
  • Loading branch information
ArnaudBger committed Jul 8, 2024
1 parent 6449f46 commit 8a398f8
Show file tree
Hide file tree
Showing 22 changed files with 4,210 additions and 56 deletions.
27 changes: 15 additions & 12 deletions ethfull/abi.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,13 @@ package ethfull
import (
"encoding/hex"
"fmt"
"github.com/golang-cz/textcase"
"github.com/huandu/xstrings"
"sort"
"strconv"
"strings"

"github.com/gertd/go-pluralize"
"github.com/huandu/xstrings"
"github.com/iancoleman/strcase"
"github.com/streamingfast/eth-go"
codegen "github.com/streamingfast/substreams-codegen"
Expand Down Expand Up @@ -87,7 +88,7 @@ func (a *ABI) BuildEventModels() (out []codegenEvent, err error) {

protoFieldName := xstrings.ToSnakeCase(pluralizerSingleton.Plural(rustABIStructName))
// prost will do a to_lower_camel_case() on any struct name
rustGeneratedStructName := xstrings.ToCamelCase(xstrings.ToSnakeCase(rustABIStructName))
rustGeneratedStructName := textcase.PascalCase(xstrings.ToSnakeCase(rustABIStructName))

eventID := hex.EncodeToString(event.LogID())

Expand Down Expand Up @@ -156,9 +157,10 @@ func (a *ABI) BuildCallModels() (out []codegenCall, err error) {
rustABIStructName = sanitizeABIStructName(rustABIStructName)

protoFieldName := "call_" + xstrings.ToSnakeCase(pluralizerSingleton.Plural(rustABIStructName))

// prost will do a to_lower_camel_case() on any struct name
rustGeneratedStructName := xstrings.ToCamelCase(xstrings.ToSnakeCase(rustABIStructName))
protoMessageName := xstrings.ToCamelCase(xstrings.ToSnakeCase(rustABIStructName) + "Call")
rustGeneratedStructName := textcase.PascalCase(xstrings.ToSnakeCase(rustABIStructName))
protoMessageName := textcase.PascalCase(xstrings.ToSnakeCase(rustABIStructName) + "Call")

codegenCall := codegenCall{
Rust: &rustCallModel{
Expand Down Expand Up @@ -253,8 +255,8 @@ func (e *rustEventModel) populateFields(log *eth.LogEventDef) error {
zlog.Info("Generating ABI Events", zap.String("name", log.Name), zap.String("param_names", strings.Join(paramNames, ",")))

for _, parameter := range log.Parameters {
name := xstrings.ToSnakeCase(parameter.Name)
name = codegen.SanitizeProtoFieldName(name)
name := codegen.SanitizeProtoFieldName(parameter.Name)
name = xstrings.ToSnakeCase(name)

toProtoCode := generateFieldTransformCode(parameter.Type, "event."+name, false)
if toProtoCode == SKIP_FIELD {
Expand Down Expand Up @@ -387,8 +389,8 @@ func methodToABIConversionMaps(
abiConversionMap = make(map[string]string)
}
for _, parameter := range parameters {
name := xstrings.ToSnakeCase(parameter.Name)
name = codegen.SanitizeProtoFieldName(name)
name := codegen.SanitizeProtoFieldName(parameter.Name)
name = xstrings.ToSnakeCase(name)

toProtoCode := generateFieldTransformCode(parameter.Type, "decoded_call."+name, false)
if toProtoCode != SKIP_FIELD {
Expand Down Expand Up @@ -499,8 +501,9 @@ func (e *protoEventModel) populateFields(log *eth.LogEventDef) error {

e.Fields = make([]protoField, 0, len(log.Parameters))
for _, parameter := range log.Parameters {
fieldName := xstrings.ToSnakeCase(parameter.Name)
fieldName = codegen.SanitizeProtoFieldName(fieldName)
fieldName := codegen.SanitizeProtoFieldName(parameter.Name)
fieldName = xstrings.ToSnakeCase(fieldName)

fieldType := getProtoFieldType(parameter.Type)
if fieldType == SKIP_FIELD {
continue
Expand All @@ -524,8 +527,8 @@ func (e *protoCallModel) populateFields(call *eth.MethodDef) error {
e.Fields = make([]protoField, 0, len(call.Parameters)+len(call.ReturnParameters))

for _, parameter := range call.Parameters {
fieldName := xstrings.ToSnakeCase(parameter.Name)
fieldName = codegen.SanitizeProtoFieldName(fieldName)
fieldName := codegen.SanitizeProtoFieldName(parameter.Name)
fieldName = xstrings.ToSnakeCase(fieldName)
fieldType := getProtoFieldType(parameter.Type)
if fieldType == SKIP_FIELD {
continue
Expand Down
80 changes: 80 additions & 0 deletions ethfull/generate_test.go
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
package ethfull

import (
"archive/zip"
"bytes"
"context"
"encoding/json"
"io"
"os"
"strings"
"testing"

"github.com/saracen/fastzip"
Expand Down Expand Up @@ -70,6 +73,11 @@ func Test_Generate(t *testing.T) {
generatorFile: "./testdata/uniswap_track_calls_clickhouse.json",
outputType: outputTypeSQL,
},
{
name: "Complex abi with digits and specific character",
generatorFile: "./testdata/complex_abi.json",
outputType: outputTypeSubgraph,
},
}

for _, c := range cases {
Expand Down Expand Up @@ -127,6 +135,78 @@ func Test_Generate(t *testing.T) {
}
}

func TestGoldenImage(t *testing.T) {
cases := []struct {
name string
generatorFile string
expectedOutput string
}{
{
name: "complex_abi",
generatorFile: "./testdata/complex_abi.json",
expectedOutput: "./testoutput/complex_abi",
},
}

for _, c := range cases {
t.Run(c.name, func(t *testing.T) {
p := testProjectFromState(t, c.generatorFile)

for _, contract := range p.Contracts {
res := cmdDecodeABI(contract)().(ReturnRunDecodeContractABI)
require.NoError(t, res.err)
contract.abi = res.abi
}

for _, dynamicContract := range p.DynamicContracts {
res := cmdDecodeDynamicABI(dynamicContract)().(ReturnRunDecodeDynamicContractABI)
require.NoError(t, res.err)
dynamicContract.abi = res.abi

for _, contract := range p.Contracts {
if contract.Name == dynamicContract.ParentContractName {
dynamicContract.parentContract = contract
}
}
}

p.outputType = outputTypeSubgraph

srcZip, projZip, err := p.generate(outputTypeSubgraph)
require.NoError(t, err)
assert.NotEmpty(t, srcZip)
assert.NotEmpty(t, projZip)

//Unzip srcZip and compare with expectedOutput
reader := bytes.NewReader(srcZip)
zipReader, err := zip.NewReader(reader, int64(len(srcZip)))
require.NoError(t, err)

for _, f := range zipReader.File {
//Should not modify the abi.json at all
if strings.HasSuffix(f.Name, "abi.json") {
continue
}

goldenFileName := c.expectedOutput + "/" + strings.TrimPrefix(f.Name, "substreams/")
goldenContent, err := os.ReadFile(goldenFileName)
require.NoError(t, err)

fileReader, err := f.Open()
require.NoError(t, err)

unzipFileContent, err := io.ReadAll(fileReader)

//Remove /n from both files
goldenContent = bytes.ReplaceAll(goldenContent, []byte("\n"), []byte(""))
unzipFileContent = bytes.ReplaceAll(unzipFileContent, []byte("\n"), []byte(""))

require.Equal(t, goldenContent, unzipFileContent)
}
})
}
}

func TestUniFactory(t *testing.T) {
p := testProjectFromState(t, "./testdata/uniswap_factory_v3.json")

Expand Down
1 change: 0 additions & 1 deletion ethfull/helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,5 @@ func sanitizeABIStructName(rustABIStructName string) string {

return replacement
})

return result
}
22 changes: 14 additions & 8 deletions ethfull/state.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,14 @@ import (
"encoding/hex"
"encoding/json"
"fmt"
"github.com/codemodus/kace"
"github.com/golang-cz/textcase"
"github.com/huandu/xstrings"
"math"
"regexp"
"strings"
"time"

"github.com/huandu/xstrings"
"github.com/iancoleman/strcase"
"github.com/streamingfast/eth-go"
)

Expand Down Expand Up @@ -59,7 +60,7 @@ func contractNames(contracts []*Contract) (out []string) {
func (p *Project) ChainConfig() *ChainConfig { return ChainConfigByID[p.ChainName] }
func (p *Project) ChainEndpoint() string { return ChainConfigByID[p.ChainName].FirehoseEndpoint }

func (p *Project) SubgraphProjectName() string { return xstrings.ToKebabCase(p.Name) }
func (p *Project) SubgraphProjectName() string { return textcase.KebabCase(p.Name) }
func (p *Project) SQLImportVersion() string { return "1.0.7" }
func (p *Project) GraphImportVersion() string { return "0.1.0" }
func (p *Project) DatabaseChangeImportVersion() string { return "1.2.1" }
Expand Down Expand Up @@ -199,9 +200,13 @@ type BaseContract struct {
abi *ABI
}

func (c *BaseContract) Identifier() string { return c.Name }
func (c *BaseContract) IdentityCamelCase() string { return strcase.ToLowerCamel(c.Name) }
func (c *BaseContract) IdentifierUpper() string { return strings.ToUpper(c.Name) }
func (c *BaseContract) Identifier() string { return c.Name }
func (c *BaseContract) IdentifierSnakeCase() string {
return xstrings.ToSnakeCase(c.Name)
}
func (c *BaseContract) IdentifierPascalCase() string { return textcase.PascalCase(c.Name) }
func (c *BaseContract) IdentityCamelCase() string { return textcase.CamelCase(c.Name) }
func (c *BaseContract) IdentifierUpper() string { return strings.ToUpper(c.Name) }

func (c *BaseContract) EventFields(event string) ([]*eth.LogParameter, error) {
hash, err := hex.DecodeString(event)
Expand Down Expand Up @@ -288,8 +293,9 @@ func (d DynamicContract) FactoryInitialBlock() uint64 {
return *d.parentContract.InitialBlock
}

func (d DynamicContract) ParentContract() *Contract { return d.parentContract }
func (d DynamicContract) Identifier() string { return d.Name }
func (d DynamicContract) ParentContract() *Contract { return d.parentContract }
func (d DynamicContract) Identifier() string { return d.Name }
func (d DynamicContract) IdentifierSnakeCase() string { return kace.Snake(d.Name) }
func (d DynamicContract) FetchABI(chainConfig *ChainConfig) (abi string, err error) {
a, err := getContractABIFollowingProxy(context.Background(), d.referenceContractAddress, chainConfig)
if err != nil {
Expand Down
16 changes: 8 additions & 8 deletions ethfull/templates/proto/contract.proto.gotmpl
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ message Events {
{{- range $index, $event := $contract.EventModels }}
{{- $proto := $event.Proto }}
{{- $eventsCounter = add $eventsCounter 1 }}
repeated {{ toPascalCase $contract.Identifier }}_{{$proto.MessageName}} {{ toSnakeCase $contract.Identifier }}_{{$proto.OutputModuleFieldName}} = {{ $eventsCounter }};
repeated {{ $contract.IdentifierPascalCase }}_{{$proto.MessageName}} {{ $contract.IdentifierSnakeCase }}_{{$proto.OutputModuleFieldName}} = {{ $eventsCounter }};
{{- end}}
{{- end}}
{{- end}}
Expand All @@ -21,7 +21,7 @@ message Events {
{{- range $index, $event := $ddsContract.EventModels -}}
{{- $proto := $event.Proto }}
{{- $eventsCounter = add $eventsCounter 1 }}
repeated {{ toPascalCase $ddsContract.Identifier }}_{{$proto.MessageName}} {{ toSnakeCase $ddsContract.Identifier }}_{{$proto.OutputModuleFieldName}} = {{ $eventsCounter }};
repeated {{ $ddsContract.IdentifierPascalCase }}_{{$proto.MessageName}} {{ $ddsContract.IdentifierSnakeCase }}_{{$proto.OutputModuleFieldName}} = {{ $eventsCounter }};
{{- end}}
{{- end}}
{{- end}}
Expand All @@ -35,7 +35,7 @@ message Calls {
{{- range $index, $call := $contract.CallModels }}
{{- $proto := $call.Proto }}
{{- $callsCounter = add $callsCounter 1 }}
repeated {{ toPascalCase $contract.Identifier }}_{{$proto.MessageName}} {{ toSnakeCase $contract.Identifier }}_{{$proto.OutputModuleFieldName}} = {{ $callsCounter }};
repeated {{ $contract.IdentifierPascalCase }}_{{$proto.MessageName}} {{ $contract.IdentifierSnakeCase }}_{{$proto.OutputModuleFieldName}} = {{ $callsCounter }};
{{- end}}
{{- end}}
{{- end}}
Expand All @@ -44,7 +44,7 @@ message Calls {
{{- range $index, $call := $ddsContract.CallModels -}}
{{- $proto := $call.Proto }}
{{- $callsCounter = add $callsCounter 1 }}
repeated {{ toPascalCase $ddsContract.Identifier }}_{{$proto.MessageName}} {{ toSnakeCase $ddsContract.Identifier }}_{{$proto.OutputModuleFieldName}} = {{ $callsCounter }};
repeated {{ $ddsContract.IdentifierPascalCase }}_{{$proto.MessageName}} {{ $ddsContract.IdentifierSnakeCase }}_{{$proto.OutputModuleFieldName}} = {{ $callsCounter }};
{{- end}}
{{- end}}
{{- end}}
Expand All @@ -60,7 +60,7 @@ message EventsCalls {
{{- if .TrackEvents }}
{{- range $index, $event := $contract.EventModels }}
{{- $proto := $event.Proto }}
message {{ toPascalCase $contract.Identifier }}_{{ $proto.MessageName }} {
message {{ $contract.IdentifierPascalCase }}_{{ $proto.MessageName }} {
string evt_tx_hash = 1;
uint32 evt_index = 2;
google.protobuf.Timestamp evt_block_time = 3;
Expand All @@ -74,7 +74,7 @@ message {{ toPascalCase $contract.Identifier }}_{{ $proto.MessageName }} {
{{ if .TrackCalls }}
{{- range $index, $call := $contract.CallModels }}
{{- $proto := $call.Proto }}
message {{ toPascalCase $contract.Identifier }}_{{ $proto.MessageName }} {
message {{ $contract.IdentifierPascalCase }}_{{ $proto.MessageName }} {
string call_tx_hash = 1;
google.protobuf.Timestamp call_block_time = 2;
uint64 call_block_number = 3;
Expand All @@ -92,7 +92,7 @@ message {{ toPascalCase $contract.Identifier }}_{{ $proto.MessageName }} {

{{- range $index, $event := $ddsContract.EventModels }}
{{ $proto := $event.Proto }}
message {{ toPascalCase $ddsContract.Identifier }}_{{ $proto.MessageName }} {
message {{ $ddsContract.IdentifierPascalCase }}_{{ $proto.MessageName }} {
string evt_tx_hash = 1;
uint32 evt_index = 2;
google.protobuf.Timestamp evt_block_time = 3;
Expand All @@ -106,7 +106,7 @@ message {{ toPascalCase $ddsContract.Identifier }}_{{ $proto.MessageName }} {

{{- range $index, $call := $ddsContract.CallModels }}
{{ $proto := $call.Proto }}
message {{ toPascalCase $ddsContract.Identifier }}_{{ $proto.MessageName }} {
message {{ $ddsContract.IdentifierPascalCase }}_{{ $proto.MessageName }} {
string call_tx_hash = 1;
google.protobuf.Timestamp call_block_time = 2;
uint64 call_block_number = 3;
Expand Down
Loading

0 comments on commit 8a398f8

Please sign in to comment.