diff --git a/Makefile b/Makefile index 2bb3506b..385b872a 100644 --- a/Makefile +++ b/Makefile @@ -11,7 +11,7 @@ DOCKER_ORG ?= avaplatform DOCKER_IMAGE ?= ${DOCKER_ORG}/${PROJECT} DOCKER_LABEL ?= latest DOCKER_TAG ?= ${DOCKER_IMAGE}:${DOCKER_LABEL} -AVALANCHE_VERSION ?= v1.6.5 +AVALANCHE_VERSION ?= v1.7.0 build: go build -o ./rosetta-server ./cmd/server diff --git a/cmd/server/main.go b/cmd/server/main.go index 498cda21..808071ca 100644 --- a/cmd/server/main.go +++ b/cmd/server/main.go @@ -74,11 +74,14 @@ func main() { } var assetID string + var AP5Activation uint64 switch cfg.ChainID { case mapper.MainnetChainID: assetID = mapper.MainnetAssetID + AP5Activation = mapper.MainnetAP5Activation.Uint64() case mapper.FujiChainID: assetID = mapper.FujiAssetID + AP5Activation = mapper.FujiAP5Activation.Uint64() default: log.Fatal("invalid ChainID:", cfg.ChainID) } @@ -119,6 +122,7 @@ func main() { NetworkID: network, GenesisBlockHash: cfg.GenesisBlockHash, AvaxAssetID: assetID, + AP5Activation: AP5Activation, } handler := configureRouter(serviceConfig, asserter, apiClient) diff --git a/go.mod b/go.mod index 95eaee05..ff88f546 100644 --- a/go.mod +++ b/go.mod @@ -4,8 +4,8 @@ go 1.16 require ( github.com/StackExchange/wmi v0.0.0-20190523213315-cbe66965904d // indirect - github.com/ava-labs/avalanchego v1.6.5 - github.com/ava-labs/coreth v0.7.4-rc.1 + github.com/ava-labs/avalanchego v1.7.0 + github.com/ava-labs/coreth v0.8.0-rc.3 github.com/coinbase/rosetta-sdk-go v0.6.5 github.com/decred/dcrd/dcrec/secp256k1/v3 v3.0.0 // indirect github.com/ethereum/go-ethereum v1.10.12 diff --git a/go.sum b/go.sum index aec077c1..65f2e791 100644 --- a/go.sum +++ b/go.sum @@ -42,7 +42,6 @@ github.com/DataDog/zstd v1.4.1/go.mod h1:1jcaCB/ufaK+sKp1NBhlGmpz41jOoPQ35bpF36t github.com/DataDog/zstd v1.4.5/go.mod h1:1jcaCB/ufaK+sKp1NBhlGmpz41jOoPQ35bpF36t7BBo= github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0= github.com/Microsoft/go-winio v0.4.14/go.mod h1:qXqCSQ3Xa7+6tgxaGTIe4Kpcdsi+P8jBhyzoq1bpyYA= -github.com/NYTimes/gziphandler v1.1.1 h1:ZUDjpQae29j0ryrS0u/B8HZfJBtBQHjqw2rQ2cqUQ3I= github.com/NYTimes/gziphandler v1.1.1/go.mod h1:n/CVRwUEOgIxrgPvAQhUUr9oeUtvrhMomdKFjzJNB0c= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo= @@ -75,11 +74,11 @@ github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5 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/aryann/difflib v0.0.0-20170710044230-e206f873d14a/go.mod h1:DAHtR1m6lCRdSC2Tm3DSWRPvIPr6xNKyeHdqDQSQT+A= -github.com/ava-labs/avalanchego v1.6.4/go.mod h1:DzxlGkF8hj3GiwRoQfHq9gJfyt4EyeIpAsdfBOBg6mI= -github.com/ava-labs/avalanchego v1.6.5 h1:xzta2OGAjF7ka06Cl1IoB4jtrqhAuxjI1onVDGWwdsk= -github.com/ava-labs/avalanchego v1.6.5/go.mod h1:M21LNXMX5AcvUfQ0x1wKewOEgJjOcq8W08m3gmnGJAU= -github.com/ava-labs/coreth v0.7.4-rc.1 h1:d2UAV+f1Ku3Ngu//tctGH5c45g38sZh1Re47QNW/Xi8= -github.com/ava-labs/coreth v0.7.4-rc.1/go.mod h1:Tfx58OW7evspvjd69fM/cQ9UyPtYGTfUkGBsP5PtAK8= +github.com/ava-labs/avalanchego v1.6.6-0.20211122023205-994831adda9b/go.mod h1:jwfTpP+SB9AZVnHBuh3/d2WNbsIgGwUpqOfOgtEkelk= +github.com/ava-labs/avalanchego v1.7.0 h1:u9QuyXy1vYrUDqPrYD5+2Q5/OzUQMRIgcAq8Tuo02dA= +github.com/ava-labs/avalanchego v1.7.0/go.mod h1:jwfTpP+SB9AZVnHBuh3/d2WNbsIgGwUpqOfOgtEkelk= +github.com/ava-labs/coreth v0.8.0-rc.3 h1:5RLBY11Om1PEUQ71wtf+Qtut2uZRuj8+sIpB0Q/SfvE= +github.com/ava-labs/coreth v0.8.0-rc.3/go.mod h1:rxTZLwjo6dfyPRkf5WfLEFP3C6Tn21lCjjLUH5XqeqM= github.com/aws/aws-lambda-go v1.13.3/go.mod h1:4UKl9IzQMoD+QF79YdCuzCwp8VbmG4VAQwij/eHl5CU= github.com/aws/aws-sdk-go v1.25.48/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= github.com/aws/aws-sdk-go v1.27.0/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= @@ -327,7 +326,6 @@ github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+ github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg= -github.com/gorilla/handlers v1.4.2 h1:0QniY0USkHQ1RGCLfKxeNHK9bkDHGRYGNDFBCS+YARg= github.com/gorilla/handlers v1.4.2/go.mod h1:Qkdc/uu4tH4g6mTK6auzZ766c4CA0Ng8+o/OAirnOIQ= github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= github.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= @@ -632,7 +630,6 @@ github.com/rjeczalik/notify v0.9.2/go.mod h1:aErll2f0sUX9PXZnVNyeiObbmTlk5jnMoCa github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rs/cors v0.0.0-20160617231935-a62a804a8a00/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU= -github.com/rs/cors v1.7.0 h1:+88SsELBHx5r+hZ8TCkggzSstaWNbDvThkVK8H6f9ik= github.com/rs/cors v1.7.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU= github.com/rs/xhandler v0.0.0-20160618193221-ed27b6fd6521/go.mod h1:RvLn4FgxWubrpZHtQLnOf6EwhN2hEMusxZOhcW9H3UQ= github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= diff --git a/mapper/transaction.go b/mapper/transaction.go index 0594233b..79eba2e8 100644 --- a/mapper/transaction.go +++ b/mapper/transaction.go @@ -1,9 +1,9 @@ package mapper import ( + "fmt" "log" "math/big" - "reflect" "strings" ethtypes "github.com/ava-labs/coreth/core/types" @@ -77,25 +77,21 @@ func Transaction( }, nil } -func CrossChainTransactions( +func crossChainTransaction( + rawIdx int, avaxAssetID string, - block *ethtypes.Block, -) ([]*types.Transaction, error) { - transactions := []*types.Transaction{} - - extra := block.ExtData() - if len(extra) == 0 { - return transactions, nil + tx *evm.Tx, +) ([]*types.Operation, error) { + var ( + ops = []*types.Operation{} + idx = int64(rawIdx) + ) + + // Prepare transaction for ID calcuation + if err := tx.Sign(codecManager, nil); err != nil { + return nil, err } - tx := &evm.Tx{} - if _, err := codecManager.Unmarshal(extra, tx); err != nil { - return transactions, err - } - - var idx int64 - ops := []*types.Operation{} - switch t := tx.UnsignedAtomicTx.(type) { case *evm.UnsignedImportTx: // Create de-duplicated list of input @@ -130,6 +126,7 @@ func CrossChainTransactions( Currency: AvaxCurrency, }, Metadata: map[string]interface{}{ + "tx": t.ID().String(), "tx_ids": txIDs, "blockchain_id": t.BlockchainID.String(), "network_id": t.NetworkID, @@ -161,6 +158,7 @@ func CrossChainTransactions( Currency: AvaxCurrency, }, Metadata: map[string]interface{}{ + "tx": t.ID().String(), "blockchain_id": t.BlockchainID.String(), "network_id": t.NetworkID, "destination_chain": t.DestinationChain.String(), @@ -172,9 +170,53 @@ func CrossChainTransactions( idx++ } default: - panic("Unsupported transaction:" + reflect.TypeOf(t).String()) + return nil, fmt.Errorf("Unsupported transaction: %T", t) + } + return ops, nil +} + +func CrossChainTransactions( + avaxAssetID string, + block *ethtypes.Block, + ap5Activation uint64, +) ([]*types.Transaction, error) { + transactions := []*types.Transaction{} + + extra := block.ExtData() + if len(extra) == 0 { + return transactions, nil + } + + // Initialize Atomic Transactions + var atomicTxs []*evm.Tx + if block.Time() < ap5Activation { + // Prior to Apricot Phase 5, there was only one atomic transaction per + // block. + tx := new(evm.Tx) + if _, err := codecManager.Unmarshal(extra, tx); err != nil { + return nil, err + } + atomicTxs = []*evm.Tx{tx} + } else { + if _, err := codecManager.Unmarshal(extra, &atomicTxs); err != nil { + return nil, fmt.Errorf("failed to unmarshal atomic tx (AP5) due to %w", err) + } + } + + ops := []*types.Operation{} + for _, tx := range atomicTxs { + txOps, err := crossChainTransaction(len(ops), avaxAssetID, tx) + if err != nil { + return nil, err + } + ops = append(ops, txOps...) } + // TODO: migrate to using atomic transaction ID instead of marking as a block + // transaction + // + // NOTE: We need to be very careful about this because it will require + // integrators to re-index the chain to get the new result. transactions = append(transactions, &types.Transaction{ TransactionIdentifier: &types.TransactionIdentifier{ Hash: block.Hash().String(), diff --git a/mapper/types.go b/mapper/types.go index ae62fa7f..98859068 100644 --- a/mapper/types.go +++ b/mapper/types.go @@ -1,6 +1,8 @@ package mapper import ( + "github.com/ava-labs/coreth/params" + "github.com/coinbase/rosetta-sdk-go/types" ) @@ -28,6 +30,9 @@ const ( ) var ( + MainnetAP5Activation = params.AvalancheMainnetChainConfig.ApricotPhase5BlockTimestamp + FujiAP5Activation = params.AvalancheFujiChainConfig.ApricotPhase5BlockTimestamp + StageBootstrap = &types.SyncStatus{ Synced: types.Bool(false), Stage: types.String("BOOTSTRAP"), diff --git a/service/config.go b/service/config.go index 6e685b9b..95362cab 100644 --- a/service/config.go +++ b/service/config.go @@ -14,6 +14,9 @@ type Config struct { NetworkID *types.NetworkIdentifier GenesisBlockHash string AvaxAssetID string + + // Upgrade Times + AP5Activation uint64 } const ( diff --git a/service/rosetta.go b/service/rosetta.go index c898c9af..4c23af8b 100644 --- a/service/rosetta.go +++ b/service/rosetta.go @@ -1,7 +1,7 @@ package service const ( - NodeVersion = "1.6.5" - MiddlewareVersion = "0.0.19" + NodeVersion = "1.7.0" + MiddlewareVersion = "0.0.20" BlockchainName = "Avalanche" ) diff --git a/service/service_block.go b/service/service_block.go index 39e8fe6c..3fe3bd14 100644 --- a/service/service_block.go +++ b/service/service_block.go @@ -200,7 +200,7 @@ func (s *BlockService) parseCrossChainTransactions( ) ([]*types.Transaction, *types.Error) { result := []*types.Transaction{} - crossTxs, err := mapper.CrossChainTransactions(s.config.AvaxAssetID, block) + crossTxs, err := mapper.CrossChainTransactions(s.config.AvaxAssetID, block, s.config.AP5Activation) if err != nil { return nil, wrapError(errInternalError, err) }