aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--go.mod2
-rw-r--r--go.sum2
-rw-r--r--plugin/evm/client.go174
-rw-r--r--plugin/evm/export_tx.go2
-rw-r--r--plugin/evm/import_tx.go2
-rw-r--r--plugin/evm/import_tx_test.go4
-rw-r--r--plugin/evm/service.go78
-rw-r--r--plugin/evm/static_service.go5
-rw-r--r--plugin/evm/tx.go6
-rw-r--r--plugin/evm/user.go4
-rw-r--r--plugin/evm/vm.go57
-rw-r--r--plugin/evm/vm_test.go17
12 files changed, 247 insertions, 106 deletions
diff --git a/go.mod b/go.mod
index 7431960..fc27ba4 100644
--- a/go.mod
+++ b/go.mod
@@ -4,7 +4,7 @@ go 1.14
require (
github.com/VictoriaMetrics/fastcache v1.5.7
- github.com/ava-labs/avalanchego v1.0.5
+ github.com/ava-labs/avalanchego v1.0.5-client
github.com/davecgh/go-spew v1.1.1
github.com/deckarep/golang-set v1.7.1
github.com/edsrzf/mmap-go v1.0.0
diff --git a/go.sum b/go.sum
index e8af04f..6232801 100644
--- a/go.sum
+++ b/go.sum
@@ -46,6 +46,8 @@ github.com/aristanetworks/goarista v0.0.0-20170210015632-ea17b1a17847/go.mod h1:
github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o=
github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY=
github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8=
+github.com/ava-labs/avalanchego v1.0.5-client h1:/tvPyl6T3Ujn8RHeQ83sezt944XZX6BMlKkp1J+I/ss=
+github.com/ava-labs/avalanchego v1.0.5-client/go.mod h1:Q/I7LaMv2EYL8plNVRbcpBJsDk2py2XISfov0KK1MgU=
github.com/ava-labs/avalanchego v1.0.5 h1:zjBaM/9l2VjnL7j6SEwmqKjPie1W9NSEDLrd2ZotMCA=
github.com/ava-labs/avalanchego v1.0.5/go.mod h1:4GfedhY9S6k/SOUeMzDh6cuLoPAtnkFsL4R89xg5wf0=
github.com/aws/aws-sdk-go v1.25.48/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo=
diff --git a/plugin/evm/client.go b/plugin/evm/client.go
new file mode 100644
index 0000000..0817545
--- /dev/null
+++ b/plugin/evm/client.go
@@ -0,0 +1,174 @@
+// (c) 2019-2020, Ava Labs, Inc. All rights reserved.
+// See the file LICENSE for licensing terms.
+
+package evm
+
+import (
+ "fmt"
+ "time"
+
+ "github.com/ava-labs/avalanchego/api"
+ "github.com/ava-labs/avalanchego/ids"
+ "github.com/ava-labs/avalanchego/utils/formatting"
+ cjson "github.com/ava-labs/avalanchego/utils/json"
+ "github.com/ava-labs/avalanchego/utils/rpc"
+)
+
+// Client ...
+type Client struct {
+ requester rpc.EndpointRequester
+}
+
+// NewClient returns a Client for interacting with EVM [chain]
+func NewClient(uri, chain string, requestTimeout time.Duration) *Client {
+ return &Client{
+ requester: rpc.NewEndpointRequester(uri, fmt.Sprintf("/ext/bc/%s/avax", chain), "avax", requestTimeout),
+ }
+}
+
+// NewCChainClient returns a Client for interacting with the C Chain
+func NewCChainClient(uri string, requestTimeout time.Duration) *Client {
+ return NewClient(uri, "C", requestTimeout)
+}
+
+// IssueTx issues a transaction to a node and returns the TxID
+func (c *Client) IssueTx(txBytes []byte) (ids.ID, error) {
+ res := &api.JSONTxID{}
+ txStr, err := formatting.Encode(formatting.Hex, txBytes)
+ if err != nil {
+ return res.TxID, fmt.Errorf("problem hex encoding bytes: %w", err)
+ }
+ err = c.requester.SendRequest("issueTx", &api.FormattedTx{
+ Tx: txStr,
+ Encoding: formatting.Hex,
+ }, res)
+ return res.TxID, err
+}
+
+// GetTxStatus returns the status of [txID]
+// func (c *Client) GetTxStatus(txID ids.ID) (choices.Status, error) {
+// res := &GetTxStatusReply{}
+// err := c.requester.SendRequest("getTxStatus", &api.JSONTxID{
+// TxID: txID,
+// }, res)
+// return res.Status, err
+// }
+
+// GetTx returns the byte representation of [txID]
+func (c *Client) GetTx(txID ids.ID) ([]byte, error) {
+ res := &api.FormattedTx{}
+ err := c.requester.SendRequest("getTx", &api.GetTxArgs{
+ TxID: txID,
+ Encoding: formatting.Hex,
+ }, res)
+ if err != nil {
+ return nil, err
+ }
+
+ return formatting.Decode(formatting.Hex, res.Tx)
+}
+
+// GetUTXOs returns the byte representation of the UTXOs controlled by [addrs]
+func (c *Client) GetUTXOs(addrs []string, limit uint32, startAddress, startUTXOID string) ([][]byte, api.Index, error) {
+ res := &api.GetUTXOsReply{}
+ err := c.requester.SendRequest("getUTXOs", &api.GetUTXOsArgs{
+ Addresses: addrs,
+ Limit: cjson.Uint32(limit),
+ StartIndex: api.Index{
+ Address: startAddress,
+ UTXO: startUTXOID,
+ },
+ Encoding: formatting.Hex,
+ }, res)
+ if err != nil {
+ return nil, api.Index{}, err
+ }
+
+ utxos := make([][]byte, len(res.UTXOs))
+ for i, utxo := range res.UTXOs {
+ b, err := formatting.Decode(formatting.Hex, utxo)
+ if err != nil {
+ return nil, api.Index{}, err
+ }
+ utxos[i] = b
+ }
+ return utxos, res.EndIndex, nil
+}
+
+// CreateAddress creates a new address controlled by [user]
+func (c *Client) CreateAddress(user api.UserPass) (string, error) {
+ res := &api.JSONAddress{}
+ err := c.requester.SendRequest("createAddress", &user, res)
+ return res.Address, err
+}
+
+// ListAddresses returns all addresses on this chain controlled by [user]
+func (c *Client) ListAddresses(user api.UserPass) ([]string, error) {
+ res := &api.JSONAddresses{}
+ err := c.requester.SendRequest("listAddresses", &user, res)
+ return res.Addresses, err
+}
+
+// ExportKey returns the private key corresponding to [addr] controlled by [user]
+// in both Avalanche standard format and hex format
+func (c *Client) ExportKey(user api.UserPass, addr string) (string, string, error) {
+ res := &ExportKeyReply{}
+ err := c.requester.SendRequest("exportKey", &ExportKeyArgs{
+ UserPass: user,
+ Address: addr,
+ }, res)
+ return res.PrivateKey, res.PrivateKeyHex, err
+}
+
+// ImportKey imports [privateKey] to [user]
+func (c *Client) ImportKey(user api.UserPass, privateKey string) (string, error) {
+ res := &api.JSONAddress{}
+ err := c.requester.SendRequest("importKey", &ImportKeyArgs{
+ UserPass: user,
+ PrivateKey: privateKey,
+ }, res)
+ return res.Address, err
+}
+
+// Import sends an import transaction to import funds from [sourceChain] and
+// returns the ID of the newly created transaction
+func (c *Client) Import(user api.UserPass, to, sourceChain string) (ids.ID, error) {
+ res := &api.JSONTxID{}
+ err := c.requester.SendRequest("import", &ImportArgs{
+ UserPass: user,
+ To: to,
+ SourceChain: sourceChain,
+ }, res)
+ return res.TxID, err
+}
+
+// ExportAVAX sends AVAX from this chain to the address specified by [to].
+// Returns the ID of the newly created atomic transaction
+func (c *Client) ExportAVAX(
+ user api.UserPass,
+ amount uint64,
+ to string,
+) (ids.ID, error) {
+ return c.Export(user, amount, to, "AVAX")
+}
+
+// Export sends an asset from this chain to the P/C-Chain.
+// After this tx is accepted, the AVAX must be imported to the P/C-chain with an importTx.
+// Returns the ID of the newly created atomic transaction
+func (c *Client) Export(
+ user api.UserPass,
+ amount uint64,
+ to string,
+ assetID string,
+) (ids.ID, error) {
+ res := &api.JSONTxID{}
+ err := c.requester.SendRequest("export", &ExportArgs{
+ ExportAVAXArgs: ExportAVAXArgs{
+ UserPass: user,
+ Amount: cjson.Uint64(amount),
+ To: to,
+ },
+ AssetID: assetID,
+ }, res)
+ return res.TxID, err
+}
diff --git a/plugin/evm/export_tx.go b/plugin/evm/export_tx.go
index ed069d4..2735573 100644
--- a/plugin/evm/export_tx.go
+++ b/plugin/evm/export_tx.go
@@ -149,7 +149,7 @@ func (tx *UnsignedExportTx) Accept(ctx *snow.Context, _ database.Batch) error {
Out: out.Out,
}
- utxoBytes, err := Codec.Marshal(utxo)
+ utxoBytes, err := Codec.Marshal(codecVersion, utxo)
if err != nil {
return err
}
diff --git a/plugin/evm/import_tx.go b/plugin/evm/import_tx.go
index 23dbc5f..1ec394c 100644
--- a/plugin/evm/import_tx.go
+++ b/plugin/evm/import_tx.go
@@ -135,7 +135,7 @@ func (tx *UnsignedImportTx) SemanticVerify(
utxoBytes := allUTXOBytes[i]
utxo := &avax.UTXO{}
- if err := vm.codec.Unmarshal(utxoBytes, utxo); err != nil {
+ if _, err := vm.codec.Unmarshal(utxoBytes, utxo); err != nil {
return tempError{err}
}
diff --git a/plugin/evm/import_tx_test.go b/plugin/evm/import_tx_test.go
index 53b9494..973802a 100644
--- a/plugin/evm/import_tx_test.go
+++ b/plugin/evm/import_tx_test.go
@@ -153,7 +153,7 @@ func TestImportTxSemanticVerify(t *testing.T) {
},
},
}
- utxoBytes, err := vm.codec.Marshal(utxo)
+ utxoBytes, err := vm.codec.Marshal(codecVersion, utxo)
if err != nil {
t.Fatal(err)
}
@@ -312,7 +312,7 @@ func TestNewImportTx(t *testing.T) {
},
},
}
- utxoBytes, err := vm.codec.Marshal(utxo)
+ utxoBytes, err := vm.codec.Marshal(codecVersion, utxo)
if err != nil {
t.Fatal(err)
}
diff --git a/plugin/evm/service.go b/plugin/evm/service.go
index 49bb862..2bb06df 100644
--- a/plugin/evm/service.go
+++ b/plugin/evm/service.go
@@ -138,7 +138,11 @@ func (service *AvaxAPI) ExportKey(r *http.Request, args *ExportKeyArgs, reply *E
if err != nil {
return fmt.Errorf("problem retrieving private key: %w", err)
}
- reply.PrivateKey = constants.SecretKeyPrefix + formatting.CB58{Bytes: sk.Bytes()}.String()
+ encodedKey, err := formatting.Encode(formatting.CB58, sk.Bytes())
+ if err != nil {
+ return fmt.Errorf("problem encoding bytes as cb58: %w", err)
+ }
+ reply.PrivateKey = constants.SecretKeyPrefix + encodedKey
reply.PrivateKeyHex = hexutil.Encode(sk.Bytes())
return nil
}
@@ -158,13 +162,13 @@ func (service *AvaxAPI) ImportKey(r *http.Request, args *ImportKeyArgs, reply *a
}
trimmedPrivateKey := strings.TrimPrefix(args.PrivateKey, constants.SecretKeyPrefix)
- formattedPrivateKey := formatting.CB58{}
- if err := formattedPrivateKey.FromString(trimmedPrivateKey); err != nil {
+ pkBytes, err := formatting.Decode(formatting.CB58, trimmedPrivateKey)
+ if err != nil {
return fmt.Errorf("problem parsing private key: %w", err)
}
factory := crypto.FactorySECP256K1R{}
- skIntf, err := factory.ToPrivateKey(formattedPrivateKey.Bytes)
+ skIntf, err := factory.ToPrivateKey(pkBytes)
if err != nil {
return fmt.Errorf("problem parsing private key: %w", err)
}
@@ -315,49 +319,8 @@ func (service *AvaxAPI) Export(_ *http.Request, args *ExportArgs, response *api.
return service.vm.issueTx(tx)
}
-// Index is an address and an associated UTXO.
-// Marks a starting or stopping point when fetching UTXOs. Used for pagination.
-type Index struct {
- Address string `json:"address"` // The address as a string
- UTXO string `json:"utxo"` // The UTXO ID as a string
-}
-
-// GetUTXOsArgs are arguments for passing into GetUTXOs.
-// Gets the UTXOs that reference at least one address in [Addresses].
-// Returns at most [limit] addresses.
-// If specified, [SourceChain] is the chain where the atomic UTXOs were exported from. If not specified,
-// then GetUTXOs returns an error since the C Chain only has atomic UTXOs.
-// If [limit] == 0 or > [maxUTXOsToFetch], fetches up to [maxUTXOsToFetch].
-// [StartIndex] defines where to start fetching UTXOs (for pagination.)
-// UTXOs fetched are from addresses equal to or greater than [StartIndex.Address]
-// For address [StartIndex.Address], only UTXOs with IDs greater than [StartIndex.UTXO] will be returned.
-// If [StartIndex] is omitted, gets all UTXOs.
-// If GetUTXOs is called multiple times, with our without [StartIndex], it is not guaranteed
-// that returned UTXOs are unique. That is, the same UTXO may appear in the response of multiple calls.
-type GetUTXOsArgs struct {
- Addresses []string `json:"addresses"`
- SourceChain string `json:"sourceChain"`
- Limit json.Uint32 `json:"limit"`
- StartIndex Index `json:"startIndex"`
- Encoding string `json:"encoding"`
-}
-
-// GetUTXOsReply defines the GetUTXOs replies returned from the API
-type GetUTXOsReply struct {
- // Number of UTXOs returned
- NumFetched json.Uint64 `json:"numFetched"`
- // The UTXOs
- UTXOs []string `json:"utxos"`
- // The last UTXO that was returned, and the address it corresponds to.
- // Used for pagination. To get the rest of the UTXOs, call GetUTXOs
- // again and set [StartIndex] to this value.
- EndIndex Index `json:"endIndex"`
- // Encoding specifies the encoding format the UTXOs are returned in
- Encoding string `json:"encoding"`
-}
-
// GetUTXOs gets all utxos for passed in addresses
-func (service *AvaxAPI) GetUTXOs(r *http.Request, args *GetUTXOsArgs, reply *GetUTXOsReply) error {
+func (service *AvaxAPI) GetUTXOs(r *http.Request, args *api.GetUTXOsArgs, reply *api.GetUTXOsReply) error {
service.vm.ctx.Log.Info("EVM: GetUTXOs called for with %s", args.Addresses)
if len(args.Addresses) == 0 {
@@ -367,11 +330,6 @@ func (service *AvaxAPI) GetUTXOs(r *http.Request, args *GetUTXOsArgs, reply *Get
return fmt.Errorf("number of addresses given, %d, exceeds maximum, %d", len(args.Addresses), maxGetUTXOsAddrs)
}
- encoding, err := service.vm.encodingManager.GetEncoding(args.Encoding)
- if err != nil {
- return fmt.Errorf("problem getting encoding formatter for '%s': %w", args.Encoding, err)
- }
-
sourceChain := ids.ID{}
if args.SourceChain == "" {
return errNoSourceChain
@@ -418,11 +376,15 @@ func (service *AvaxAPI) GetUTXOs(r *http.Request, args *GetUTXOsArgs, reply *Get
reply.UTXOs = make([]string, len(utxos))
for i, utxo := range utxos {
- b, err := service.vm.codec.Marshal(utxo)
+ b, err := service.vm.codec.Marshal(codecVersion, utxo)
if err != nil {
return fmt.Errorf("problem marshalling UTXO: %w", err)
}
- reply.UTXOs[i] = encoding.ConvertBytes(b)
+ str, err := formatting.Encode(args.Encoding, b)
+ if err != nil {
+ return fmt.Errorf("problem encoding utxo: %w", err)
+ }
+ reply.UTXOs[i] = str
}
endAddress, err := service.vm.FormatLocalAddress(endAddr)
@@ -433,7 +395,7 @@ func (service *AvaxAPI) GetUTXOs(r *http.Request, args *GetUTXOsArgs, reply *Get
reply.EndIndex.Address = endAddress
reply.EndIndex.UTXO = endUTXOID.String()
reply.NumFetched = json.Uint64(len(utxos))
- reply.Encoding = encoding.Encoding()
+ reply.Encoding = args.Encoding
return nil
}
@@ -441,17 +403,13 @@ func (service *AvaxAPI) GetUTXOs(r *http.Request, args *GetUTXOsArgs, reply *Get
func (service *AvaxAPI) IssueTx(r *http.Request, args *api.FormattedTx, response *api.JSONTxID) error {
log.Info("EVM: IssueTx called")
- encoding, err := service.vm.encodingManager.GetEncoding(args.Encoding)
- if err != nil {
- return fmt.Errorf("problem getting encoding formatter for '%s': %w", args.Encoding, err)
- }
- txBytes, err := encoding.ConvertString(args.Tx)
+ txBytes, err := formatting.Decode(args.Encoding, args.Tx)
if err != nil {
return fmt.Errorf("problem decoding transaction: %w", err)
}
tx := &Tx{}
- if err := service.vm.codec.Unmarshal(txBytes, tx); err != nil {
+ if _, err := service.vm.codec.Unmarshal(txBytes, tx); err != nil {
return fmt.Errorf("problem parsing transaction: %w", err)
}
if err := tx.Sign(service.vm.codec, nil); err != nil {
diff --git a/plugin/evm/static_service.go b/plugin/evm/static_service.go
index 1e48734..1b45939 100644
--- a/plugin/evm/static_service.go
+++ b/plugin/evm/static_service.go
@@ -8,7 +8,6 @@ import (
"encoding/json"
"github.com/ava-labs/coreth/core"
- "github.com/ava-labs/avalanchego/utils/formatting"
)
// StaticService defines the static API services exposed by the evm
@@ -16,7 +15,7 @@ type StaticService struct{}
// BuildGenesis returns the UTXOs such that at least one address in [args.Addresses] is
// referenced in the UTXO.
-func (*StaticService) BuildGenesis(_ context.Context, args *core.Genesis) (formatting.CB58, error) {
+func (*StaticService) BuildGenesis(_ context.Context, args *core.Genesis) ([]byte, error) {
bytes, err := json.Marshal(args)
- return formatting.CB58{Bytes: bytes}, err
+ return bytes, err
}
diff --git a/plugin/evm/tx.go b/plugin/evm/tx.go
index 82d4c10..1c0ce48 100644
--- a/plugin/evm/tx.go
+++ b/plugin/evm/tx.go
@@ -89,8 +89,8 @@ type Tx struct {
// (*secp256k1fx.Credential)
// Sign this transaction with the provided signers
-func (tx *Tx) Sign(c codec.Codec, signers [][]*crypto.PrivateKeySECP256K1R) error {
- unsignedBytes, err := c.Marshal(&tx.UnsignedTx)
+func (tx *Tx) Sign(c codec.Manager, signers [][]*crypto.PrivateKeySECP256K1R) error {
+ unsignedBytes, err := c.Marshal(codecVersion, &tx.UnsignedTx)
if err != nil {
return fmt.Errorf("couldn't marshal UnsignedTx: %w", err)
}
@@ -111,7 +111,7 @@ func (tx *Tx) Sign(c codec.Codec, signers [][]*crypto.PrivateKeySECP256K1R) erro
tx.Creds = append(tx.Creds, cred) // Attach credential
}
- signedBytes, err := c.Marshal(tx)
+ signedBytes, err := c.Marshal(codecVersion, tx)
if err != nil {
return fmt.Errorf("couldn't marshal Tx: %w", err)
}
diff --git a/plugin/evm/user.go b/plugin/evm/user.go
index 0ab1863..fc4587e 100644
--- a/plugin/evm/user.go
+++ b/plugin/evm/user.go
@@ -48,7 +48,7 @@ func (u *user) getAddresses() ([]common.Address, error) {
return nil, err
}
addresses := []common.Address{}
- if err := Codec.Unmarshal(bytes, &addresses); err != nil {
+ if _, err := Codec.Unmarshal(bytes, &addresses); err != nil {
return nil, err
}
return addresses, nil
@@ -94,7 +94,7 @@ func (u *user) putAddress(privKey *crypto.PrivateKeySECP256K1R) error {
}
}
addresses = append(addresses, address)
- bytes, err := Codec.Marshal(addresses)
+ bytes, err := Codec.Marshal(codecVersion, addresses)
if err != nil {
return err
}
diff --git a/plugin/evm/vm.go b/plugin/evm/vm.go
index 284a772..aaf7f10 100644
--- a/plugin/evm/vm.go
+++ b/plugin/evm/vm.go
@@ -70,6 +70,7 @@ const (
batchSize = 250
maxUTXOsToFetch = 1024
blockCacheSize = 1 << 10 // 1024
+ codecVersion = uint16(0)
)
const (
@@ -110,26 +111,29 @@ func maxDuration(x, y time.Duration) time.Duration {
}
// Codec does serialization and deserialization
-var Codec codec.Codec
+var Codec codec.Manager
func init() {
- Codec = codec.NewDefault()
+ Codec = codec.NewDefaultManager()
+ c := codec.NewDefault()
errs := wrappers.Errs{}
errs.Add(
- Codec.RegisterType(&UnsignedImportTx{}),
- Codec.RegisterType(&UnsignedExportTx{}),
+ c.RegisterType(&UnsignedImportTx{}),
+ c.RegisterType(&UnsignedExportTx{}),
)
- Codec.Skip(3)
+ c.Skip(3)
errs.Add(
- Codec.RegisterType(&secp256k1fx.TransferInput{}),
- Codec.RegisterType(&secp256k1fx.MintOutput{}),
- Codec.RegisterType(&secp256k1fx.TransferOutput{}),
- Codec.RegisterType(&secp256k1fx.MintOperation{}),
- Codec.RegisterType(&secp256k1fx.Credential{}),
- Codec.RegisterType(&secp256k1fx.Input{}),
- Codec.RegisterType(&secp256k1fx.OutputOwners{}),
+ c.RegisterType(&secp256k1fx.TransferInput{}),
+ c.RegisterType(&secp256k1fx.MintOutput{}),
+ c.RegisterType(&secp256k1fx.TransferOutput{}),
+ c.RegisterType(&secp256k1fx.MintOperation{}),
+ c.RegisterType(&secp256k1fx.Credential{}),
+ c.RegisterType(&secp256k1fx.Input{}),
+ c.RegisterType(&secp256k1fx.OutputOwners{}),
)
+
+ errs.Add(Codec.RegisterCodec(0, c))
if errs.Errored() {
panic(errs.Err)
}
@@ -139,8 +143,7 @@ func init() {
type VM struct {
ctx *snow.Context
- CLIConfig CommandLineConfig
- encodingManager formatting.EncodingManager
+ CLIConfig CommandLineConfig
chainID *big.Int
networkID uint64
@@ -173,7 +176,8 @@ type VM struct {
txSubmitChan <-chan struct{}
atomicTxSubmitChan chan struct{}
shutdownSubmitChan chan struct{}
- codec codec.Codec
+ baseCodec codec.Codec
+ codec codec.Manager
clock timer.Clock
txFee uint64
pendingAtomicTxs chan *Tx
@@ -187,7 +191,7 @@ type VM struct {
func (vm *VM) getAtomicTx(block *types.Block) *Tx {
extdata := block.ExtraData()
atx := new(Tx)
- if err := vm.codec.Unmarshal(extdata, atx); err != nil {
+ if _, err := vm.codec.Unmarshal(extdata, atx); err != nil {
return nil
}
atx.Sign(vm.codec, nil)
@@ -195,7 +199,10 @@ func (vm *VM) getAtomicTx(block *types.Block) *Tx {
}
// Codec implements the secp256k1fx interface
-func (vm *VM) Codec() codec.Codec { return codec.NewDefault() }
+func (vm *VM) Codec() codec.Manager { return vm.codec }
+
+// CodecRegistry implements the secp256k1fx interface
+func (vm *VM) CodecRegistry() codec.Registry { return vm.baseCodec }
// Clock implements the secp256k1fx interface
func (vm *VM) Clock() *timer.Clock { return &vm.clock }
@@ -221,12 +228,6 @@ func (vm *VM) Initialize(
return vm.CLIConfig.ParsingError
}
- encodingManager, err := formatting.NewEncodingManager(formatting.CB58Encoding)
- if err != nil {
- return fmt.Errorf("problem creating encoding manager: %w", err)
- }
- vm.encodingManager = encodingManager
-
if len(fxs) > 0 {
return errUnsupportedFXs
}
@@ -284,7 +285,7 @@ func (vm *VM) Initialize(
vm.newBlockChan <- nil
return nil, err
}
- raw, _ := vm.codec.Marshal(atx)
+ raw, _ := vm.codec.Marshal(codecVersion, atx)
return raw, nil
default:
if len(txs) == 0 {
@@ -382,10 +383,14 @@ func (vm *VM) Initialize(
vm.genesisHash = chain.GetGenesisBlock().Hash()
log.Info(fmt.Sprintf("lastAccepted = %s", vm.lastAccepted.ethBlock.Hash().Hex()))
- // TODO: shutdown this go routine
vm.shutdownWg.Add(1)
go vm.ctx.Log.RecoverAndPanic(vm.awaitSubmittedTxs)
vm.codec = Codec
+ // The Codec explicitly registers the types it requires from the secp256k1fx
+ // so [vm.baseCodec] is a dummy codec use to fulfill the secp256k1fx VM
+ // interface. The fx will register all of its types, which can be safely
+ // ignored by the VM's codec.
+ vm.baseCodec = codec.NewDefault()
return vm.fx.Initialize(vm)
}
@@ -857,7 +862,7 @@ func (vm *VM) GetAtomicUTXOs(
utxos := make([]*avax.UTXO, len(allUTXOBytes))
for i, utxoBytes := range allUTXOBytes {
utxo := &avax.UTXO{}
- if err := vm.codec.Unmarshal(utxoBytes, utxo); err != nil {
+ if _, err := vm.codec.Unmarshal(utxoBytes, utxo); err != nil {
return nil, ids.ShortID{}, ids.ID{}, fmt.Errorf("error parsing UTXO: %w", err)
}
utxos[i] = utxo
diff --git a/plugin/evm/vm_test.go b/plugin/evm/vm_test.go
index 020b663..1b894ce 100644
--- a/plugin/evm/vm_test.go
+++ b/plugin/evm/vm_test.go
@@ -36,7 +36,7 @@ var (
)
func init() {
- cb58 := formatting.CB58{}
+ var b []byte
factory := crypto.FactorySECP256K1R{}
for _, key := range []string{
@@ -44,8 +44,8 @@ func init() {
"2MMvUMsxx6zsHSNXJdFD8yc5XkancvwyKPwpw4xUK3TCGDuNBY",
"cxb7KpGWhDMALTjNNSJ7UQkkomPesyWAPUaWRGdyeBNzR6f35",
} {
- _ = cb58.FromString(key)
- pk, _ := factory.ToPrivateKey(cb58.Bytes)
+ b, _ = formatting.Decode(formatting.CB58, key)
+ pk, _ := factory.ToPrivateKey(b)
secpKey := pk.(*crypto.PrivateKeySECP256K1R)
testKeys = append(testKeys, secpKey)
testEthAddrs = append(testEthAddrs, GetEthAddress(secpKey))
@@ -63,11 +63,11 @@ func BuildGenesisTest(t *testing.T) []byte {
if err := json.Unmarshal([]byte(genesisJSON), genesis); err != nil {
t.Fatalf("Problem unmarshaling genesis JSON: %s", err)
}
- genesisReply, err := ss.BuildGenesis(nil, genesis)
+ genesisBytes, err := ss.BuildGenesis(nil, genesis)
if err != nil {
t.Fatalf("Failed to create test genesis")
}
- return genesisReply.Bytes
+ return genesisBytes
}
func NewContext() *snow.Context {
@@ -102,7 +102,10 @@ func GenesisVM(t *testing.T, finishBootstrapping bool) (chan engCommon.Message,
// The caller of this function is responsible for unlocking.
ctx.Lock.Lock()
- userKeystore := keystore.CreateTestKeystore()
+ userKeystore, err := keystore.CreateTestKeystore()
+ if err != nil {
+ t.Fatal(err)
+ }
if err := userKeystore.AddUser(username, password); err != nil {
t.Fatal(err)
}
@@ -112,7 +115,7 @@ func GenesisVM(t *testing.T, finishBootstrapping bool) (chan engCommon.Message,
vm := &VM{
txFee: testTxFee,
}
- err := vm.Initialize(
+ err = vm.Initialize(
ctx,
prefixdb.New([]byte{1}, baseDB),
genesisBytes,
1339'>1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469