forked from KyberNetwork/kyberswap-dex-lib
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* using KyberNetwork/msgpack/v5 * encoding test encoding test renamed * feat: handled uniswapentities.{Token, Native, Ether} cycle pointer alias feat: added generate_register_pool_types.go to automatically msgpack.RegisterConcreteType() for all PoolSimulator feat: implemented AfterMsgpackUnmarshal() for pools that need to set pointer alias after decoding * Revert "encoding test" This reverts commit 9858b05. * removed test * rerun go generate * added go_generate_check.yaml * update README.md * ignore `go generate ./...` exit code * update go_generate_check.yaml's name
- Loading branch information
Showing
30 changed files
with
965 additions
and
11 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
name: Check generated codes update-to-date | ||
|
||
concurrency: | ||
group: ci-workflow-${{ github.ref }}-${{ github.event_name }} | ||
cancel-in-progress: true | ||
|
||
on: | ||
workflow_dispatch: | ||
push: | ||
branches: | ||
- main | ||
- release-v** | ||
pull_request: | ||
|
||
jobs: | ||
generate-check: | ||
name: Check generated codes update-to-date | ||
runs-on: [ubuntu-22.04] | ||
steps: | ||
- name: Checkout code | ||
uses: actions/checkout@v4 | ||
- name: Install Go | ||
uses: actions/setup-go@v5 | ||
with: | ||
go-version-file: 'go.mod' | ||
- name: Run "go generate ./..." | ||
run: go generate ./... || true | ||
- name: Check working tree clean | ||
run: if [ -z "$(git status --porcelain)" ]; then exit 0; else exit 1; fi |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,28 @@ | ||
# kyberswap-dex-lib | ||
|
||
## Marshal/unmarshal pool simulator | ||
|
||
When implementing a new pool simulator, to make it marshal-able and unmarshal-able, we have to notice the following: | ||
|
||
* rerun `go generate ./...` to register the new pool simulator struct | ||
* Because we might marshal/unmarshal a pool simulator under the `IPoolSimulator` interface. We have to register the underlying struct so we can unmarshal it as `IPoolSimulator`. | ||
|
||
* pointer aliases | ||
* If the pool simulator struct contains pointer aliases, we must use `msgpack:"-"` tag to ignore the aliases and set them inside the `AfterMsgpackUnmarshal()` method. For an example: | ||
``` | ||
type PoolSimulator struct { | ||
vault *Vault | ||
vaultUtils *VaultUtils | ||
} | ||
|
||
type VaultUtils struct { | ||
vault *Vault `msgpack:"-"` | ||
} | ||
|
||
func (p *PoolSimulator) AfterMsgpackUnmarshal() error { | ||
if p.vaultUtils != nil { | ||
p.vaultUtils.vault = p.vault | ||
} | ||
return nil | ||
} | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
package msgpack | ||
|
||
import ( | ||
"bytes" | ||
"io" | ||
"sync" | ||
|
||
"github.com/KyberNetwork/kyberswap-dex-lib/pkg/source/pool" | ||
"github.com/KyberNetwork/msgpack/v5" | ||
"github.com/klauspost/compress/snappy" | ||
) | ||
|
||
var decoderPool = sync.Pool{ | ||
New: func() any { | ||
de := msgpack.NewDecoder(nil) | ||
return de | ||
}, | ||
} | ||
|
||
func NewDecoder(r io.Reader) *msgpack.Decoder { | ||
de := decoderPool.Get().(*msgpack.Decoder) | ||
de.Reset(r) | ||
de.IncludeUnexported(true) | ||
de.SetForceAsArray(true) | ||
return de | ||
} | ||
|
||
func PutDecoder(en *msgpack.Decoder) { | ||
decoderPool.Put(en) | ||
} | ||
|
||
// DecodePoolSimulatorsMap decodes an encoded and Snappy compressed map from pool ID to IPoolSimulator | ||
func DecodePoolSimulatorsMap(encoded []byte) (map[string]pool.IPoolSimulator, error) { | ||
poolsMap := make(map[string]pool.IPoolSimulator) | ||
zw := snappy.NewReader(bytes.NewReader(encoded)) | ||
de := NewDecoder(zw) | ||
defer PutDecoder(de) | ||
if err := de.Decode(&poolsMap); err != nil { | ||
return nil, err | ||
} | ||
return poolsMap, nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
package msgpack | ||
|
||
import ( | ||
"bytes" | ||
"io" | ||
"sync" | ||
|
||
"github.com/KyberNetwork/kyberswap-dex-lib/pkg/source/pool" | ||
"github.com/KyberNetwork/msgpack/v5" | ||
"github.com/klauspost/compress/snappy" | ||
) | ||
|
||
var encoderPool = sync.Pool{ | ||
New: func() any { | ||
en := msgpack.NewEncoder(nil) | ||
return en | ||
}, | ||
} | ||
|
||
func NewEncoder(w io.Writer) *msgpack.Encoder { | ||
en := encoderPool.Get().(*msgpack.Encoder) | ||
en.Reset(w) | ||
en.IncludeUnexported(true) | ||
en.SetForceAsArray(true) | ||
return en | ||
} | ||
|
||
func PutEncoder(en *msgpack.Encoder) { | ||
encoderPool.Put(en) | ||
} | ||
|
||
// EncodePoolSimulatorsMap encode a map from pool ID to IPoolSimulator with Snappy compression | ||
func EncodePoolSimulatorsMap(poolsMap map[string]pool.IPoolSimulator) ([]byte, error) { | ||
var ( | ||
buf bytes.Buffer | ||
zw = snappy.NewBufferedWriter(&buf) | ||
) | ||
en := NewEncoder(zw) | ||
defer PutEncoder(en) | ||
if err := en.Encode(poolsMap); err != nil { | ||
return nil, err | ||
} | ||
if err := zw.Close(); err != nil { | ||
return nil, err | ||
} | ||
return buf.Bytes(), nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,168 @@ | ||
package main | ||
|
||
import ( | ||
"bufio" | ||
"fmt" | ||
"io" | ||
"io/fs" | ||
"log" | ||
"os" | ||
"path/filepath" | ||
"strings" | ||
) | ||
|
||
const ( | ||
poolSimFileName = "pool_simulator.go" | ||
moduleName = "github.com/KyberNetwork/kyberswap-dex-lib" | ||
regularPoolSimName = "PoolSimulator" | ||
) | ||
|
||
var ( | ||
irregularPoolSimNameByPackageName = map[string]string{ | ||
"pkg_source_balancer_stable": "StablePool", | ||
"pkg_source_balancer_weighted": "WeightedPool2Tokens", | ||
"pkg_source_curve_aave": "AavePool", | ||
"pkg_source_curve_base": "PoolBaseSimulator", | ||
"pkg_source_curve_compound": "CompoundPool", | ||
"pkg_source_curve_meta": "Pool", | ||
"pkg_source_curve_plainoracle": "Pool", | ||
"pkg_source_curve_tricrypto": "Pool", | ||
"pkg_source_curve_two": "Pool", | ||
"pkg_source_maverickv1": "Pool", | ||
"pkg_source_velocimeter": "Pool", | ||
} | ||
) | ||
|
||
func main() { | ||
var paths []string | ||
|
||
if dir := findGoModDirInParents(); dir != "" { | ||
for _, path := range findAllPoolTestdataSourceFile(dir) { | ||
path = strings.TrimPrefix(path, dir+"/") | ||
paths = append(paths, path) | ||
} | ||
} | ||
|
||
if len(paths) == 0 { | ||
return | ||
} | ||
|
||
pkgNames := getPackageNamesFromSourceFiles(paths) | ||
importPaths := getPackageImportPathsFromSourceFiles(paths) | ||
|
||
outFile, err := os.Create("./register_pool_types.go") | ||
if err != nil { | ||
log.Fatalf("could not create dispatch_gen.go: %s", err) | ||
} | ||
defer outFile.Close() | ||
|
||
outFileBuf := bufio.NewWriter(outFile) | ||
defer outFileBuf.Flush() | ||
|
||
emitImports(outFileBuf, pkgNames, importPaths) | ||
|
||
fmt.Fprintf(outFileBuf, "func init() {\n") | ||
for _, pkgName := range pkgNames { | ||
poolSimName := regularPoolSimName | ||
if name, ok := irregularPoolSimNameByPackageName[pkgName]; ok { | ||
poolSimName = name | ||
} | ||
fmt.Fprintf(outFileBuf, "\tmsgpack.RegisterConcreteType(&%s.%s{})\n", pkgName, poolSimName) | ||
} | ||
fmt.Fprintf(outFileBuf, "}\n") | ||
|
||
} | ||
|
||
func emitImports(outFileBuf io.Writer, pkgNames, importPaths []string) { | ||
fmt.Fprintf(outFileBuf, "package msgpack\n") | ||
fmt.Fprintf(outFileBuf, "\n") | ||
|
||
fmt.Fprintf(outFileBuf, "// Code generated by %s/pkg/msgpack/generate DO NOT EDIT.\n", moduleName) | ||
fmt.Fprintf(outFileBuf, "\n") | ||
|
||
fmt.Fprintf(outFileBuf, "import (\n") | ||
fmt.Fprintf(outFileBuf, "\t\"github.com/KyberNetwork/msgpack/v5\"\n") | ||
fmt.Fprintf(outFileBuf, "\n") | ||
for i, dexName := range pkgNames { | ||
fmt.Fprintf(outFileBuf, "\t%s \"%s\"\n", dexName, importPaths[i]) | ||
} | ||
fmt.Fprintf(outFileBuf, ")\n") | ||
} | ||
|
||
func findGoModDirInParents() string { | ||
var ( | ||
hasGoMod = false | ||
cwd, _ = os.Getwd() | ||
visited = make(map[string]struct{}) // to eliminate cycle | ||
) | ||
for { | ||
if _, ok := visited[cwd]; ok { | ||
break | ||
} | ||
visited[cwd] = struct{}{} | ||
|
||
entries, err := os.ReadDir(cwd) | ||
if err != nil { | ||
break | ||
} | ||
for _, entry := range entries { | ||
if entry.Name() == "go.mod" { | ||
hasGoMod = true | ||
break | ||
} | ||
} | ||
if hasGoMod { | ||
break | ||
} | ||
|
||
cwd = filepath.Join(cwd, "..") | ||
cwd, err = filepath.Abs(cwd) | ||
if err != nil { | ||
break | ||
} | ||
} | ||
if hasGoMod { | ||
return cwd | ||
} | ||
return "" | ||
} | ||
|
||
func findAllPoolTestdataSourceFile(rootDir string) []string { | ||
var paths []string | ||
err := filepath.Walk(rootDir, func(path string, info fs.FileInfo, err error) error { | ||
if err != nil { | ||
return err | ||
} | ||
if info.IsDir() { | ||
return nil | ||
} | ||
if strings.HasSuffix(path, "/"+poolSimFileName) { | ||
paths = append(paths, path) | ||
} | ||
return nil | ||
}) | ||
if err != nil { | ||
panic(err) | ||
} | ||
return paths | ||
} | ||
|
||
func getPackageNamesFromSourceFiles(sourcePaths []string) []string { | ||
importNames := make([]string, 0, len(sourcePaths)) | ||
for _, path := range sourcePaths { | ||
dexName := strings.TrimSuffix(path, "/"+poolSimFileName) | ||
dexName = strings.ReplaceAll(dexName, "-", "") | ||
dexName = strings.ReplaceAll(dexName, "/", "_") | ||
importNames = append(importNames, dexName) | ||
} | ||
return importNames | ||
} | ||
|
||
func getPackageImportPathsFromSourceFiles(sourcePaths []string) []string { | ||
paths := make([]string, 0, len(sourcePaths)) | ||
for _, path := range sourcePaths { | ||
importPath := filepath.Join(moduleName, strings.TrimSuffix(path, "/"+poolSimFileName)) | ||
paths = append(paths, importPath) | ||
} | ||
return paths | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
//go:generate go run ./generate | ||
|
||
package msgpack |
Oops, something went wrong.