diff --git a/.github/workflows/full_test.yml b/.github/workflows/full_test.yml index add285e1b..fbe6132c3 100644 --- a/.github/workflows/full_test.yml +++ b/.github/workflows/full_test.yml @@ -10,9 +10,6 @@ on: - opened - reopened - synchronize - pull_request_target: - types: - - edited push: branches: - master @@ -49,7 +46,7 @@ jobs: env: CC_TEST_REPORTER_ID: ${{secrets.CC_TEST_REPORTER_ID}} with: - coverageCommand: go test -timeout 999s -coverprofile build/c.out -v ./... + coverageCommand: go test -timeout 999s -coverprofile build/c.out ./... prefix: github.com/aergoio/aergo/v2 coverageLocations: ${{github.workspace}}/build/c.out:gocov debug: true @@ -57,13 +54,16 @@ jobs: # run unit test only in other cases - name: Unit Tests if: github.event_name != 'push' || github.ref_name != 'master' || github.ref_type != 'branch' - run: go test -timeout 999s -v ./... + run: go test -timeout 999s ./... - - name: Integration Tests - run: | - if [ -d "tests" ]; then - cd tests - ./run_tests.sh - else - echo "The 'tests' folder does not exist." - fi + - name: Integration Tests - brick + run: cd tests && ./run_tests.sh brick + + - name: Integration Tests - sbp + run: cd tests && ./run_tests.sh sbp + + - name: Integration Tests - dpos + run: cd tests && ./run_tests.sh dpos + + - name: Integration Tests - raft + run: cd tests && ./run_tests.sh raft diff --git a/.github/workflows/manual_test.yml b/.github/workflows/manual_test.yml index e126768d2..38d09e716 100644 --- a/.github/workflows/manual_test.yml +++ b/.github/workflows/manual_test.yml @@ -30,4 +30,4 @@ jobs: run: make - name: Unit Tests - run: go test -timeout 999s -v ./... + run: go test -timeout 999s ./... diff --git a/README.md b/README.md index 46aa84113..c5c5551ee 100644 --- a/README.md +++ b/README.md @@ -114,7 +114,7 @@ MVP based, Forward compatibility, Iteration ### Prerequisites -* Go1.12.5+ - https://golang.org/dl +* Go1.19.1+ - https://golang.org/dl * Proto Buffers - https://github.com/google/protobuf * CMake 3.0.0 or higher - https://cmake.org diff --git a/account/key/crypto/v1strategy.go b/account/key/crypto/v1strategy.go index 6e6c2d9e4..d4a8a32ac 100644 --- a/account/key/crypto/v1strategy.go +++ b/account/key/crypto/v1strategy.go @@ -10,12 +10,12 @@ import ( "crypto/cipher" "crypto/rand" "crypto/sha256" - "encoding/hex" "encoding/json" "errors" "io" "reflect" + "github.com/aergoio/aergo/v2/internal/enc/hex" "github.com/aergoio/aergo/v2/types" "github.com/btcsuite/btcd/btcec" "golang.org/x/crypto/scrypt" @@ -105,9 +105,9 @@ func (ks *v1Strategy) Encrypt(key *PrivateKey, passphrase string) ([]byte, error cipher := v1CipherJSON{ Algorithm: cipherAlgorithm, Params: v1CipherParamsJSON{ - Iv: hex.EncodeToString(iv), + Iv: hex.Encode(iv), }, - Ciphertext: hex.EncodeToString(ciphertext), + Ciphertext: hex.Encode(ciphertext), } // json: kdf kdf := v1KdfJson{ @@ -117,9 +117,9 @@ func (ks *v1Strategy) Encrypt(key *PrivateKey, passphrase string) ([]byte, error N: scryptN, P: scryptP, R: scryptR, - Salt: hex.EncodeToString(salt), + Salt: hex.Encode(salt), }, - Mac: hex.EncodeToString(mac), + Mac: hex.Encode(mac), } rawAddress := GenerateAddress(&(key.ToECDSA().PublicKey)) encodedAddress := types.EncodeAddress(rawAddress) @@ -155,11 +155,11 @@ func (ks *v1Strategy) Decrypt(encrypted []byte, passphrase string) (*PrivateKey, } // check mac - mac, err := hex.DecodeString(kdf.Mac) + mac, err := hex.Decode(kdf.Mac) if nil != err { return nil, err } - cipherText, err := hex.DecodeString(cipher.Ciphertext) + cipherText, err := hex.Decode(cipher.Ciphertext) if nil != err { return nil, err } @@ -170,7 +170,7 @@ func (ks *v1Strategy) Decrypt(encrypted []byte, passphrase string) (*PrivateKey, // decrypt decryptKey := derivedKey[:16] - iv, err := hex.DecodeString(cipher.Params.Iv) + iv, err := hex.Decode(cipher.Params.Iv) if nil != err { return nil, err } @@ -207,7 +207,7 @@ func checkKeyFormat(keyFormat *v1KeyStoreFormat) error { } func deriveCipherKey(passphrase []byte, kdf v1KdfJson) ([]byte, error) { - salt, err := hex.DecodeString(kdf.Params.Salt) + salt, err := hex.Decode(kdf.Params.Salt) if err != nil { return nil, err } diff --git a/chain/blockvalidator.go b/chain/blockvalidator.go index 3fa07fb91..42c795042 100644 --- a/chain/blockvalidator.go +++ b/chain/blockvalidator.go @@ -10,7 +10,7 @@ import ( "errors" "fmt" - "github.com/aergoio/aergo/v2/internal/enc" + "github.com/aergoio/aergo/v2/internal/enc/base58" "github.com/aergoio/aergo/v2/pkg/component" "github.com/aergoio/aergo/v2/state" "github.com/aergoio/aergo/v2/types" @@ -90,7 +90,7 @@ func (t validateReport) toString() string { result = "failed" } - msgStr = fmt.Sprintf("%s : %s. block= %s, computed=%s", t.name, result, enc.ToString(t.src), enc.ToString(t.target)) + msgStr = fmt.Sprintf("%s : %s. block= %s, computed=%s", t.name, result, base58.Encode(t.src), base58.Encode(t.target)) return msgStr } @@ -99,7 +99,7 @@ func (bv *BlockValidator) ValidateBody(block *types.Block) error { txs := block.GetBody().GetTxs() // TxRootHash - logger.Debug().Int("Txlen", len(txs)).Str("TxRoot", enc.ToString(block.GetHeader().GetTxsRootHash())). + logger.Debug().Int("Txlen", len(txs)).Str("TxRoot", base58.Encode(block.GetHeader().GetTxsRootHash())). Msg("tx root verify") hdrRootHash := block.GetHeader().GetTxsRootHash() @@ -112,8 +112,8 @@ func (bv *BlockValidator) ValidateBody(block *types.Block) error { if !ret { logger.Error().Str("block", block.ID()). - Str("txroot", enc.ToString(hdrRootHash)). - Str("compute txroot", enc.ToString(computeTxRootHash)). + Str("txroot", base58.Encode(hdrRootHash)). + Str("compute txroot", base58.Encode(computeTxRootHash)). Msg("tx root validation failed") return ErrorBlockVerifyTxRoot @@ -160,13 +160,13 @@ func (bv *BlockValidator) ValidatePost(sdbRoot []byte, receipts *types.Receipts, } if !ret { logger.Error().Str("block", block.ID()). - Str("hdrroot", enc.ToString(hdrRoot)). - Str("sdbroot", enc.ToString(sdbRoot)). + Str("hdrroot", base58.Encode(hdrRoot)). + Str("sdbroot", base58.Encode(sdbRoot)). Msg("block root hash validation failed") return ErrorBlockVerifyStateRoot } - logger.Debug().Str("sdbroot", enc.ToString(sdbRoot)). + logger.Debug().Str("sdbroot", base58.Encode(sdbRoot)). Msg("block root hash validation succeed") hdrRoot = block.GetHeader().ReceiptsRootHash @@ -177,12 +177,12 @@ func (bv *BlockValidator) ValidatePost(sdbRoot []byte, receipts *types.Receipts, bv.report(validateReport{name: "Verify receipt merkle root", pass: ret, src: hdrRoot, target: receiptsRoot}) } else if !ret { logger.Error().Str("block", block.ID()). - Str("hdrroot", enc.ToString(hdrRoot)). - Str("receipts_root", enc.ToString(receiptsRoot)). + Str("hdrroot", base58.Encode(hdrRoot)). + Str("receipts_root", base58.Encode(receiptsRoot)). Msg("receipts root hash validation failed") return ErrorBlockVerifyReceiptRoot } - logger.Debug().Str("receipts_root", enc.ToString(receiptsRoot)). + logger.Debug().Str("receipts_root", base58.Encode(receiptsRoot)). Msg("receipt root hash validation succeed") return nil diff --git a/chain/chainanchor.go b/chain/chainanchor.go index a29455879..b252dfe23 100644 --- a/chain/chainanchor.go +++ b/chain/chainanchor.go @@ -6,7 +6,7 @@ package chain import ( - "github.com/aergoio/aergo/v2/internal/enc" + "github.com/aergoio/aergo/v2/internal/enc/base58" "github.com/aergoio/aergo/v2/types" ) @@ -72,7 +72,7 @@ func (cs *ChainService) getAnchorsFromHash(blockHash []byte) ChainAnchor { return nil } - logger.Debug().Uint64("no", latestNo).Str("hash", enc.ToString(blockHash)).Msg("anchor") + logger.Debug().Uint64("no", latestNo).Str("hash", base58.Encode(blockHash)).Msg("anchor") anchors = append(anchors, blockHash) if latestNo == 0 { @@ -91,7 +91,7 @@ func (cs *ChainService) getAnchorsFromHash(blockHash []byte) ChainAnchor { return nil } - logger.Debug().Uint64("no", latestNo).Str("hash", enc.ToString(blockHash)).Msg("anchor") + logger.Debug().Uint64("no", latestNo).Str("hash", base58.Encode(blockHash)).Msg("anchor") anchors = append(anchors, blockHash) if latestNo <= dec { diff --git a/chain/chaindb.go b/chain/chaindb.go index efd4e36b7..52b50495c 100644 --- a/chain/chaindb.go +++ b/chain/chaindb.go @@ -7,8 +7,6 @@ package chain import ( "bytes" - "encoding/binary" - "encoding/gob" "encoding/json" "errors" "fmt" @@ -18,15 +16,11 @@ import ( "github.com/aergoio/aergo/v2/config" "github.com/aergoio/aergo/v2/consensus" "github.com/aergoio/aergo/v2/internal/common" - "github.com/aergoio/aergo/v2/internal/enc" + "github.com/aergoio/aergo/v2/internal/enc/base58" + "github.com/aergoio/aergo/v2/internal/enc/gob" + "github.com/aergoio/aergo/v2/internal/enc/proto" "github.com/aergoio/aergo/v2/types" - "github.com/golang/protobuf/proto" -) - -const ( - chainDBName = "chain" - genesisKey = chainDBName + ".genesisInfo" - genesisBalanceKey = chainDBName + ".genesisBalance" + "github.com/aergoio/aergo/v2/types/dbkey" ) var ( @@ -41,21 +35,6 @@ var ( ErrInvalidCCProgress = errors.New("invalid conf change progress") ) -var ( - latestKey = []byte(chainDBName + ".latest") - receiptsPrefix = []byte("r") - - raftIdentityKey = []byte("r_identity") - raftStateKey = []byte("r_state") - raftSnapKey = []byte("r_snap") - raftEntryLastIdxKey = []byte("r_last") - raftEntryPrefix = []byte("r_entry.") - raftEntryInvertPrefix = []byte("r_inv.") - raftConfChangeProgressPrefix = []byte("r_ccstatus.") - - hardforkKey = []byte("hardfork") -) - // ErrNoBlock reports there is no such a block with id (hash or block number). type ErrNoBlock struct { id interface{} @@ -66,7 +45,7 @@ func (e ErrNoBlock) Error() string { switch id := e.id.(type) { case []byte: - idStr = fmt.Sprintf("blockHash=%v", enc.ToString(id)) + idStr = fmt.Sprintf("blockHash=%v", base58.Encode(id)) default: idStr = fmt.Sprintf("blockNo=%v", id) } @@ -101,7 +80,7 @@ func (cdb *ChainDB) NewTx() db.Transaction { func (cdb *ChainDB) Init(dbType string, dataDir string) error { if cdb.store == nil { logger.Info().Str("datadir", dataDir).Msg("chain database initialized") - dbPath := common.PathMkdirAll(dataDir, chainDBName) + dbPath := common.PathMkdirAll(dataDir, dbkey.ChainDBName) cdb.store = db.NewDB(db.ImplType(dbType), dbPath) } @@ -236,7 +215,7 @@ func (cdb *ChainDB) GetBestBlock() (*types.Block, error) { } func (cdb *ChainDB) loadChainData() error { - latestBytes := cdb.store.Get(latestKey) + latestBytes := cdb.store.Get(dbkey.LatestBlock()) if latestBytes == nil || len(latestBytes) == 0 { return nil } @@ -295,7 +274,7 @@ func (cdb *ChainDB) loadData(key []byte, pb proto.Message) error { return fmt.Errorf("failed to load data: key=%v", key) } //logger.Debugf(" loadData: key=%d, len=%d, val=%s\n", Btoi(key), len(buf), enc.ToString(buf)) - err := proto.Unmarshal(buf, pb) + err := proto.Decode(buf, pb) if err != nil { return fmt.Errorf("failed to unmarshal: key=%v, len=%d", key, len(buf)) } @@ -313,9 +292,9 @@ func (cdb *ChainDB) addGenesisBlock(genesis *types.Genesis) error { } cdb.connectToChain(tx, block, false) - tx.Set([]byte(genesisKey), genesis.Bytes()) + tx.Set(dbkey.Genesis(), genesis.Bytes()) if totalBalance := genesis.TotalBalance(); totalBalance != nil { - tx.Set([]byte(genesisBalanceKey), totalBalance.Bytes()) + tx.Set(dbkey.GenesisBalance(), totalBalance.Bytes()) } tx.Commit() @@ -329,7 +308,7 @@ func (cdb *ChainDB) addGenesisBlock(genesis *types.Genesis) error { // GetGenesisInfo returns Genesis info, which is read from cdb. func (cdb *ChainDB) GetGenesisInfo() *types.Genesis { - if b := cdb.Get([]byte(genesisKey)); len(b) != 0 { + if b := cdb.Get(dbkey.Genesis()); len(b) != 0 { genesis := types.GetGenesisFromBytes(b) if block, err := cdb.GetBlockByNo(0); err == nil { genesis.SetBlock(block) @@ -348,7 +327,7 @@ func (cdb *ChainDB) GetGenesisInfo() *types.Genesis { } - if v := cdb.Get([]byte(genesisBalanceKey)); len(v) != 0 { + if v := cdb.Get(dbkey.GenesisBalance()); len(v) != 0 { genesis.SetTotalBalance(v) } @@ -380,7 +359,7 @@ func (cdb *ChainDB) connectToChain(dbtx db.Transaction, block *types.Block, skip } // Update best block hash - dbtx.Set(latestKey, blockIdx) + dbtx.Set(dbkey.LatestBlock(), blockIdx) dbtx.Set(blockIdx, block.BlockHash()) // Save the last consensus status. @@ -420,7 +399,7 @@ func (cdb *ChainDB) swapChainMapping(newBlocks []*types.Block) error { bulk.Set(blockIdx, block.BlockHash()) } - bulk.Set(latestKey, blockIdx) + bulk.Set(dbkey.LatestBlock(), blockIdx) // Save the last consensus status. cdb.cc.Save(bulk) @@ -466,7 +445,7 @@ func (cdb *ChainDB) addTxsOfBlock(dbTx *db.Transaction, txs []*types.Tx, blockHa for i, txEntry := range txs { if err := cdb.addTx(dbTx, txEntry, blockHash, i); err != nil { - logger.Error().Err(err).Str("hash", enc.ToString(blockHash)).Int("txidx", i). + logger.Error().Err(err).Str("hash", base58.Encode(blockHash)).Int("txidx", i). Msg("failed to add tx") return err @@ -482,7 +461,7 @@ func (cdb *ChainDB) addTx(dbtx *db.Transaction, tx *types.Tx, blockHash []byte, BlockHash: blockHash, Idx: int32(idx), } - txidxbytes, err := proto.Marshal(&txidx) + txidxbytes, err := proto.Encode(&txidx) if err != nil { return err } @@ -507,7 +486,7 @@ func (cdb *ChainDB) addBlock(dbtx db.Transaction, block *types.Block) error { // assumption: not an orphan // fork can be here logger.Debug().Uint64("blockNo", blockNo).Msg("add block to db") - blockBytes, err := proto.Marshal(block) + blockBytes, err := proto.Encode(block) if err != nil { logger.Error().Err(err).Uint64("no", blockNo).Str("hash", block.ID()).Msg("failed to add block") return err @@ -552,7 +531,7 @@ func (cdb *ChainDB) dropBlock(dropNo types.BlockNo) error { dbTx.Delete(dropIdx) // update latest - dbTx.Set(latestKey, newLatestIdx) + dbTx.Set(dbkey.LatestBlock(), newLatestIdx) dbTx.Commit() @@ -632,7 +611,7 @@ func (cdb *ChainDB) getTx(txHash []byte) (*types.Tx, *types.TxIdx, error) { err := cdb.loadData(txHash, txIdx) if err != nil { - return nil, nil, fmt.Errorf("tx not found: txHash=%v", enc.ToString(txHash)) + return nil, nil, fmt.Errorf("tx not found: txHash=%v", base58.Encode(txHash)) } block, err := cdb.getBlock(txIdx.BlockHash) if err != nil { @@ -643,7 +622,7 @@ func (cdb *ChainDB) getTx(txHash []byte) (*types.Tx, *types.TxIdx, error) { return nil, nil, fmt.Errorf("wrong tx idx: %d", txIdx.Idx) } tx := txs[txIdx.Idx] - logger.Debug().Str("hash", enc.ToString(txHash)).Msg("getTx") + logger.Debug().Str("hash", base58.Encode(txHash)).Msg("getTx") return tx, txIdx, nil } @@ -666,23 +645,20 @@ func (cdb *ChainDB) getReceipt(blockHash []byte, blockNo types.BlockNo, idx int3 func (cdb *ChainDB) getReceipts(blockHash []byte, blockNo types.BlockNo, hardForkConfig *config.HardforkConfig) (*types.Receipts, error) { - data := cdb.store.Get(receiptsKey(blockHash, blockNo)) + data := cdb.store.Get(dbkey.Receipts(blockHash, blockNo)) if len(data) == 0 { return nil, errors.New("cannot find a receipt") } - var b bytes.Buffer - b.Write(data) var receipts types.Receipts receipts.SetHardFork(hardForkConfig, blockNo) - decoder := gob.NewDecoder(&b) - err := decoder.Decode(&receipts) + err := gob.Decode(data, &receipts) return &receipts, err } func (cdb *ChainDB) checkExistReceipts(blockHash []byte, blockNo types.BlockNo) bool { - data := cdb.store.Get(receiptsKey(blockHash, blockNo)) + data := cdb.store.Get(dbkey.Receipts(blockHash, blockNo)) if len(data) == 0 { return false } @@ -704,9 +680,9 @@ func (cdb *ChainDB) GetChainTree() ([]byte, error) { hash, _ := cdb.getHashByNo(i) tree = append(tree, ChainInfo{ Height: i, - Hash: enc.ToString(hash), + Hash: base58.Encode(hash), }) - logger.Info().Str("hash", enc.ToString(hash)).Msg("GetChainTree") + logger.Info().Str("hash", base58.Encode(hash)).Msg("GetChainTree") } jsonBytes, err := json.Marshal(tree) if err != nil { @@ -719,27 +695,14 @@ func (cdb *ChainDB) writeReceipts(blockHash []byte, blockNo types.BlockNo, recei dbTx := cdb.store.NewTx() defer dbTx.Discard() - var val bytes.Buffer - gobEncoder := gob.NewEncoder(&val) - gobEncoder.Encode(receipts) - - dbTx.Set(receiptsKey(blockHash, blockNo), val.Bytes()) + val, _ := gob.Encode(receipts) + dbTx.Set(dbkey.Receipts(blockHash, blockNo), val) dbTx.Commit() } func (cdb *ChainDB) deleteReceipts(dbTx *db.Transaction, blockHash []byte, blockNo types.BlockNo) { - (*dbTx).Delete(receiptsKey(blockHash, blockNo)) -} - -func receiptsKey(blockHash []byte, blockNo types.BlockNo) []byte { - var key bytes.Buffer - key.Write(receiptsPrefix) - key.Write(blockHash) - l := make([]byte, 8) - binary.LittleEndian.PutUint64(l[:], blockNo) - key.Write(l) - return key.Bytes() + (*dbTx).Delete(dbkey.Receipts(blockHash, blockNo)) } func (cdb *ChainDB) writeReorgMarker(marker *ReorgMarker) error { @@ -752,7 +715,7 @@ func (cdb *ChainDB) writeReorgMarker(marker *ReorgMarker) error { return err } - dbTx.Set(reorgKey, val) + dbTx.Set(dbkey.ReOrg(), val) dbTx.Commit() return nil @@ -762,22 +725,19 @@ func (cdb *ChainDB) deleteReorgMarker() { dbTx := cdb.store.NewTx() defer dbTx.Discard() - dbTx.Delete(reorgKey) + dbTx.Delete(dbkey.ReOrg()) dbTx.Commit() } func (cdb *ChainDB) getReorgMarker() (*ReorgMarker, error) { - data := cdb.store.Get(reorgKey) + data := cdb.store.Get(dbkey.ReOrg()) if len(data) == 0 { return nil, nil } var marker ReorgMarker - var b bytes.Buffer - b.Write(data) - decoder := gob.NewDecoder(&b) - err := decoder.Decode(&marker) + err := gob.Decode(data, &marker) return &marker, err } @@ -790,7 +750,7 @@ func (cdb *ChainDB) IsNew() bool { func (cdb *ChainDB) Hardfork(hConfig config.HardforkConfig) config.HardforkDbConfig { var c config.HardforkDbConfig - data := cdb.store.Get(hardforkKey) + data := cdb.store.Get(dbkey.HardFork()) if len(data) == 0 { return c } @@ -808,6 +768,6 @@ func (cdb *ChainDB) WriteHardfork(c *config.HardforkConfig) error { if err != nil { return err } - cdb.store.Set(hardforkKey, data) + cdb.store.Set(dbkey.HardFork(), data) return nil } diff --git a/chain/chaindbForRaft.go b/chain/chaindbForRaft.go index a43949745..5f18f18ed 100644 --- a/chain/chaindbForRaft.go +++ b/chain/chaindbForRaft.go @@ -1,16 +1,15 @@ package chain import ( - "bytes" - "encoding/binary" - "encoding/gob" "errors" "github.com/aergoio/aergo-lib/db" "github.com/aergoio/aergo/v2/consensus" + "github.com/aergoio/aergo/v2/internal/enc/gob" + "github.com/aergoio/aergo/v2/internal/enc/proto" "github.com/aergoio/aergo/v2/types" + "github.com/aergoio/aergo/v2/types/dbkey" "github.com/aergoio/etcd/raft/raftpb" - "github.com/golang/protobuf/proto" ) var ( @@ -86,10 +85,10 @@ func (cdb *ChainDB) ClearWAL() { defer bulk.DiscardLast() for i := lastIdx; i >= 1; i-- { - bulk.Delete(getRaftEntryKey(i)) + bulk.Delete(dbkey.RaftEntry(i)) } - bulk.Delete(raftEntryLastIdxKey) + bulk.Delete(dbkey.RaftEntryLastIdx()) bulk.Flush() } @@ -97,13 +96,13 @@ func (cdb *ChainDB) ClearWAL() { dbTx := cdb.store.NewTx() defer dbTx.Discard() - dbTx.Delete(raftIdentityKey) + dbTx.Delete(dbkey.RaftIdentity()) // remove hardstate - dbTx.Delete(raftStateKey) + dbTx.Delete(dbkey.RaftState()) // remove snapshot - dbTx.Delete(raftSnapKey) + dbTx.Delete(dbkey.RaftSnap()) logger.Debug().Msg("reset identify, hardstate, snapshot from datafiles") @@ -127,24 +126,24 @@ func (cdb *ChainDB) WriteHardState(hardstate *raftpb.HardState) error { logger.Info().Uint64("term", hardstate.Term).Str("vote", types.Uint64ToHexaString(hardstate.Vote)).Uint64("commit", hardstate.Commit).Msg("save hard state") - if data, err = proto.Marshal(hardstate); err != nil { + if data, err = proto.Encode(hardstate); err != nil { logger.Panic().Msg("failed to marshal raft state") } - dbTx.Set(raftStateKey, data) + dbTx.Set(dbkey.RaftState(), data) dbTx.Commit() return nil } func (cdb *ChainDB) GetHardState() (*raftpb.HardState, error) { - data := cdb.store.Get(raftStateKey) + data := cdb.store.Get(dbkey.RaftState()) if len(data) == 0 { return nil, ErrWalNoHardState } state := &raftpb.HardState{} - if err := proto.Unmarshal(data, state); err != nil { + if err := proto.Decode(data, state); err != nil { logger.Panic().Msg("failed to unmarshal raft state") } @@ -153,22 +152,6 @@ func (cdb *ChainDB) GetHardState() (*raftpb.HardState, error) { return state, nil } -func getRaftEntryKey(idx uint64) []byte { - var key bytes.Buffer - key.Write(raftEntryPrefix) - l := make([]byte, 8) - binary.LittleEndian.PutUint64(l[:], idx) - key.Write(l) - return key.Bytes() -} - -func getRaftEntryInvertKey(blockHash []byte) []byte { - var key bytes.Buffer - key.Write(raftEntryInvertPrefix) - key.Write(blockHash) - return key.Bytes() -} - func (cdb *ChainDB) WriteRaftEntry(ents []*consensus.WalEntry, blocks []*types.Block, ccProposes []*raftpb.ConfChange) error { var data []byte var err error @@ -188,7 +171,7 @@ func (cdb *ChainDB) WriteRaftEntry(ents []*consensus.WalEntry, blocks []*types.B for i := ents[0].Index; i <= last; i++ { // delete ents[0].Index ~ lastIndex of wal - dbTx.Delete(getRaftEntryKey(i)) + dbTx.Delete(dbkey.RaftEntry(i)) } } @@ -208,11 +191,11 @@ func (cdb *ChainDB) WriteRaftEntry(ents []*consensus.WalEntry, blocks []*types.B } lastIdx = entry.Index - dbTx.Set(getRaftEntryKey(entry.Index), data) + dbTx.Set(dbkey.RaftEntry(entry.Index), data) // invert key to search raft entry corresponding to block hash if entry.Type == consensus.EntryBlock { - dbTx.Set(getRaftEntryInvertKey(blocks[i].BlockHash()), types.Uint64ToBytes(entry.Index)) + dbTx.Set(dbkey.RaftEntryInvert(blocks[i].BlockHash()), types.Uint64ToBytes(entry.Index)) } if entry.Type == consensus.EntryConfChange { @@ -241,20 +224,17 @@ func (cdb *ChainDB) WriteRaftEntry(ents []*consensus.WalEntry, blocks []*types.B func (cdb *ChainDB) writeRaftEntryLastIndex(dbTx db.Transaction, lastIdx uint64) { logger.Debug().Uint64("index", lastIdx).Msg("set last wal entry") - dbTx.Set(raftEntryLastIdxKey, types.BlockNoToBytes(lastIdx)) + dbTx.Set(dbkey.RaftEntryLastIdx(), types.BlockNoToBytes(lastIdx)) } func (cdb *ChainDB) GetRaftEntry(idx uint64) (*consensus.WalEntry, error) { - data := cdb.store.Get(getRaftEntryKey(idx)) + data := cdb.store.Get(dbkey.RaftEntry(idx)) if len(data) == 0 { return nil, ErrNoWalEntry } var entry consensus.WalEntry - var b bytes.Buffer - b.Write(data) - decoder := gob.NewDecoder(&b) - if err := decoder.Decode(&entry); err != nil { + if err := gob.Decode(data, &entry); err != nil { return nil, err } @@ -267,7 +247,7 @@ func (cdb *ChainDB) GetRaftEntry(idx uint64) (*consensus.WalEntry, error) { } func (cdb *ChainDB) GetRaftEntryIndexOfBlock(hash []byte) (uint64, error) { - data := cdb.store.Get(getRaftEntryInvertKey(hash)) + data := cdb.store.Get(dbkey.RaftEntryInvert(hash)) if len(data) == 0 { return 0, ErrNoWalEntryForBlock } @@ -290,7 +270,7 @@ func (cdb *ChainDB) GetRaftEntryOfBlock(hash []byte) (*consensus.WalEntry, error } func (cdb *ChainDB) GetRaftEntryLastIdx() (uint64, error) { - lastBytes := cdb.store.Get(raftEntryLastIdxKey) + lastBytes := cdb.store.Get(dbkey.RaftEntryLastIdx()) if lastBytes == nil || len(lastBytes) == 0 { return 0, nil } @@ -374,13 +354,13 @@ func (cdb *ChainDB) WriteSnapshot(snap *raftpb.Snapshot) error { } logger.Debug().Str("snapshot", consensus.SnapToString(snap, &snapdata)).Msg("write snapshot to wal") - data, err := proto.Marshal(snap) + data, err := proto.Encode(snap) if err != nil { return err } dbTx := cdb.store.NewTx() - dbTx.Set(raftSnapKey, data) + dbTx.Set(dbkey.RaftSnap(), data) dbTx.Commit() return nil @@ -416,13 +396,13 @@ func (cdb *ChainDB) WriteSnapshot(snap *raftpb.Snapshot) error { */ func (cdb *ChainDB) GetSnapshot() (*raftpb.Snapshot, error) { - data := cdb.store.Get(raftSnapKey) + data := cdb.store.Get(dbkey.RaftSnap()) if len(data) == 0 { return nil, nil } snap := &raftpb.Snapshot{} - if err := proto.Unmarshal(data, snap); err != nil { + if err := proto.Decode(data, snap); err != nil { logger.Panic().Msg("failed to unmarshal raft snap") return nil, ErrInvalidRaftSnapshot } @@ -441,30 +421,25 @@ func (cdb *ChainDB) WriteIdentity(identity *consensus.RaftIdentity) error { logger.Info().Str("id", identity.ToString()).Msg("save raft identity") - var val bytes.Buffer - - enc := gob.NewEncoder(&val) - if err := enc.Encode(identity); err != nil { + enc, err := gob.Encode(identity) + if err != nil { return ErrEncodeRaftIdentity } - dbTx.Set(raftIdentityKey, val.Bytes()) + dbTx.Set(dbkey.RaftIdentity(), enc) dbTx.Commit() return nil } func (cdb *ChainDB) GetIdentity() (*consensus.RaftIdentity, error) { - data := cdb.store.Get(raftIdentityKey) + data := cdb.store.Get(dbkey.RaftIdentity()) if len(data) == 0 { return nil, nil } var id consensus.RaftIdentity - var b bytes.Buffer - b.Write(data) - decoder := gob.NewDecoder(&b) - if err := decoder.Decode(&id); err != nil { + if err := gob.Decode(data, &id); err != nil { return nil, ErrDecodeRaftIdentity } @@ -486,48 +461,35 @@ func (cdb *ChainDB) WriteConfChangeProgress(id uint64, progress *types.ConfChang return nil } -func getConfChangeProgressKey(idx uint64) []byte { - var key bytes.Buffer - key.Write(raftConfChangeProgressPrefix) - l := make([]byte, 8) - binary.LittleEndian.PutUint64(l[:], idx) - key.Write(l) - return key.Bytes() -} - func (cdb *ChainDB) writeConfChangeProgress(dbTx db.Transaction, id uint64, progress *types.ConfChangeProgress) error { if id == 0 { // it's for intial member's for startup return nil } - ccKey := getConfChangeProgressKey(id) - // Make CC Data var data []byte var err error - if data, err = proto.Marshal(progress); err != nil { + if data, err = proto.Encode(progress); err != nil { logger.Error().Msg("failed to marshal confChangeProgress") return err } - dbTx.Set(ccKey, data) + dbTx.Set(dbkey.RaftConfChangeProgress(id), data) return nil } func (cdb *ChainDB) GetConfChangeProgress(id uint64) (*types.ConfChangeProgress, error) { - ccKey := getConfChangeProgressKey(id) - - data := cdb.store.Get(ccKey) + data := cdb.store.Get(dbkey.RaftConfChangeProgress(id)) if len(data) == 0 { return nil, nil } var progress types.ConfChangeProgress - if err := proto.Unmarshal(data, &progress); err != nil { + if err := proto.Decode(data, &progress); err != nil { logger.Error().Msg("failed to unmarshal raft state") return nil, ErrInvalidCCProgress } diff --git a/chain/chainhandle.go b/chain/chainhandle.go index 2f4a49acd..4691b73f7 100644 --- a/chain/chainhandle.go +++ b/chain/chainhandle.go @@ -18,11 +18,12 @@ import ( "github.com/aergoio/aergo/v2/contract" "github.com/aergoio/aergo/v2/contract/name" "github.com/aergoio/aergo/v2/contract/system" - "github.com/aergoio/aergo/v2/internal/enc" + "github.com/aergoio/aergo/v2/fee" + "github.com/aergoio/aergo/v2/internal/enc/base58" + "github.com/aergoio/aergo/v2/internal/enc/proto" "github.com/aergoio/aergo/v2/message" "github.com/aergoio/aergo/v2/state" "github.com/aergoio/aergo/v2/types" - "github.com/golang/protobuf/proto" ) var ( @@ -55,7 +56,7 @@ type ErrBlock struct { } func (ec *ErrBlock) Error() string { - return fmt.Sprintf("Error: %s. block(%s, %d)", ec.err.Error(), enc.ToString(ec.block.Hash), ec.block.No) + return fmt.Sprintf("Error: %s. block(%s, %d)", ec.err.Error(), base58.Encode(ec.block.Hash), ec.block.No) } type ErrTx struct { @@ -64,7 +65,7 @@ type ErrTx struct { } func (ec *ErrTx) Error() string { - return fmt.Sprintf("error executing tx:%s, tx=%s", ec.err.Error(), enc.ToString(ec.tx.GetHash())) + return fmt.Sprintf("error executing tx:%s, tx=%s", ec.err.Error(), base58.Encode(ec.tx.GetHash())) } func (cs *ChainService) getBestBlockNo() types.BlockNo { @@ -288,7 +289,7 @@ func (cp *chainProcessor) addBlock(blk *types.Block) error { Uint64("latest", cp.cdb.getBestBlockNo()). Uint64("blockNo", blk.BlockNo()). Str("hash", blk.ID()). - Str("prev_hash", enc.ToString(blk.GetHeader().GetPrevBlockHash())). + Str("prev_hash", base58.Encode(blk.GetHeader().GetPrevBlockHash())). Msg("block added to the block indices") } cp.lastBlock = blk @@ -603,7 +604,7 @@ func newBlockExecutor(cs *ChainService, bState *state.BlockState, block *types.B // executed by the block factory. commitOnly = true } - bState.SetGasPrice(system.GetGasPriceFromState(bState)) + bState.SetGasPrice(system.GetGasPrice()) bState.Receipts().SetHardFork(cs.cfg.Hardfork, block.BlockNo()) return &blockExecutor{ @@ -637,7 +638,7 @@ func NewTxExecutor(execCtx context.Context, ccc consensus.ChainConsensusCluster, err := executeTx(execCtx, ccc, cdb, bState, tx, bi, preloadService) if err != nil { - logger.Error().Err(err).Str("hash", enc.ToString(tx.GetHash())).Msg("tx failed") + logger.Error().Err(err).Str("hash", base58.Encode(tx.GetHash())).Msg("tx failed") if err2 := bState.Rollback(blockSnap); err2 != nil { logger.Panic().Err(err).Msg("failed to rollback block state") } @@ -949,18 +950,14 @@ func executeTx(execCtx context.Context, ccc consensus.ChainConsensusCluster, cdb txFee = new(big.Int).SetUint64(0) events, err = executeGovernanceTx(ccc, bs, txBody, sender, receiver, bi) if err != nil { - logger.Warn().Err(err).Str("txhash", enc.ToString(tx.GetHash())).Msg("governance tx Error") + logger.Warn().Err(err).Str("txhash", base58.Encode(tx.GetHash())).Msg("governance tx Error") } case types.TxType_FEEDELEGATION: - balance := receiver.Balance() - var fee *big.Int - fee, err = tx.GetMaxFee(balance, bs.GasPrice, bi.ForkVersion) + err = tx.ValidateMaxFee(receiver.Balance(), bs.GasPrice, bi.ForkVersion) if err != nil { return err } - if fee.Cmp(balance) > 0 { - return types.ErrInsufficientBalance - } + var contractState *state.ContractState contractState, err = bs.OpenContractState(receiver.AccountID(), receiver.State()) if err != nil { @@ -970,7 +967,7 @@ func executeTx(execCtx context.Context, ccc consensus.ChainConsensusCluster, cdb tx.GetHash(), txBody.GetAccount(), txBody.GetAmount()) if err != nil { if err != types.ErrNotAllowedFeeDelegation { - logger.Warn().Err(err).Str("txhash", enc.ToString(tx.GetHash())).Msg("checkFeeDelegation Error") + logger.Warn().Err(err).Str("txhash", base58.Encode(tx.GetHash())).Msg("checkFeeDelegation Error") return err } return types.ErrNotAllowedFeeDelegation @@ -1035,7 +1032,8 @@ func executeTx(execCtx context.Context, ccc consensus.ChainConsensusCluster, cdb receipt.TxHash = tx.GetHash() receipt.Events = events receipt.FeeDelegation = txBody.Type == types.TxType_FEEDELEGATION - receipt.GasUsed = contract.GasUsed(txFee, bs.GasPrice, txBody.Type, bi.ForkVersion) + isGovernance := txBody.Type == types.TxType_GOVERNANCE + receipt.GasUsed = fee.ReceiptGasUsed(bi.ForkVersion, isGovernance, txFee, bs.GasPrice) return bs.AddReceipt(receipt) } diff --git a/chain/chainhandle_test.go b/chain/chainhandle_test.go index de0b98b35..a71e1c1bc 100644 --- a/chain/chainhandle_test.go +++ b/chain/chainhandle_test.go @@ -13,7 +13,6 @@ import ( "github.com/aergoio/aergo-lib/db" "github.com/aergoio/aergo/v2/account/key" "github.com/aergoio/aergo/v2/contract" - "github.com/aergoio/aergo/v2/contract/system" "github.com/aergoio/aergo/v2/internal/common" "github.com/aergoio/aergo/v2/state" "github.com/aergoio/aergo/v2/types" @@ -37,7 +36,6 @@ func initTest(t *testing.T, testmode bool) { t.Fatalf("failed init : %s", err.Error()) } types.InitGovernance("dpos", true) - system.InitGovernance("dpos") } diff --git a/chain/chainservice.go b/chain/chainservice.go index 93a328415..7b4b0aaea 100644 --- a/chain/chainservice.go +++ b/chain/chainservice.go @@ -24,11 +24,12 @@ import ( "github.com/aergoio/aergo/v2/contract/name" "github.com/aergoio/aergo/v2/contract/system" "github.com/aergoio/aergo/v2/fee" - "github.com/aergoio/aergo/v2/internal/enc" + "github.com/aergoio/aergo/v2/internal/enc/base58" "github.com/aergoio/aergo/v2/message" "github.com/aergoio/aergo/v2/pkg/component" "github.com/aergoio/aergo/v2/state" "github.com/aergoio/aergo/v2/types" + "github.com/aergoio/aergo/v2/types/dbkey" lru "github.com/hashicorp/golang-lru" ) @@ -144,7 +145,7 @@ func (core *Core) initGenesis(genesis *types.Genesis, mainnet bool, testmode boo genesisBlock, _ := core.cdb.GetBlockByNo(0) logger.Info().Str("chain id", gen.ID.ToJSON()). - Str("hash", enc.ToString(genesisBlock.GetHash())).Msg("chain initialized") + Str("hash", base58.Encode(genesisBlock.GetHash())).Msg("chain initialized") return genesisBlock, nil } @@ -273,7 +274,7 @@ func NewChainService(cfg *cfg.Config) *ChainService { logger.Debug().Err(err).Msg("failed to get elected BPs") } else { for _, res := range top.Votes { - logger.Debug().Str("BP", enc.ToString(res.Candidate)). + logger.Debug().Str("BP", base58.Encode(res.Candidate)). Str("votes", new(big.Int).SetBytes(res.Amount).String()).Msgf("BP vote stat") } } @@ -291,7 +292,6 @@ func NewChainService(cfg *cfg.Config) *ChainService { // For a strict governance transaction validation. types.InitGovernance(cs.ConsensusType(), cs.IsPublic()) - system.InitGovernance(cs.ConsensusType()) //reset parameter of aergo.system systemState, err := cs.SDB().GetSystemAccountState() @@ -566,7 +566,7 @@ func (cs *ChainService) getNameInfo(qname string, blockNo types.BlockNo) (*types func (cs *ChainService) getEnterpriseConf(key string) (*types.EnterpriseConfig, error) { sdb := cs.sdb.OpenNewStateDB(cs.sdb.GetRoot()) - if strings.ToUpper(key) != enterprise.AdminsKey { + if strings.ToUpper(key) != string(dbkey.EnterpriseAdmins()) { return enterprise.GetConf(sdb, key) } return enterprise.GetAdmin(sdb) @@ -641,7 +641,7 @@ func (cm *ChainManager) Receive(context actor.Context) { bstate = msg.Bstate.(*state.BlockState) if timeoutTx := bstate.TimeoutTx(); timeoutTx != nil { if logger.IsDebugEnabled() { - logger.Debug().Str("hash", enc.ToString(timeoutTx.GetHash())).Msg("received timeout tx") + logger.Debug().Str("hash", base58.Encode(timeoutTx.GetHash())).Msg("received timeout tx") } cm.TellTo(message.MemPoolSvc, &message.MemPoolDelTx{Tx: timeoutTx.GetTx()}) } @@ -686,7 +686,7 @@ func getAddressNameResolved(sdb *state.StateDB, account []byte) ([]byte, error) if len(account) == types.NameLength { scs, err := sdb.GetNameAccountState() if err != nil { - logger.Error().Str("hash", enc.ToString(account)).Err(err).Msg("failed to get state for account") + logger.Error().Str("hash", base58.Encode(account)).Err(err).Msg("failed to get state for account") return nil, err } return name.GetAddress(scs, account), nil @@ -705,7 +705,7 @@ func (cw *ChainWorker) Receive(context actor.Context) { id := types.ToAccountID(address) proof, err := sdb.GetAccountAndProof(id[:], root, compressed) if err != nil { - logger.Error().Str("hash", enc.ToString(address)).Err(err).Msg("failed to get state for account") + logger.Error().Str("hash", base58.Encode(address)).Err(err).Msg("failed to get state for account") return nil, err } proof.Key = address @@ -717,7 +717,7 @@ func (cw *ChainWorker) Receive(context actor.Context) { bid := types.ToBlockID(msg.BlockHash) block, err := cw.getBlock(bid[:]) if err != nil { - logger.Debug().Err(err).Str("hash", enc.ToString(msg.BlockHash)).Msg("block not found") + logger.Debug().Err(err).Str("hash", base58.Encode(msg.BlockHash)).Msg("block not found") } context.Respond(message.GetBlockRsp{ Block: block, @@ -746,7 +746,7 @@ func (cw *ChainWorker) Receive(context actor.Context) { id := types.ToAccountID(address) accState, err := sdb.GetAccountState(id) if err != nil { - logger.Error().Str("hash", enc.ToString(address)).Err(err).Msg("failed to get state for account") + logger.Error().Str("hash", base58.Encode(address)).Err(err).Msg("failed to get state for account") } context.Respond(message.GetStateRsp{ Account: address, @@ -807,7 +807,7 @@ func (cw *ChainWorker) Receive(context actor.Context) { } ctrState, err := sdb.OpenContractStateAccount(types.ToAccountID(address)) if err != nil { - logger.Error().Str("hash", enc.ToString(address)).Err(err).Msg("failed to get state for contract") + logger.Error().Str("hash", base58.Encode(address)).Err(err).Msg("failed to get state for contract") context.Respond(message.GetQueryRsp{Result: nil, Err: err}) } else { bs := state.NewBlockState(sdb) @@ -833,7 +833,7 @@ func (cw *ChainWorker) Receive(context actor.Context) { varProof.Key = storageKey varProofs = append(varProofs, varProof) if err != nil { - logger.Error().Str("hash", enc.ToString(contractProof.Key)).Err(err).Msg("failed to get state variable in contract") + logger.Error().Str("hash", base58.Encode(contractProof.Key)).Err(err).Msg("failed to get state variable in contract") } } } @@ -895,7 +895,7 @@ func (cw *ChainWorker) Receive(context actor.Context) { sdb = cw.sdb.OpenNewStateDB(cw.sdb.GetRoot()) ctrState, err := sdb.OpenContractStateAccount(types.ToAccountID(msg.Contract)) if err != nil { - logger.Error().Str("hash", enc.ToString(msg.Contract)).Err(err).Msg("failed to get state for contract") + logger.Error().Str("hash", base58.Encode(msg.Contract)).Err(err).Msg("failed to get state for contract") context.Respond(message.CheckFeeDelegationRsp{Err: err}) } else { bs := state.NewBlockState(sdb) diff --git a/chain/chainverifier.go b/chain/chainverifier.go index bd5bc4fc2..811edc8ea 100644 --- a/chain/chainverifier.go +++ b/chain/chainverifier.go @@ -6,7 +6,7 @@ import ( "time" "github.com/aergoio/aergo-actor/actor" - "github.com/aergoio/aergo/v2/internal/enc" + "github.com/aergoio/aergo/v2/internal/enc/base58" "github.com/aergoio/aergo/v2/message" "github.com/aergoio/aergo/v2/pkg/component" "github.com/aergoio/aergo/v2/types" @@ -189,14 +189,14 @@ func (cv *ChainVerifier) report(prevBlock *types.Block, targetBlock *types.Block switch cv.stage { case TestPrevBlock: report += fmt.Sprintf("[description] prev block hash=%s, prev stage root=%s", prevBlock.ID(), - enc.ToString(prevBlock.GetHeader().GetBlocksRootHash())) + base58.Encode(prevBlock.GetHeader().GetBlocksRootHash())) case TestCurBlock: report += fmt.Sprintf("[description] target block hash=%s", targetBlock.ID()) case TestBlockExecute: - report += fmt.Sprintf("[description] tx Merkle = %s", enc.ToString(targetBlock.GetHeader().GetTxsRootHash())) - report += fmt.Sprintf(", state Root = %s", enc.ToString(targetBlock.GetHeader().GetBlocksRootHash())) + report += fmt.Sprintf("[description] tx Merkle = %s", base58.Encode(targetBlock.GetHeader().GetTxsRootHash())) + report += fmt.Sprintf(", state Root = %s", base58.Encode(targetBlock.GetHeader().GetBlocksRootHash())) report += fmt.Sprintf(", all transaction passed") } diff --git a/chain/common.go b/chain/common.go index fccd0ec9c..fa8c2f79d 100644 --- a/chain/common.go +++ b/chain/common.go @@ -9,7 +9,7 @@ import ( "errors" "github.com/aergoio/aergo/v2/consensus" - "github.com/aergoio/aergo/v2/internal/enc" + "github.com/aergoio/aergo/v2/internal/enc/base58" "github.com/aergoio/aergo/v2/types" ) @@ -48,7 +48,7 @@ func Init(maxBlkBodySize uint32, coinbaseAccountStr string, isBp bool, maxAnchor if err != nil { return ErrInvalidCoinbaseAccount } - logger.Info().Str("account", enc.ToString(CoinbaseAccount)).Str("str", coinbaseAccountStr). + logger.Info().Str("account", base58.Encode(CoinbaseAccount)).Str("str", coinbaseAccountStr). Msg("set coinbase account") } else { diff --git a/chain/orphanpool.go b/chain/orphanpool.go index 1e254fcb7..2c49d7860 100644 --- a/chain/orphanpool.go +++ b/chain/orphanpool.go @@ -9,7 +9,7 @@ import ( "errors" "sync" - "github.com/aergoio/aergo/v2/internal/enc" + "github.com/aergoio/aergo/v2/internal/enc/base58" "github.com/aergoio/aergo/v2/types" "github.com/hashicorp/golang-lru/simplelru" ) @@ -51,7 +51,7 @@ func NewOrphanPool(size int) *OrphanPool { // add Orphan into the orphan cache pool func (op *OrphanPool) addOrphan(block *types.Block) error { - logger.Warn().Str("prev", enc.ToString(block.GetHeader().GetPrevBlockHash())).Msg("add orphan Block") + logger.Warn().Str("prev", base58.Encode(block.GetHeader().GetPrevBlockHash())).Msg("add orphan Block") id := types.ToBlockID(block.Header.PrevBlockHash) cachedblock, exists := op.cache[id] diff --git a/chain/recover.go b/chain/recover.go index 922786741..26e14ee74 100644 --- a/chain/recover.go +++ b/chain/recover.go @@ -2,15 +2,16 @@ package chain import ( "bytes" - "encoding/gob" "errors" "fmt" "os" "runtime" "runtime/debug" - "github.com/aergoio/aergo/v2/internal/enc" + "github.com/aergoio/aergo/v2/internal/enc/base58" + "github.com/aergoio/aergo/v2/internal/enc/gob" "github.com/aergoio/aergo/v2/types" + "github.com/aergoio/aergo/v2/types/dbkey" ) var ( @@ -62,7 +63,7 @@ func (cs *ChainService) Recover() error { // check status of chain if !bytes.Equal(best.BlockHash(), marker.BrBestHash) { - logger.Error().Str("best", best.ID()).Str("markerbest", enc.ToString(marker.BrBestHash)).Msg("best block is not equal to old chain") + logger.Error().Str("best", best.ID()).Str("markerbest", base58.Encode(marker.BrBestHash)).Msg("best block is not equal to old chain") return ErrRecoInvalidBest } @@ -191,7 +192,7 @@ func (rm *ReorgMarker) RecoverChainMapping(cdb *ChainDB) error { logger.Info().Uint64("bestno", rm.BrBestNo).Msg("update best block") - bulk.Set(latestKey, types.BlockNoToBytes(rm.BrBestNo)) + bulk.Set(dbkey.LatestBlock(), types.BlockNoToBytes(rm.BrBestNo)) bulk.Flush() cdb.setLatest(bestBlock) @@ -217,26 +218,20 @@ func (rm *ReorgMarker) delete() { } func (rm *ReorgMarker) toBytes() ([]byte, error) { - var val bytes.Buffer - encoder := gob.NewEncoder(&val) - if err := encoder.Encode(rm); err != nil { - return nil, err - } - - return val.Bytes(), nil + return gob.Encode(rm) } func (rm *ReorgMarker) toString() string { buf := "" if len(rm.BrStartHash) != 0 { - buf = buf + fmt.Sprintf("branch root=(%d, %s).", rm.BrStartNo, enc.ToString(rm.BrStartHash)) + buf = buf + fmt.Sprintf("branch root=(%d, %s).", rm.BrStartNo, base58.Encode(rm.BrStartHash)) } if len(rm.BrTopHash) != 0 { - buf = buf + fmt.Sprintf("branch top=(%d, %s).", rm.BrTopNo, enc.ToString(rm.BrTopHash)) + buf = buf + fmt.Sprintf("branch top=(%d, %s).", rm.BrTopNo, base58.Encode(rm.BrTopHash)) } if len(rm.BrBestHash) != 0 { - buf = buf + fmt.Sprintf("org best=(%d, %s).", rm.BrBestNo, enc.ToString(rm.BrBestHash)) + buf = buf + fmt.Sprintf("org best=(%d, %s).", rm.BrBestNo, base58.Encode(rm.BrBestHash)) } return buf diff --git a/chain/reorg.go b/chain/reorg.go index 5691c5ed3..c4107c634 100644 --- a/chain/reorg.go +++ b/chain/reorg.go @@ -8,7 +8,7 @@ import ( "github.com/aergoio/aergo/v2/consensus" "github.com/aergoio/aergo/v2/contract/system" - "github.com/aergoio/aergo/v2/internal/enc" + "github.com/aergoio/aergo/v2/internal/enc/base58" "github.com/aergoio/aergo/v2/message" "github.com/aergoio/aergo/v2/state" "github.com/aergoio/aergo/v2/types" @@ -18,11 +18,6 @@ const ( initBlkCount = 20 ) -var ( - reorgKeyStr = "_reorg_marker_" - reorgKey = []byte(reorgKeyStr) -) - var ( ErrInvalidReorgMarker = errors.New("reorg marker is invalid") ErrMarkerNil = errors.New("reorg marker is nil") @@ -57,7 +52,7 @@ type ErrReorgBlock struct { func (ec *ErrReorgBlock) Error() string { if ec.blockHash != nil { - return fmt.Sprintf("%s, block:%d,%s", ec.msg, ec.blockNo, enc.ToString(ec.blockHash)) + return fmt.Sprintf("%s, block:%d,%s", ec.msg, ec.blockNo, base58.Encode(ec.blockHash)) } else if ec.blockNo != 0 { return fmt.Sprintf("%s, block:%d", ec.msg, ec.blockNo) } else { diff --git a/chain/signVerifier.go b/chain/signVerifier.go index b3b65edab..6240e88bf 100644 --- a/chain/signVerifier.go +++ b/chain/signVerifier.go @@ -7,7 +7,7 @@ import ( "github.com/aergoio/aergo-actor/actor" "github.com/aergoio/aergo/v2/account/key" "github.com/aergoio/aergo/v2/contract/name" - "github.com/aergoio/aergo/v2/internal/enc" + "github.com/aergoio/aergo/v2/internal/enc/base58" "github.com/aergoio/aergo/v2/message" "github.com/aergoio/aergo/v2/pkg/component" "github.com/aergoio/aergo/v2/state" @@ -83,7 +83,7 @@ func (sv *SignVerifier) verifyTxLoop(workerNo int) { hit, err := sv.verifyTx(sv.comm, txWork.tx, txWork.useMempool) if err != nil { - logger.Error().Int("worker", workerNo).Bool("hit", hit).Str("hash", enc.ToString(txWork.tx.GetHash())). + logger.Error().Int("worker", workerNo).Bool("hit", hit).Str("hash", base58.Encode(txWork.tx.GetHash())). Err(err).Msg("error verify tx") } diff --git a/cmd/aergocli/cmd/blockchain_test.go b/cmd/aergocli/cmd/blockchain_test.go index 112fb0dc2..271f32234 100644 --- a/cmd/aergocli/cmd/blockchain_test.go +++ b/cmd/aergocli/cmd/blockchain_test.go @@ -1,13 +1,13 @@ package cmd import ( - "encoding/hex" "testing" "github.com/aergoio/aergo/v2/cmd/aergocli/util/encoding/json" + "github.com/aergoio/aergo/v2/internal/enc/base58" + "github.com/aergoio/aergo/v2/internal/enc/hex" "github.com/aergoio/aergo/v2/types" "github.com/golang/mock/gomock" - "github.com/mr-tron/base58/base58" "github.com/stretchr/testify/assert" ) @@ -49,6 +49,6 @@ func TestBlockchainWithMock(t *testing.T) { t.Fatal(err) } testBlockHashByte, _ := base58.Decode(testBlockHashString) - assert.Equal(t, hex.EncodeToString(testBlockHashByte), result["Hash"]) + assert.Equal(t, hex.Encode(testBlockHashByte), result["Hash"]) assert.Equal(t, float64(1), result["Height"]) } diff --git a/cmd/aergocli/cmd/committx_test.go b/cmd/aergocli/cmd/committx_test.go index 27f3de136..aa5eb00fd 100644 --- a/cmd/aergocli/cmd/committx_test.go +++ b/cmd/aergocli/cmd/committx_test.go @@ -4,9 +4,9 @@ import ( "testing" "github.com/aergoio/aergo/v2/cmd/aergocli/util/encoding/json" + "github.com/aergoio/aergo/v2/internal/enc/base58" "github.com/aergoio/aergo/v2/types" "github.com/golang/mock/gomock" - "github.com/mr-tron/base58/base58" "github.com/stretchr/testify/assert" ) diff --git a/cmd/aergocli/cmd/contract.go b/cmd/aergocli/cmd/contract.go index 0e8bbb2aa..010b7f6ac 100644 --- a/cmd/aergocli/cmd/contract.go +++ b/cmd/aergocli/cmd/contract.go @@ -3,7 +3,6 @@ package cmd import ( "bytes" "context" - "encoding/hex" "encoding/json" "errors" "fmt" @@ -14,9 +13,10 @@ import ( luacEncoding "github.com/aergoio/aergo/v2/cmd/aergoluac/encoding" luac "github.com/aergoio/aergo/v2/cmd/aergoluac/util" "github.com/aergoio/aergo/v2/internal/common" + "github.com/aergoio/aergo/v2/internal/enc/base58" + "github.com/aergoio/aergo/v2/internal/enc/hex" "github.com/aergoio/aergo/v2/types" aergorpc "github.com/aergoio/aergo/v2/types" - "github.com/mr-tron/base58/base58" "github.com/spf13/cobra" ) @@ -201,7 +201,7 @@ func runDeployCmd(cmd *cobra.Command, args []string) error { if isHexString(data) { // the data is expected to be copied from aergoscan view of // the transaction that deployed the contract - payload, err = hex.DecodeString(data) + payload, err = hex.Decode(data) } else { // the data is the output of aergoluac code, err = luacEncoding.DecodeCode(data) diff --git a/cmd/aergocli/cmd/enterprise.go b/cmd/aergocli/cmd/enterprise.go index ad24bfd40..ed57846d4 100644 --- a/cmd/aergocli/cmd/enterprise.go +++ b/cmd/aergocli/cmd/enterprise.go @@ -16,9 +16,9 @@ import ( "github.com/aergoio/aergo/v2/cmd/aergocli/util" "github.com/aergoio/aergo/v2/cmd/aergocli/util/encoding/json" "github.com/aergoio/aergo/v2/contract/enterprise" + "github.com/aergoio/aergo/v2/internal/enc/base58" "github.com/aergoio/aergo/v2/types" aergorpc "github.com/aergoio/aergo/v2/types" - "github.com/mr-tron/base58/base58" "github.com/spf13/cobra" ) diff --git a/cmd/aergocli/cmd/enterprise_test.go b/cmd/aergocli/cmd/enterprise_test.go index 09737e07b..a9ddd1faf 100644 --- a/cmd/aergocli/cmd/enterprise_test.go +++ b/cmd/aergocli/cmd/enterprise_test.go @@ -5,9 +5,9 @@ import ( "errors" "testing" + "github.com/aergoio/aergo/v2/internal/enc/base58" aergorpc "github.com/aergoio/aergo/v2/types" "github.com/golang/mock/gomock" - "github.com/mr-tron/base58/base58" "github.com/stretchr/testify/assert" ) diff --git a/cmd/aergocli/cmd/getblock.go b/cmd/aergocli/cmd/getblock.go index 6f29340b0..f54e43dbb 100644 --- a/cmd/aergocli/cmd/getblock.go +++ b/cmd/aergocli/cmd/getblock.go @@ -12,8 +12,8 @@ import ( "fmt" "github.com/aergoio/aergo/v2/cmd/aergocli/util" + "github.com/aergoio/aergo/v2/internal/enc/base58" aergorpc "github.com/aergoio/aergo/v2/types" - "github.com/mr-tron/base58/base58" "github.com/spf13/cobra" ) diff --git a/cmd/aergocli/cmd/getstate.go b/cmd/aergocli/cmd/getstate.go index a2b02c3eb..7e3080523 100644 --- a/cmd/aergocli/cmd/getstate.go +++ b/cmd/aergocli/cmd/getstate.go @@ -9,8 +9,8 @@ import ( "context" "github.com/aergoio/aergo/v2/cmd/aergocli/util" + "github.com/aergoio/aergo/v2/internal/enc/base58" "github.com/aergoio/aergo/v2/types" - "github.com/mr-tron/base58/base58" "github.com/spf13/cobra" ) diff --git a/cmd/aergocli/cmd/gettx.go b/cmd/aergocli/cmd/gettx.go index a9f7f8d8e..a122aec0c 100644 --- a/cmd/aergocli/cmd/gettx.go +++ b/cmd/aergocli/cmd/gettx.go @@ -9,8 +9,8 @@ import ( "context" "github.com/aergoio/aergo/v2/cmd/aergocli/util" + "github.com/aergoio/aergo/v2/internal/enc/base58" aergorpc "github.com/aergoio/aergo/v2/types" - "github.com/mr-tron/base58/base58" "github.com/spf13/cobra" ) diff --git a/cmd/aergocli/cmd/keygen.go b/cmd/aergocli/cmd/keygen.go index 8d6a323e9..ef553d154 100644 --- a/cmd/aergocli/cmd/keygen.go +++ b/cmd/aergocli/cmd/keygen.go @@ -1,7 +1,6 @@ package cmd import ( - b64 "encoding/base64" "encoding/json" "fmt" "os" @@ -10,6 +9,7 @@ import ( "github.com/aergoio/aergo/v2/account/key" keycrypto "github.com/aergoio/aergo/v2/account/key/crypto" + "github.com/aergoio/aergo/v2/internal/enc/base64" "github.com/aergoio/aergo/v2/p2p/p2putil" "github.com/aergoio/aergo/v2/types" "github.com/btcsuite/btcd/btcec" @@ -195,7 +195,7 @@ func generateKeyJson(priv crypto.PrivKey, pub crypto.PubKey) error { addressEncoded := types.EncodeAddress(address) jsonMarshalled, err := json.MarshalIndent(keyJson{ Address: addressEncoded, - PubKey: b64.StdEncoding.EncodeToString(pubBytes), + PubKey: base64.Encode(pubBytes), PrivKey: types.EncodePrivKey(privKeyExport), Id: types.IDB58Encode(pid), }, "", " ") diff --git a/cmd/aergocli/cmd/listblocks.go b/cmd/aergocli/cmd/listblocks.go index d20a32385..aa4c1c003 100644 --- a/cmd/aergocli/cmd/listblocks.go +++ b/cmd/aergocli/cmd/listblocks.go @@ -9,8 +9,8 @@ import ( "context" "github.com/aergoio/aergo/v2/cmd/aergocli/util" + "github.com/aergoio/aergo/v2/internal/enc/base58" "github.com/aergoio/aergo/v2/types" - "github.com/mr-tron/base58/base58" "github.com/spf13/cobra" ) diff --git a/cmd/aergocli/cmd/receipt.go b/cmd/aergocli/cmd/receipt.go index fc7d8fefe..c36945556 100644 --- a/cmd/aergocli/cmd/receipt.go +++ b/cmd/aergocli/cmd/receipt.go @@ -10,8 +10,8 @@ import ( "log" "github.com/aergoio/aergo/v2/cmd/aergocli/util" + "github.com/aergoio/aergo/v2/internal/enc/base58" aergorpc "github.com/aergoio/aergo/v2/types" - "github.com/mr-tron/base58/base58" "github.com/spf13/cobra" ) diff --git a/cmd/aergocli/cmd/sendtx.go b/cmd/aergocli/cmd/sendtx.go index f76923ba7..0b01d7df6 100644 --- a/cmd/aergocli/cmd/sendtx.go +++ b/cmd/aergocli/cmd/sendtx.go @@ -10,8 +10,8 @@ import ( "errors" "github.com/aergoio/aergo/v2/cmd/aergocli/util" + "github.com/aergoio/aergo/v2/internal/enc/base58" "github.com/aergoio/aergo/v2/types" - "github.com/mr-tron/base58" "github.com/spf13/cobra" ) diff --git a/cmd/aergocli/cmd/sendtx_test.go b/cmd/aergocli/cmd/sendtx_test.go index 5cb101dac..cec44f02e 100644 --- a/cmd/aergocli/cmd/sendtx_test.go +++ b/cmd/aergocli/cmd/sendtx_test.go @@ -4,9 +4,9 @@ import ( "testing" "github.com/aergoio/aergo/v2/cmd/aergocli/util/encoding/json" + "github.com/aergoio/aergo/v2/internal/enc/base58" "github.com/aergoio/aergo/v2/types" "github.com/golang/mock/gomock" - "github.com/mr-tron/base58/base58" "github.com/stretchr/testify/assert" ) diff --git a/cmd/aergocli/cmd/signtx.go b/cmd/aergocli/cmd/signtx.go index d4e8b48db..748784ff1 100644 --- a/cmd/aergocli/cmd/signtx.go +++ b/cmd/aergocli/cmd/signtx.go @@ -8,9 +8,9 @@ import ( "github.com/aergoio/aergo/v2/account/key" crypto "github.com/aergoio/aergo/v2/account/key/crypto" "github.com/aergoio/aergo/v2/cmd/aergocli/util" + "github.com/aergoio/aergo/v2/internal/enc/base58" "github.com/aergoio/aergo/v2/types" "github.com/btcsuite/btcd/btcec" - "github.com/mr-tron/base58/base58" "github.com/spf13/cobra" ) diff --git a/cmd/aergocli/cmd/signtx_test.go b/cmd/aergocli/cmd/signtx_test.go index e76a37b52..972aca344 100644 --- a/cmd/aergocli/cmd/signtx_test.go +++ b/cmd/aergocli/cmd/signtx_test.go @@ -8,8 +8,8 @@ import ( "github.com/aergoio/aergo/v2/cmd/aergocli/util" "github.com/aergoio/aergo/v2/cmd/aergocli/util/encoding/json" + "github.com/aergoio/aergo/v2/internal/enc/base58" "github.com/aergoio/aergo/v2/types" - "github.com/mr-tron/base58/base58" "github.com/stretchr/testify/assert" ) diff --git a/cmd/aergocli/cmd/vote.go b/cmd/aergocli/cmd/vote.go index 880980b9c..122c35441 100644 --- a/cmd/aergocli/cmd/vote.go +++ b/cmd/aergocli/cmd/vote.go @@ -13,8 +13,8 @@ import ( "strings" "github.com/aergoio/aergo/v2/cmd/aergocli/util" + "github.com/aergoio/aergo/v2/internal/enc/base58" "github.com/aergoio/aergo/v2/types" - "github.com/mr-tron/base58/base58" "github.com/spf13/cobra" ) diff --git a/cmd/aergocli/util/base58addr.go b/cmd/aergocli/util/base58addr.go index 90993c03a..c744d6591 100644 --- a/cmd/aergocli/util/base58addr.go +++ b/cmd/aergocli/util/base58addr.go @@ -8,9 +8,9 @@ import ( "strconv" "time" + "github.com/aergoio/aergo/v2/internal/enc/base58" "github.com/aergoio/aergo/v2/p2p/p2putil" "github.com/aergoio/aergo/v2/types" - "github.com/mr-tron/base58/base58" ) type InOutBlockHeader struct { diff --git a/cmd/aergocli/util/base58addr_test.go b/cmd/aergocli/util/base58addr_test.go index a3f962b98..ec6800c28 100644 --- a/cmd/aergocli/util/base58addr_test.go +++ b/cmd/aergocli/util/base58addr_test.go @@ -3,8 +3,8 @@ package util import ( "testing" + "github.com/aergoio/aergo/v2/internal/enc/base58" "github.com/aergoio/aergo/v2/types" - "github.com/mr-tron/base58/base58" "github.com/stretchr/testify/assert" ) diff --git a/cmd/aergocli/util/base64ToHex.go b/cmd/aergocli/util/base64ToHex.go index 0df49c088..6ce5d33aa 100644 --- a/cmd/aergocli/util/base64ToHex.go +++ b/cmd/aergocli/util/base64ToHex.go @@ -1,9 +1,9 @@ package util import ( - "encoding/hex" "encoding/json" + "github.com/aergoio/aergo/v2/internal/enc/hex" "github.com/aergoio/aergo/v2/types" ) @@ -18,9 +18,9 @@ type InOutBlockchainStatus struct { func ConvHexBlockchainStatus(in *types.BlockchainStatus) string { out := &InOutBlockchainStatus{} - out.Hash = hex.EncodeToString(in.BestBlockHash) + out.Hash = hex.Encode(in.BestBlockHash) out.Height = in.BestHeight - out.ChainIdHash = hex.EncodeToString(in.BestChainIdHash) + out.ChainIdHash = hex.Encode(in.BestChainIdHash) jsonout, err := json.Marshal(out) if err != nil { return "" diff --git a/cmd/aergocli/util/encoding/json/decode.go b/cmd/aergocli/util/encoding/json/decode.go index 9fd2838d3..a6dd2b0d8 100644 --- a/cmd/aergocli/util/encoding/json/decode.go +++ b/cmd/aergocli/util/encoding/json/decode.go @@ -17,7 +17,7 @@ import ( "unicode/utf16" "unicode/utf8" - "github.com/mr-tron/base58/base58" + "github.com/aergoio/aergo/v2/internal/enc/base58" ) // Unmarshal parses the JSON-encoded data and stores the result diff --git a/cmd/aergocli/util/encoding/json/encode.go b/cmd/aergocli/util/encoding/json/encode.go index 337129a21..26b0c472a 100644 --- a/cmd/aergocli/util/encoding/json/encode.go +++ b/cmd/aergocli/util/encoding/json/encode.go @@ -23,7 +23,7 @@ import ( "unicode" "unicode/utf8" - "github.com/mr-tron/base58/base58" + "github.com/aergoio/aergo/v2/internal/enc/base58" ) // Marshal returns the JSON encoding of v. diff --git a/cmd/aergocli/util/grpccommon.go b/cmd/aergocli/util/grpccommon.go index e21af7fba..11a6b3b93 100644 --- a/cmd/aergocli/util/grpccommon.go +++ b/cmd/aergocli/util/grpccommon.go @@ -9,8 +9,8 @@ import ( "fmt" "github.com/aergoio/aergo/v2/cmd/aergocli/util/encoding/json" + "github.com/aergoio/aergo/v2/internal/enc/proto" "github.com/aergoio/aergo/v2/types" - protobuf "github.com/golang/protobuf/proto" "google.golang.org/grpc" ) @@ -44,7 +44,7 @@ func (c *ConnClient) Close() { } // JSON converts protobuf message(struct) to json notation -func JSON(pb protobuf.Message) string { +func JSON(pb proto.Message) string { jsonout, err := json.MarshalIndent(pb, "", " ") if err != nil { fmt.Printf("Failed: %s\n", err.Error()) diff --git a/cmd/aergoluac/encoding/codeEncoding.go b/cmd/aergoluac/encoding/codeEncoding.go index a2e850158..75329ed98 100644 --- a/cmd/aergoluac/encoding/codeEncoding.go +++ b/cmd/aergoluac/encoding/codeEncoding.go @@ -1,17 +1,17 @@ package encoding import ( - "encoding/hex" "errors" "fmt" - "github.com/anaskhan96/base58check" + "github.com/aergoio/aergo/v2/internal/enc/base58check" + "github.com/aergoio/aergo/v2/internal/enc/hex" ) const CodeVersion = 0xC0 func EncodeCode(code []byte) string { - encoded, _ := base58check.Encode(fmt.Sprintf("%x", CodeVersion), hex.EncodeToString(code)) + encoded, _ := base58check.Encode(fmt.Sprintf("%x", CodeVersion), hex.Encode(code)) return encoded } @@ -20,7 +20,7 @@ func DecodeCode(encodedCode string) ([]byte, error) { if err != nil { return nil, err } - decodedBytes, err := hex.DecodeString(decodedString) + decodedBytes, err := hex.Decode(decodedString) if err != nil { return nil, err } diff --git a/cmd/aergosvr/init.go b/cmd/aergosvr/init.go index b88a9c0a4..d9026f177 100644 --- a/cmd/aergosvr/init.go +++ b/cmd/aergosvr/init.go @@ -7,7 +7,7 @@ import ( "github.com/aergoio/aergo/v2/chain" "github.com/aergoio/aergo/v2/consensus/impl" - "github.com/aergoio/aergo/v2/internal/enc" + "github.com/aergoio/aergo/v2/internal/enc/base58" "github.com/aergoio/aergo/v2/types" "github.com/spf13/cobra" ) @@ -36,7 +36,7 @@ var initGenesis = &cobra.Command{ if core != nil { exist := core.GetGenesisInfo() if exist != nil { - fmt.Printf("genesis block(%s) is already initialized\n", enc.ToString(exist.Block().GetHash())) + fmt.Printf("genesis block(%s) is already initialized\n", base58.Encode(exist.Block().GetHash())) core.Close() return } @@ -71,7 +71,7 @@ var initGenesis = &cobra.Command{ } g := core.GetGenesisInfo() - fmt.Printf("genesis block[%s] is created in (%s)\n", enc.ToString(g.Block().GetHash()), cfg.DataDir) + fmt.Printf("genesis block[%s] is created in (%s)\n", base58.Encode(g.Block().GetHash()), cfg.DataDir) } }, } diff --git a/cmd/colaris/cmd/common.go b/cmd/colaris/cmd/common.go index 848e30338..a443872ea 100644 --- a/cmd/colaris/cmd/common.go +++ b/cmd/colaris/cmd/common.go @@ -9,8 +9,8 @@ import ( "fmt" "github.com/aergoio/aergo/v2/cmd/aergocli/util/encoding/json" + "github.com/aergoio/aergo/v2/internal/enc/proto" "github.com/aergoio/aergo/v2/types" - "github.com/golang/protobuf/proto" "google.golang.org/grpc" ) diff --git a/cmd/colaris/cmd/current.go b/cmd/colaris/cmd/current.go index 4d971f197..ef96bc018 100644 --- a/cmd/colaris/cmd/current.go +++ b/cmd/colaris/cmd/current.go @@ -10,9 +10,7 @@ import ( "time" "github.com/aergoio/aergo/v2/cmd/aergocli/util" - - "github.com/mr-tron/base58/base58" - + "github.com/aergoio/aergo/v2/internal/enc/base58" "github.com/aergoio/aergo/v2/types" "github.com/spf13/cobra" ) diff --git a/config/hardfork_gen.go b/config/hardfork_gen.go index 9d68c5f32..c3c96bf6d 100644 --- a/config/hardfork_gen.go +++ b/config/hardfork_gen.go @@ -47,7 +47,6 @@ func (dc HardforkDbConfig) FixDbConfig(hConfig HardforkConfig) HardforkDbConfig return dc } - func (c *HardforkConfig) IsV2Fork(h types.BlockNo) bool { return isFork(c.V2, h) } @@ -81,7 +80,7 @@ func (c *HardforkConfig) Version(h types.BlockNo) int32 { func (c *HardforkConfig) Height(verStr string) types.BlockNo { v := reflect.ValueOf(c) - f := reflect.Indirect(v).FieldByName(verStr) + f := reflect.Indirect(v).FieldByName(verStr) return types.BlockNo(f.Uint()) } diff --git a/consensus/chain/block.go b/consensus/chain/block.go index d81aa4649..01b712d22 100644 --- a/consensus/chain/block.go +++ b/consensus/chain/block.go @@ -7,7 +7,7 @@ import ( "time" "github.com/aergoio/aergo/v2/chain" - "github.com/aergoio/aergo/v2/internal/enc" + "github.com/aergoio/aergo/v2/internal/enc/base58" "github.com/aergoio/aergo/v2/message" "github.com/aergoio/aergo/v2/pkg/component" "github.com/aergoio/aergo/v2/state" @@ -124,7 +124,7 @@ func (g *BlockGenerator) Rejected() *RejTxInfo { // SetTimeoutTx set bState.timeoutTx to tx. func (g *BlockGenerator) SetTimeoutTx(tx types.Transaction) { - logger.Warn().Str("hash", enc.ToString(tx.GetHash())).Msg("timeout tx marked for eviction") + logger.Warn().Str("hash", base58.Encode(tx.GetHash())).Msg("timeout tx marked for eviction") g.bState.SetTimeoutTx(tx) } @@ -211,7 +211,7 @@ func ConnectBlock(hs component.ICompSyncRequester, block *types.Block, blockStat func SyncChain(hs *component.ComponentHub, targetHash []byte, targetNo types.BlockNo, peerID types.PeerID) error { logger.Info().Stringer("peer", types.LogPeerShort(peerID)).Uint64("no", targetNo). - Str("hash", enc.ToString(targetHash)).Msg("request to sync for consensus") + Str("hash", base58.Encode(targetHash)).Msg("request to sync for consensus") notiC := make(chan error) hs.Tell(message.SyncerSvc, &message.SyncStart{PeerID: peerID, TargetNo: targetNo, NotifyC: notiC}) @@ -221,7 +221,7 @@ func SyncChain(hs *component.ComponentHub, targetHash []byte, targetNo types.Blo case err := <-notiC: if err != nil { logger.Error().Err(err).Uint64("no", targetNo). - Str("hash", enc.ToString(targetHash)). + Str("hash", base58.Encode(targetHash)). Msg("failed to sync") return err diff --git a/consensus/chain/tx.go b/consensus/chain/tx.go index 9d8412c68..a9af96d20 100644 --- a/consensus/chain/tx.go +++ b/consensus/chain/tx.go @@ -13,11 +13,11 @@ import ( "github.com/aergoio/aergo-lib/log" "github.com/aergoio/aergo/v2/chain" "github.com/aergoio/aergo/v2/contract" + "github.com/aergoio/aergo/v2/internal/enc/proto" "github.com/aergoio/aergo/v2/message" "github.com/aergoio/aergo/v2/pkg/component" "github.com/aergoio/aergo/v2/state" "github.com/aergoio/aergo/v2/types" - "github.com/golang/protobuf/proto" ) var ( diff --git a/consensus/impl/dpos/blockfactory.go b/consensus/impl/dpos/blockfactory.go index b3e291f8a..3643f2c0c 100644 --- a/consensus/impl/dpos/blockfactory.go +++ b/consensus/impl/dpos/blockfactory.go @@ -19,7 +19,7 @@ import ( "github.com/aergoio/aergo/v2/consensus/impl/dpos/slot" "github.com/aergoio/aergo/v2/contract" "github.com/aergoio/aergo/v2/contract/system" - "github.com/aergoio/aergo/v2/internal/enc" + "github.com/aergoio/aergo/v2/internal/enc/base58" "github.com/aergoio/aergo/v2/p2p/p2pkey" "github.com/aergoio/aergo/v2/pkg/component" "github.com/aergoio/aergo/v2/state" @@ -239,7 +239,7 @@ func (bf *BlockFactory) generateBlock(execCtx context.Context, bpi *bpInfo, lpbN bpi.bestBlock.GetHeader().GetBlocksRootHash(), state.SetPrevBlockHash(bpi.bestBlock.BlockHash()), ) - bs.SetGasPrice(system.GetGasPriceFromState(bs)) + bs.SetGasPrice(system.GetGasPrice()) bs.Receipts().SetHardFork(bf.bv, bi.No) bGen := chain.NewBlockGenerator( @@ -264,7 +264,7 @@ func (bf *BlockFactory) generateBlock(execCtx context.Context, bpi *bpInfo, lpbN logger.Info(). Str("BP", bf.ID).Str("id", block.ID()). - Str("sroot", enc.ToString(block.GetHeader().GetBlocksRootHash())). + Str("sroot", base58.Encode(block.GetHeader().GetBlocksRootHash())). Uint64("no", block.BlockNo()).Uint64("confirms", block.Confirms()). Uint64("lpb", lpbNo). Msg("block produced") @@ -277,7 +277,7 @@ func (bf *BlockFactory) rejected() *chain.RejTxInfo { } func (bf *BlockFactory) setRejected(rej *chain.RejTxInfo) { - logger.Warn().Str("hash", enc.ToString(rej.Hash())).Msg("timeout tx reserved for rescheduling") + logger.Warn().Str("hash", base58.Encode(rej.Hash())).Msg("timeout tx reserved for rescheduling") bf.recentRejectedTx = rej } diff --git a/consensus/impl/dpos/bp/cluster.go b/consensus/impl/dpos/bp/cluster.go index 00447e060..7a97f2ead 100644 --- a/consensus/impl/dpos/bp/cluster.go +++ b/consensus/impl/dpos/bp/cluster.go @@ -16,7 +16,7 @@ import ( "github.com/aergoio/aergo-lib/log" "github.com/aergoio/aergo/v2/consensus" "github.com/aergoio/aergo/v2/contract/system" - "github.com/aergoio/aergo/v2/internal/common" + "github.com/aergoio/aergo/v2/internal/enc/gob" "github.com/aergoio/aergo/v2/state" "github.com/aergoio/aergo/v2/types" "github.com/davecgh/go-spew/spew" @@ -287,7 +287,7 @@ func buildKey(blockNo types.BlockNo) []byte { // Value returns s.list. func (s *Snapshot) Value() []byte { - b, err := common.GobEncode(s.List) + b, err := gob.Encode(s.List) if err != nil { logger.Debug().Err(err).Msg("BP list encoding failed") return nil diff --git a/consensus/impl/dpos/lib.go b/consensus/impl/dpos/lib.go index e6c825196..c6937a748 100644 --- a/consensus/impl/dpos/lib.go +++ b/consensus/impl/dpos/lib.go @@ -7,15 +7,13 @@ import ( "github.com/aergoio/aergo-lib/db" "github.com/aergoio/aergo/v2/consensus" - "github.com/aergoio/aergo/v2/internal/common" + "github.com/aergoio/aergo/v2/internal/enc/gob" "github.com/aergoio/aergo/v2/p2p/p2pkey" "github.com/aergoio/aergo/v2/types" + "github.com/aergoio/aergo/v2/types/dbkey" "github.com/davecgh/go-spew/spew" ) -// LibStatusKey is the key when a LIB information is put into the chain DB. -var LibStatusKey = []byte("dpos.LibStatus") - type errLibUpdate struct { current string parent string @@ -237,12 +235,12 @@ func (ls *libStatus) load(endBlockNo types.BlockNo) { } func (ls *libStatus) save(tx consensus.TxWriter) error { - b, err := common.GobEncode(ls) + b, err := gob.Encode(ls) if err != nil { return err } - tx.Set(LibStatusKey, b) + tx.Set(dbkey.DposLibStatus(), b) logger.Debug().Int("proposed lib len", len(ls.Prpsd)).Msg("lib status stored to DB") @@ -250,7 +248,7 @@ func (ls *libStatus) save(tx consensus.TxWriter) error { } func reset(tx db.Transaction) { - tx.Delete(LibStatusKey) + tx.Delete(dbkey.DposLibStatus()) } func (ls *libStatus) gc(bps []string) { @@ -385,7 +383,7 @@ func newConfirmInfo(block *types.Block, confirmsRequired uint16) *confirmInfo { func (bs *bootLoader) loadLibStatus() *libStatus { pls := newLibStatus(bs.confirmsRequired) - if err := bs.decodeStatus(LibStatusKey, pls); err != nil { + if err := bs.decodeStatus(dbkey.DposLibStatus(), pls); err != nil { return nil } pls.load(bs.best.BlockNo()) @@ -399,7 +397,7 @@ func (bs *bootLoader) decodeStatus(key []byte, dst interface{}) error { return fmt.Errorf("LIB status not found: key = %v", string(key)) } - err := common.GobDecode(value, dst) + err := gob.Decode(value, dst) if err != nil { logger.Panic().Err(err).Str("key", string(key)). Msg("failed to decode DPoS status") diff --git a/consensus/impl/dpos/lib_test.go b/consensus/impl/dpos/lib_test.go index 0128398f8..b5c506afd 100644 --- a/consensus/impl/dpos/lib_test.go +++ b/consensus/impl/dpos/lib_test.go @@ -3,7 +3,7 @@ package dpos import ( "testing" - "github.com/aergoio/aergo/v2/internal/enc" + "github.com/aergoio/aergo/v2/internal/enc/base58" "github.com/aergoio/aergo/v2/types" "github.com/libp2p/go-libp2p-core/crypto" "github.com/stretchr/testify/assert" @@ -50,7 +50,7 @@ func newTestChain(clusterSize uint16) (*testChain, error) { tc := &testChain{ chain: make([]*types.Block, 0), status: NewStatus(&testCluster{size: clusterSize}, nil, nil, 0), - bpid: enc.ToString(b), + bpid: base58.Encode(b), lpb: make(map[string]types.BlockNo), bpKey: bpKey, bpClusterSize: clusterSize, @@ -78,7 +78,7 @@ func (tc *testChain) addBlock(i types.BlockNo) error { if err != nil { return err } - spk := enc.ToString(b) + spk := base58.Encode(b) prevBlock := tc.chain[len(tc.chain)-1] block := newBlockFromPrev(prevBlock, 0, types.DummyBlockVersionner(0)) diff --git a/consensus/impl/dpos/status.go b/consensus/impl/dpos/status.go index 8fa303a02..b6e8f739c 100644 --- a/consensus/impl/dpos/status.go +++ b/consensus/impl/dpos/status.go @@ -6,6 +6,7 @@ import ( "github.com/aergoio/aergo/v2/consensus" "github.com/aergoio/aergo/v2/consensus/impl/dpos/bp" + "github.com/aergoio/aergo/v2/contract/system" "github.com/aergoio/aergo/v2/state" "github.com/aergoio/aergo/v2/types" ) @@ -83,6 +84,10 @@ func (s *Status) Update(block *types.Block) { } bps, _ = s.bps.AddSnapshot(block.BlockNo()) + + // if a system param was changed, apply its new value + system.CommitParams(true) + } else { // Rollback resulting from a reorganization: The code below assumes // that there is no block-by-block rollback; it assumes that the @@ -109,6 +114,11 @@ func (s *Status) Update(block *types.Block) { } else { logger.Debug().Uint64("from block no", block.BlockNo()).Msg("VPR reloaded") } + + // if a system param was changed, discard its new value + // this is mainly for block revert case + // the params are reloaded from db on block reorganization + system.CommitParams(false) } s.libState.gc(bps) diff --git a/consensus/impl/raftv2/blockfactory.go b/consensus/impl/raftv2/blockfactory.go index 72d3079d3..5aa478851 100644 --- a/consensus/impl/raftv2/blockfactory.go +++ b/consensus/impl/raftv2/blockfactory.go @@ -19,7 +19,7 @@ import ( "github.com/aergoio/aergo/v2/consensus/chain" "github.com/aergoio/aergo/v2/contract" "github.com/aergoio/aergo/v2/contract/system" - "github.com/aergoio/aergo/v2/internal/enc" + "github.com/aergoio/aergo/v2/internal/enc/base58" "github.com/aergoio/aergo/v2/p2p/p2pcommon" "github.com/aergoio/aergo/v2/p2p/p2pkey" "github.com/aergoio/aergo/v2/pkg/component" @@ -523,7 +523,7 @@ func (bf *BlockFactory) generateBlock(work *Work) (*types.Block, *state.BlockSta bestBlock.GetHeader().GetBlocksRootHash(), state.SetPrevBlockHash(bestBlock.BlockHash()), ) - blockState.SetGasPrice(system.GetGasPriceFromState(blockState)) + blockState.SetGasPrice(system.GetGasPrice()) blockState.Receipts().SetHardFork(bf.bv, bi.No) block, err := chain.NewBlockGenerator(bf, work.execCtx, bi, blockState, txOp, RaftSkipEmptyBlock).GenerateBlock() @@ -541,7 +541,7 @@ func (bf *BlockFactory) generateBlock(work *Work) (*types.Block, *state.BlockSta } logger.Info().Str("blockProducer", bf.ID).Str("raftID", EtcdIDToString(bf.bpc.NodeID())). - Str("sroot", enc.ToString(block.GetHeader().GetBlocksRootHash())). + Str("sroot", base58.Encode(block.GetHeader().GetBlocksRootHash())). Uint64("no", block.GetHeader().GetBlockNo()). Str("hash", block.ID()). Msg("block produced") diff --git a/consensus/impl/raftv2/cluster.go b/consensus/impl/raftv2/cluster.go index 2cf27b7cb..21b68c6b2 100644 --- a/consensus/impl/raftv2/cluster.go +++ b/consensus/impl/raftv2/cluster.go @@ -14,7 +14,7 @@ import ( "github.com/aergoio/aergo/v2/cmd/aergocli/util" "github.com/aergoio/aergo/v2/consensus" - "github.com/aergoio/aergo/v2/internal/enc" + "github.com/aergoio/aergo/v2/internal/enc/base58" "github.com/aergoio/aergo/v2/message" "github.com/aergoio/aergo/v2/pkg/component" "github.com/aergoio/aergo/v2/types" @@ -409,7 +409,7 @@ func (cl *Cluster) isValidMember(member *consensus.Member) error { } // check if peerID of this node is valid - if cl.NodeName() == member.Name && enc.ToString([]byte(member.GetPeerID())) != cl.NodePeerID() { + if cl.NodeName() == member.Name && base58.Encode([]byte(member.GetPeerID())) != cl.NodePeerID() { logger.Error().Str("config", member.GetPeerID().String()).Str("cluster peerid", cl.NodePeerID()).Msg("peerID value is not matched with P2P") return ErrInvalidRaftPeerID } @@ -433,7 +433,7 @@ func (cl *Cluster) addMember(member *consensus.Member, applied bool) error { // notify to p2p TODO temporary code peerID, err := types.IDFromBytes(member.PeerID) if err != nil { - logger.Panic().Err(err).Str("peerid", enc.ToString(member.PeerID)).Msg("invalid member peerid") + logger.Panic().Err(err).Str("peerid", base58.Encode(member.PeerID)).Msg("invalid member peerid") } if cl.notifyFn != nil { @@ -466,7 +466,7 @@ func (cl *Cluster) removeMember(member *consensus.Member) error { // notify to p2p TODO temporary code peerID, err := types.IDFromBytes(member.PeerID) if err != nil { - logger.Panic().Err(err).Str("peerid", enc.ToString(member.PeerID)).Msg("invalid member peerid") + logger.Panic().Err(err).Str("peerid", base58.Encode(member.PeerID)).Msg("invalid member peerid") } if cl.notifyFn != nil { @@ -494,7 +494,7 @@ func (cl *Cluster) ValidateAndMergeExistingCluster(existingCl *Cluster) bool { } // TODO check my network config is equal to member of remote - if enc.ToString(remoteMember.PeerID) != cl.NodePeerID() { + if base58.Encode(remoteMember.PeerID) != cl.NodePeerID() { logger.Error().Msg("peerid is different with peerid of member of existing cluster") } diff --git a/consensus/impl/raftv2/raftserver.go b/consensus/impl/raftv2/raftserver.go index 33307fa20..f514d6465 100644 --- a/consensus/impl/raftv2/raftserver.go +++ b/consensus/impl/raftv2/raftserver.go @@ -30,6 +30,7 @@ import ( "github.com/aergoio/aergo/v2/chain" "github.com/aergoio/aergo/v2/consensus" + "github.com/aergoio/aergo/v2/internal/enc/proto" "github.com/aergoio/aergo/v2/message" "github.com/aergoio/aergo/v2/p2p/p2pcommon" "github.com/aergoio/aergo/v2/pkg/component" @@ -40,7 +41,6 @@ import ( "github.com/aergoio/etcd/raft/raftpb" "github.com/aergoio/etcd/rafthttp" "github.com/aergoio/etcd/snap" - "github.com/golang/protobuf/proto" ) const ( @@ -1527,7 +1527,7 @@ func (rs *raftServer) GetExistingCluster() (*Cluster, *types.HardStateInfo, erro func marshalEntryData(block *types.Block) ([]byte, error) { var data []byte var err error - if data, err = proto.Marshal(block); err != nil { + if data, err = proto.Encode(block); err != nil { logger.Fatal().Err(err).Msg("poposed data is invalid") } @@ -1540,7 +1540,7 @@ var ( func unmarshalEntryData(data []byte) (*types.Block, error) { block := &types.Block{} - if err := proto.Unmarshal(data, block); err != nil { + if err := proto.Decode(data, block); err != nil { return block, ErrUnmarshal } diff --git a/consensus/impl/sbp/sbp.go b/consensus/impl/sbp/sbp.go index dd69af88c..47f3f5bae 100644 --- a/consensus/impl/sbp/sbp.go +++ b/consensus/impl/sbp/sbp.go @@ -12,7 +12,7 @@ import ( "github.com/aergoio/aergo/v2/consensus/chain" "github.com/aergoio/aergo/v2/contract" "github.com/aergoio/aergo/v2/contract/system" - "github.com/aergoio/aergo/v2/internal/enc" + "github.com/aergoio/aergo/v2/internal/enc/base58" "github.com/aergoio/aergo/v2/pkg/component" "github.com/aergoio/aergo/v2/state" "github.com/aergoio/aergo/v2/types" @@ -190,7 +190,7 @@ func (s *SimpleBlockFactory) Start() { prevBlock.GetHeader().GetBlocksRootHash(), state.SetPrevBlockHash(prevBlock.BlockHash()), ) - blockState.SetGasPrice(system.GetGasPriceFromState(blockState)) + blockState.SetGasPrice(system.GetGasPrice()) blockState.Receipts().SetHardFork(s.bv, bi.No) txOp := chain.NewCompTxOp(s.txOp, newTxExec(s.ChainDB, bi)) @@ -202,7 +202,7 @@ func (s *SimpleBlockFactory) Start() { continue } logger.Info().Uint64("no", block.GetHeader().GetBlockNo()).Str("hash", block.ID()). - Str("TrieRoot", enc.ToString(block.GetHeader().GetBlocksRootHash())). + Str("TrieRoot", base58.Encode(block.GetHeader().GetBlocksRootHash())). Err(err).Msg("block produced") chain.ConnectBlock(s, block, blockState, time.Second) diff --git a/consensus/raftCommon.go b/consensus/raftCommon.go index 4bcbd42f4..eefd26d5b 100644 --- a/consensus/raftCommon.go +++ b/consensus/raftCommon.go @@ -5,13 +5,13 @@ import ( "context" "crypto/sha1" "encoding/binary" - "encoding/gob" "encoding/json" "errors" "fmt" "io" - "github.com/aergoio/aergo/v2/internal/enc" + "github.com/aergoio/aergo/v2/internal/enc/base58" + "github.com/aergoio/aergo/v2/internal/enc/gob" "github.com/aergoio/aergo/v2/types" "github.com/aergoio/etcd/raft" "github.com/aergoio/etcd/raft/raftpb" @@ -59,13 +59,7 @@ type WalEntry struct { } func (we *WalEntry) ToBytes() ([]byte, error) { - var val bytes.Buffer - encoder := gob.NewEncoder(&val) - if err := encoder.Encode(we); err != nil { - logger.Panic().Err(err).Msg("raft entry to bytes error") - } - - return val.Bytes(), nil + return gob.Encode(we) } func (we *WalEntry) ToString() string { @@ -203,7 +197,7 @@ func (csnap *ChainSnapshot) ToString() string { if csnap == nil || csnap.Hash == nil { return "csnap: empty" } - return fmt.Sprintf("chainsnap:(no=%d, hash=%s)", csnap.No, enc.ToString(csnap.Hash)) + return fmt.Sprintf("chainsnap:(no=%d, hash=%s)", csnap.No, base58.Encode(csnap.Hash)) } /* diff --git a/contract/contract.go b/contract/contract.go index 8c2b24df0..63e9f12a4 100644 --- a/contract/contract.go +++ b/contract/contract.go @@ -12,6 +12,7 @@ import ( "github.com/aergoio/aergo/v2/fee" "github.com/aergoio/aergo/v2/state" "github.com/aergoio/aergo/v2/types" + "github.com/aergoio/aergo/v2/types/dbkey" "github.com/minio/sha256-simd" ) @@ -68,10 +69,16 @@ func SetPreloadTx(tx *types.Tx, service int) { // Execute executes a normal transaction which is possibly executing smart contract. func Execute(execCtx context.Context, bs *state.BlockState, cdb ChainAccessor, tx *types.Tx, sender, receiver *state.V, bi *types.BlockHeaderInfo, preloadService int, isFeeDelegation bool) (rv string, events []*types.Event, usedFee *big.Int, err error) { - txBody := tx.GetBody() + var ( + txBody = tx.GetBody() + txType = txBody.GetType() + txPayload = txBody.GetPayload() + txAmount = txBody.GetAmountBigInt() + txGasLimit = txBody.GetGasLimit() + ) // compute the base fee - usedFee = TxFee(len(txBody.GetPayload()), bs.GasPrice, bi.ForkVersion) + usedFee = fee.TxBaseFee(bi.ForkVersion, bs.GasPrice, len(txPayload)) // check if sender and receiver are not the same if sender.AccountID() != receiver.AccountID() { @@ -85,53 +92,17 @@ func Execute(execCtx context.Context, bs *state.BlockState, cdb ChainAccessor, t receiver.AddBalance(txBody.GetAmountBigInt()) } - // check if the receiver is a not contract - if !receiver.IsDeploy() && len(receiver.State().CodeHash) == 0 { - // Before the chain version 3, any tx with no code hash is - // unconditionally executed as a simple Aergo transfer. Since this - // causes confusion, emit error for call-type tx with a wrong address - // from the chain version 3 by not returning error but fall-through for - // correct gas estimation. - if !(bi.ForkVersion >= 3 && txBody.Type == types.TxType_CALL) { - // Here, the condition for fee delegation TX essentially being - // call-type, is not necessary, because it is rejected from the - // mempool without code hash. - return - } + // check if the tx is valid and if the code should be executed + var do_execute bool + if do_execute, err = checkExecution(txType, txAmount, len(txPayload), bi.ForkVersion, receiver.IsDeploy(), receiver.IsContract()); do_execute != true { + return } + // compute gas limit var gasLimit uint64 - if useGas(bi.ForkVersion) { - if isFeeDelegation { - // check if the contract has enough balance for fee - balance := new(big.Int).Sub(receiver.Balance(), usedFee) - gasLimit = fee.MaxGasLimit(balance, bs.GasPrice) - if gasLimit == 0 { - err = newVmError(types.ErrNotEnoughGas) - return - } - } else { - // read the gas limit from the tx - gasLimit = txBody.GetGasLimit() - if gasLimit == 0 { - // no gas limit specified, the limit is the sender's balance - balance := new(big.Int).Sub(sender.Balance(), usedFee) - gasLimit = fee.MaxGasLimit(balance, bs.GasPrice) - if gasLimit == 0 { - err = newVmError(types.ErrNotEnoughGas) - return - } - } else { - // check if the sender has enough balance for gas - usedGas := fee.TxGas(len(txBody.GetPayload())) - if gasLimit <= usedGas { - err = newVmError(types.ErrNotEnoughGas) - return - } - // subtract the used gas from the gas limit - gasLimit -= usedGas - } - } + if gasLimit, err = fee.GasLimit(bi.ForkVersion, isFeeDelegation, txGasLimit, len(txPayload), bs.GasPrice, usedFee, sender.Balance(), receiver.Balance()); err != nil { + err = newVmError(types.ErrNotEnoughGas) + return } // open the contract state @@ -232,17 +203,6 @@ func Execute(execCtx context.Context, bs *state.BlockState, cdb ChainAccessor, t return rv, events, usedFee, nil } -// compute the base fee for a transaction -func TxFee(payloadSize int, GasPrice *big.Int, version int32) *big.Int { - if version < 2 { - return fee.PayloadTxFee(payloadSize) - } - // get the amount of gas needed for the payload - txGas := fee.TxGas(payloadSize) - // multiply the amount of gas with the gas price - return new(big.Int).Mul(new(big.Int).SetUint64(txGas), GasPrice) -} - // send a request to preload an executor for the next tx func RequestPreload(bs *state.BlockState, bi *types.BlockHeaderInfo, next, current *types.Tx, preloadService int) { loadReqCh <- &preloadRequest{preloadService, bs, bi, next, current} @@ -301,7 +261,7 @@ func preloadWorker() { } // when deploy and call in same block and not deployed yet - if receiver.IsNew() || len(receiver.State().CodeHash) == 0 { + if receiver.IsNew() || !receiver.IsContract() { // do not preload an executor for a contract that is not deployed yet replyCh <- &preloadReply{tx, nil, nil} continue @@ -329,6 +289,29 @@ func preloadWorker() { } } +// check if the tx is valid and if the code should be executed +func checkExecution(txType types.TxType, amount *big.Int, payloadSize int, version int32, isDeploy, isContract bool) (do_execute bool, err error) { + + // check if the receiver is a not contract + if !isDeploy && !isContract { + // before the hardfork version 3, all transactions in which the recipient + // is not a contract were processed as a simple Aergo transfer, including + // type CALL and FEEDELEGATION. + // starting from hardfork version 3, transactions expected to CALL a + // contract but without a valid recipient will emit an error. + // FEEDELEGATION txns with invalid recipient are rejected on mempool. + if version >= 3 && txType == types.TxType_CALL { + // continue and emit an error for correct gas estimation + // it will fail because there is no code to execute + } else { + // no code to execute, just return + return false, nil + } + } + + return true, nil +} + func CreateContractID(account []byte, nonce uint64) []byte { h := sha256.New() h.Write(account) @@ -339,13 +322,13 @@ func CreateContractID(account []byte, nonce uint64) []byte { func checkRedeploy(sender, receiver *state.V, contractState *state.ContractState) error { // check if the contract exists - if len(receiver.State().CodeHash) == 0 || receiver.IsNew() { + if !receiver.IsContract() || receiver.IsNew() { receiverAddr := types.EncodeAddress(receiver.ID()) ctrLgr.Warn().Str("error", "not found contract").Str("contract", receiverAddr).Msg("redeploy") return newVmError(fmt.Errorf("not found contract %s", receiverAddr)) } // get the contract creator - creator, err := contractState.GetData(creatorMetaKey) + creator, err := contractState.GetData(dbkey.CreatorMeta()) if err != nil { return err } @@ -357,17 +340,6 @@ func checkRedeploy(sender, receiver *state.V, contractState *state.ContractState return nil } -func useGas(version int32) bool { - return version >= 2 && PubNet -} - -func GasUsed(txFee, gasPrice *big.Int, txType types.TxType, version int32) uint64 { - if fee.IsZeroFee() || txType == types.TxType_GOVERNANCE || version < 2 { - return 0 - } - return new(big.Int).Div(txFee, gasPrice).Uint64() -} - func SetStateSQLMaxDBSize(size uint64) { if size > stateSQLMaxDBSize { maxSQLDBSize = stateSQLMaxDBSize @@ -376,7 +348,7 @@ func SetStateSQLMaxDBSize(size uint64) { } else { maxSQLDBSize = size } - sqlLgr.Info().Uint64("size", maxSQLDBSize).Msg("set max database size(MB)") + //sqlLgr.Info().Uint64("size", maxSQLDBSize).Msg("set max database size(MB)") } func StrHash(d string) []byte { diff --git a/contract/contract_test.go b/contract/contract_test.go new file mode 100644 index 000000000..eaa254eea --- /dev/null +++ b/contract/contract_test.go @@ -0,0 +1,87 @@ +package contract + +import ( + "math/big" + "testing" + + "github.com/aergoio/aergo/v2/types" + "github.com/stretchr/testify/assert" +) + +func initContractTest(t *testing.T) { + PubNet = true +} + +func deinitContractTest(t *testing.T) { + PubNet = false +} + +func TestCheckExecution(t *testing.T) { + initContractTest(t) + defer deinitContractTest(t) + + for _, test := range []struct { + version int32 + txType types.TxType + amount *big.Int + payloadSize int + isDeploy bool + isContract bool + + expectErr error + expectExec bool + }{ + // deploy + {version: 2, txType: types.TxType_NORMAL, amount: types.NewAmount(1, types.Aergo), payloadSize: 1000, isDeploy: true, isContract: false, expectErr: nil, expectExec: true}, + {version: 2, txType: types.TxType_DEPLOY, amount: types.NewAmount(1, types.Aergo), payloadSize: 1000, isDeploy: true, isContract: false, expectErr: nil, expectExec: true}, + {version: 2, txType: types.TxType_REDEPLOY, amount: types.NewAmount(1, types.Aergo), payloadSize: 1000, isDeploy: true, isContract: false, expectErr: nil, expectExec: true}, + {version: 3, txType: types.TxType_NORMAL, amount: types.NewAmount(1, types.Aergo), payloadSize: 1000, isDeploy: true, isContract: false, expectErr: nil, expectExec: true}, + {version: 3, txType: types.TxType_DEPLOY, amount: types.NewAmount(1, types.Aergo), payloadSize: 1000, isDeploy: true, isContract: false, expectErr: nil, expectExec: true}, + {version: 3, txType: types.TxType_REDEPLOY, amount: types.NewAmount(1, types.Aergo), payloadSize: 1000, isDeploy: true, isContract: false, expectErr: nil, expectExec: true}, + // recipient is contract + {version: 2, txType: types.TxType_NORMAL, amount: types.NewAmount(1, types.Aergo), payloadSize: 1000, isDeploy: false, isContract: true, expectErr: nil, expectExec: true}, + {version: 2, txType: types.TxType_TRANSFER, amount: types.NewAmount(1, types.Aergo), payloadSize: 1000, isDeploy: false, isContract: true, expectErr: nil, expectExec: true}, + {version: 2, txType: types.TxType_CALL, amount: types.NewAmount(1, types.Aergo), payloadSize: 1000, isDeploy: false, isContract: true, expectErr: nil, expectExec: true}, + {version: 2, txType: types.TxType_FEEDELEGATION, amount: types.NewAmount(1, types.Aergo), payloadSize: 1000, isDeploy: false, isContract: true, expectErr: nil, expectExec: true}, + {version: 3, txType: types.TxType_NORMAL, amount: types.NewAmount(1, types.Aergo), payloadSize: 1000, isDeploy: false, isContract: true, expectErr: nil, expectExec: true}, + {version: 3, txType: types.TxType_TRANSFER, amount: types.NewAmount(1, types.Aergo), payloadSize: 1000, isDeploy: false, isContract: true, expectErr: nil, expectExec: true}, + {version: 3, txType: types.TxType_CALL, amount: types.NewAmount(1, types.Aergo), payloadSize: 1000, isDeploy: false, isContract: true, expectErr: nil, expectExec: true}, + {version: 3, txType: types.TxType_FEEDELEGATION, amount: types.NewAmount(1, types.Aergo), payloadSize: 1000, isDeploy: false, isContract: true, expectErr: nil, expectExec: true}, + // recipient is not a contract + {version: 2, txType: types.TxType_NORMAL, amount: types.NewAmount(1, types.Aergo), payloadSize: 1000, isDeploy: false, isContract: false, expectErr: nil, expectExec: false}, + {version: 2, txType: types.TxType_TRANSFER, amount: types.NewAmount(1, types.Aergo), payloadSize: 1000, isDeploy: false, isContract: false, expectErr: nil, expectExec: false}, + {version: 2, txType: types.TxType_CALL, amount: types.NewAmount(1, types.Aergo), payloadSize: 1000, isDeploy: false, isContract: false, expectErr: nil, expectExec: false}, + {version: 2, txType: types.TxType_FEEDELEGATION, amount: types.NewAmount(1, types.Aergo), payloadSize: 1000, isDeploy: false, isContract: false, expectErr: nil, expectExec: false}, + {version: 3, txType: types.TxType_NORMAL, amount: types.NewAmount(1, types.Aergo), payloadSize: 1000, isDeploy: false, isContract: false, expectErr: nil, expectExec: false}, + {version: 3, txType: types.TxType_TRANSFER, amount: types.NewAmount(1, types.Aergo), payloadSize: 1000, isDeploy: false, isContract: false, expectErr: nil, expectExec: false}, + {version: 3, txType: types.TxType_CALL, amount: types.NewAmount(1, types.Aergo), payloadSize: 1000, isDeploy: false, isContract: false, expectErr: nil, expectExec: true}, + {version: 3, txType: types.TxType_FEEDELEGATION, amount: types.NewAmount(1, types.Aergo), payloadSize: 1000, isDeploy: false, isContract: false, expectErr: nil, expectExec: false}, + } { + do_execute, err := checkExecution(test.txType, test.amount, test.payloadSize, test.version, test.isDeploy, test.isContract) + assert.Equal(t, test.expectErr, err, "checkExecution(version:%d, txType:%d, amount:%s, payloadSize:%d)", test.version, test.txType, test.amount, test.payloadSize) + assert.Equal(t, test.expectExec, do_execute, "checkExecution(version:%d, txType:%d, amount:%s, payloadSize:%d)", test.version, test.txType, test.amount, test.payloadSize) + } +} + +//----------------------------------------------------------------------------------------// +// tests for chain / block factory functions + +func TestCreateContractID(t *testing.T) { + initContractTest(t) + defer deinitContractTest(t) + + for _, test := range []struct { + account []byte + nonce uint64 + expectContractID []byte + }{ + // purpose to detect logic change + {[]byte{0x01}, 0, []byte{0xc, 0x44, 0xc8, 0x8, 0xfd, 0x16, 0x6d, 0xbb, 0x89, 0x61, 0xfb, 0x79, 0x55, 0x87, 0xe5, 0xee, 0x0, 0x82, 0xf8, 0xa2, 0xdc, 0x78, 0x1f, 0xf0, 0x6a, 0x3f, 0x2, 0x22, 0x3d, 0xcc, 0x6, 0xa7, 0xda}}, + {[]byte{0x01}, 1, []byte{0xc, 0xf1, 0x6b, 0xa6, 0xfa, 0x61, 0xda, 0x33, 0x98, 0x81, 0x5b, 0xe2, 0xa6, 0xc0, 0xf7, 0xcb, 0x13, 0x51, 0x98, 0x2d, 0xbc, 0xc6, 0xc6, 0x4b, 0xbe, 0xb9, 0xb6, 0x5f, 0x67, 0x2a, 0x8b, 0x10, 0x2a}}, + {[]byte{0xFF}, 0, []byte{0xc, 0x65, 0x1c, 0xb3, 0x16, 0x99, 0xd4, 0xd, 0xd0, 0xd0, 0x94, 0x44, 0xc7, 0xd7, 0x41, 0x87, 0xa0, 0xee, 0xcb, 0x4c, 0xbc, 0x2b, 0x1b, 0x4, 0x61, 0xbc, 0x4a, 0x3f, 0x1a, 0x5f, 0x97, 0x2e, 0xdb}}, + {[]byte{0xFF}, 1, []byte{0xc, 0x71, 0x36, 0x9f, 0x7c, 0x97, 0x5c, 0xf, 0x86, 0x19, 0x57, 0xbc, 0x6, 0x4, 0x28, 0x1e, 0x86, 0x37, 0x6a, 0x12, 0xd7, 0x1e, 0xe7, 0xf6, 0x2f, 0x98, 0xab, 0x14, 0xbe, 0x4d, 0xf5, 0xd4, 0x56}}, + } { + resultContractID := CreateContractID(test.account, test.nonce) + assert.Equal(t, test.expectContractID, resultContractID, "CreateContractID(account:%x, nonce:%d)", test.account, test.nonce) + } +} diff --git a/contract/enterprise/admin.go b/contract/enterprise/admin.go index f9874a929..1af6038b0 100644 --- a/contract/enterprise/admin.go +++ b/contract/enterprise/admin.go @@ -5,10 +5,9 @@ import ( "github.com/aergoio/aergo/v2/state" "github.com/aergoio/aergo/v2/types" + "github.com/aergoio/aergo/v2/types/dbkey" ) -const AdminsKey = "ADMINS" - func GetAdmin(r AccountStateReader) (*types.EnterpriseConfig, error) { scs, err := r.GetEnterpriseAccountState() if err != nil { @@ -18,7 +17,7 @@ func GetAdmin(r AccountStateReader) (*types.EnterpriseConfig, error) { if err != nil { return nil, err } - ret := &types.EnterpriseConfig{Key: AdminsKey, On: false} + ret := &types.EnterpriseConfig{Key: string(dbkey.EnterpriseAdmins()), On: false} if admins != nil { ret.On = true for _, admin := range admins { @@ -28,11 +27,11 @@ func GetAdmin(r AccountStateReader) (*types.EnterpriseConfig, error) { return ret, nil } func setAdmins(scs *state.ContractState, addresses [][]byte) error { - return scs.SetData([]byte(AdminsKey), bytes.Join(addresses, []byte(""))) + return scs.SetData(dbkey.EnterpriseAdmins(), bytes.Join(addresses, []byte(""))) } func getAdmins(scs *state.ContractState) ([][]byte, error) { - data, err := scs.GetData([]byte(AdminsKey)) + data, err := scs.GetData(dbkey.EnterpriseAdmins()) if err != nil { return nil, err } diff --git a/contract/enterprise/config.go b/contract/enterprise/config.go index f3bd44d6d..57a33b85c 100644 --- a/contract/enterprise/config.go +++ b/contract/enterprise/config.go @@ -6,10 +6,9 @@ import ( "github.com/aergoio/aergo/v2/state" "github.com/aergoio/aergo/v2/types" + "github.com/aergoio/aergo/v2/types/dbkey" ) -var confPrefix = []byte("conf\\") - const ( RPCPermissions = "RPCPERMISSIONS" P2PWhite = "P2PWHITE" @@ -49,7 +48,7 @@ func (c *Conf) Validate(key []byte, context *EnterpriseContext) error { if !c.On { return nil } - strKey := string(key) + strKey := strings.ToUpper(string(key)) switch strKey { case RPCPermissions: for _, v := range c.Values { @@ -113,7 +112,7 @@ func enableConf(scs *state.ContractState, key []byte, value bool) (*Conf, error) } func getConf(scs *state.ContractState, key []byte) (*Conf, error) { - data, err := scs.GetData(append(confPrefix, genKey(key)...)) + data, err := scs.GetData(dbkey.EnterpriseConf(key)) if err != nil || data == nil { return nil, err } @@ -134,7 +133,7 @@ func setConfValues(scs *state.ContractState, key []byte, values []string) (*Conf } func setConf(scs *state.ContractState, key []byte, conf *Conf) error { - return scs.SetData(append(confPrefix, genKey(key)...), serializeConf(conf)) + return scs.SetData(dbkey.EnterpriseConf(key), serializeConf(conf)) } func serializeConf(c *Conf) []byte { @@ -161,7 +160,3 @@ func deserializeConf(data []byte) *Conf { } return ret } - -func genKey(key []byte) []byte { - return []byte(strings.ToUpper(string(key))) -} diff --git a/contract/enterprise/validate.go b/contract/enterprise/validate.go index 142c9bacf..9001362f0 100644 --- a/contract/enterprise/validate.go +++ b/contract/enterprise/validate.go @@ -2,13 +2,13 @@ package enterprise import ( "bytes" - "encoding/base64" "encoding/json" "errors" "fmt" "strings" "github.com/aergoio/aergo/v2/consensus" + "github.com/aergoio/aergo/v2/internal/enc/base64" "github.com/aergoio/aergo/v2/state" "github.com/aergoio/aergo/v2/types" ) @@ -75,7 +75,7 @@ func ValidateEnterpriseTx(tx *types.TxBody, sender *state.V, if err := checkArgs(context, &ci); err != nil { return nil, err } - key := genKey([]byte(context.Args[0])) + key := []byte(context.Args[0]) admins, err := checkAdmin(scs, sender.ID()) if err != nil { return nil, err @@ -112,7 +112,7 @@ func ValidateEnterpriseTx(tx *types.TxBody, sender *state.V, context.Conf = conf context.Admins = admins - key := genKey([]byte(context.Args[0])) + key := []byte(context.Args[0]) if ci.Name == AppendConf { if context.HasConfValue(context.Args[1]) { return nil, fmt.Errorf("already included config value : %v", context.Args) @@ -141,7 +141,7 @@ func ValidateEnterpriseTx(tx *types.TxBody, sender *state.V, return nil, fmt.Errorf("not allowed key : %s", ci.Args[0]) } context.Args = append(context.Args, arg0) - key := genKey([]byte(arg0)) + key := []byte(arg0) value, ok := ci.Args[1].(bool) if !ok { return nil, fmt.Errorf("not bool in payload for enableConf : %s", ci.Args) @@ -265,7 +265,7 @@ func checkRPCPermissions(v string) error { return fmt.Errorf("invalid RPC permission %s", v) } - if _, err := base64.StdEncoding.DecodeString(values[0]); err != nil { + if _, err := base64.Decode(values[0]); err != nil { return fmt.Errorf("invalid RPC cert %s", v) } diff --git a/contract/ethstorageproof.go b/contract/ethstorageproof.go index da50b9902..018c8e9a1 100644 --- a/contract/ethstorageproof.go +++ b/contract/ethstorageproof.go @@ -3,10 +3,10 @@ package contract import ( "bytes" "encoding/binary" - "encoding/hex" "errors" "math" + "github.com/aergoio/aergo/v2/internal/enc/hex" "golang.org/x/crypto/sha3" ) @@ -33,7 +33,7 @@ func verifyEthStorageProof(key []byte, value rlpObject, expectedHash []byte, pro if len(key) == 0 || value == nil || len(proof) == 0 { return false } - key = []byte(hex.EncodeToString(keccak256(key))) + key = []byte(hex.Encode(keccak256(key))) valueRlpEncoded := rlpEncode(value) ks := keyStream{bytes.NewBuffer(key)} for i, p := range proof { @@ -50,7 +50,7 @@ func verifyEthStorageProof(key []byte, value rlpObject, expectedHash []byte, pro if err != nil { return false } - sharedNibbles = append(sharedNibbles, []byte(hex.EncodeToString(n[0][1:]))...) + sharedNibbles = append(sharedNibbles, []byte(hex.Encode(n[0][1:]))...) if len(sharedNibbles) == 0 { return false } @@ -180,7 +180,7 @@ func keccak256(data ...[]byte) []byte { } func keccak256Hex(data ...[]byte) string { - return hex.EncodeToString(keccak256(data...)) + return hex.Encode(keccak256(data...)) } func decodeHpHeader(b byte) (bool, []byte, error) { diff --git a/contract/ethstorageproof_test.go b/contract/ethstorageproof_test.go index e87de30a7..9da60d342 100644 --- a/contract/ethstorageproof_test.go +++ b/contract/ethstorageproof_test.go @@ -2,10 +2,11 @@ package contract import ( "bytes" - "encoding/hex" "fmt" "reflect" "testing" + + "github.com/aergoio/aergo/v2/internal/enc/hex" ) func TestVerify(t *testing.T) { @@ -205,14 +206,14 @@ func removeHexPrefix(s string) string { } func toBytes(s string) []byte { - n, _ := hex.DecodeString(removeHexPrefix(s)) + n, _ := hex.Decode(removeHexPrefix(s)) return n } func proofToBytes(proof []string) [][]byte { var r [][]byte for _, n := range proof { - d, err := hex.DecodeString(removeHexPrefix(n)) + d, err := hex.Decode(removeHexPrefix(n)) if err != nil { return [][]byte{} } diff --git a/contract/hook_dbg.go b/contract/hook_dbg.go index 72f6a05e0..72fba8aba 100644 --- a/contract/hook_dbg.go +++ b/contract/hook_dbg.go @@ -10,11 +10,11 @@ package contract import "C" import ( "container/list" - "encoding/hex" "errors" "fmt" "path/filepath" + "github.com/aergoio/aergo/v2/internal/enc/hex" "github.com/aergoio/aergo/v2/types" ) @@ -43,7 +43,7 @@ func (ce *executor) setCountHook(limit C.int) { } func HexAddrToBase58Addr(contract_id_hex string) (string, error) { - byteContractID, err := hex.DecodeString(contract_id_hex) + byteContractID, err := hex.Decode(contract_id_hex) if err != nil { return "", err } @@ -66,7 +66,7 @@ func HexAddrOrPlainStrToHexAddr(d string) string { } func PlainStrToHexAddr(d string) string { - return hex.EncodeToString(StrHash(d)) + return hex.Encode(StrHash(d)) } func SetBreakPoint(contract_id_hex string, line uint64) error { diff --git a/contract/name/execute.go b/contract/name/execute.go index 68739e853..6dc00e739 100644 --- a/contract/name/execute.go +++ b/contract/name/execute.go @@ -14,23 +14,18 @@ import ( func ExecuteNameTx(bs *state.BlockState, scs *state.ContractState, txBody *types.TxBody, sender, receiver *state.V, blockInfo *types.BlockHeaderInfo) ([]*types.Event, error) { - systemContractState, err := bs.StateDB.GetSystemAccountState() - - ci, err := ValidateNameTx(txBody, sender, scs, systemContractState) + ci, err := ValidateNameTx(txBody, sender, scs) if err != nil { return nil, err } - var events []*types.Event - var nameState *state.V owner := getOwner(scs, []byte(types.AergoName), false) if owner != nil { if bytes.Equal(sender.ID(), owner) { nameState = sender } else { - nameState, err = bs.GetAccountStateV(owner) - if err != nil { + if nameState, err = bs.GetAccountStateV(owner); err != nil { return nil, err } } @@ -38,17 +33,18 @@ func ExecuteNameTx(bs *state.BlockState, scs *state.ContractState, txBody *types nameState = receiver } + var events []*types.Event switch ci.Name { case types.NameCreate: - if err = CreateName(scs, txBody, sender, nameState, - ci.Args[0].(string)); err != nil { + nameArg := ci.Args[0].(string) + if err = CreateName(scs, txBody, sender, nameState, nameArg); err != nil { return nil, err } jsonArgs := "" if blockInfo.ForkVersion < 2 { - jsonArgs = `{"name":"` + ci.Args[0].(string) + `"}` + jsonArgs = `{"name":"` + nameArg + `"}` } else { - jsonArgs = `["` + ci.Args[0].(string) + `"]` + jsonArgs = `["` + nameArg + `"]` } events = append(events, &types.Event{ ContractAddress: receiver.ID(), @@ -57,16 +53,16 @@ func ExecuteNameTx(bs *state.BlockState, scs *state.ContractState, txBody *types JsonArgs: jsonArgs, }) case types.NameUpdate: - if err = UpdateName(bs, scs, txBody, sender, nameState, - ci.Args[0].(string), ci.Args[1].(string)); err != nil { + nameArg := ci.Args[0].(string) + toArg := ci.Args[1].(string) + if err = UpdateName(bs, scs, txBody, sender, nameState, nameArg, toArg); err != nil { return nil, err } jsonArgs := "" if blockInfo.ForkVersion < 2 { - jsonArgs = `{"name":"` + ci.Args[0].(string) + - `","to":"` + ci.Args[1].(string) + `"}` + jsonArgs = `{"name":"` + nameArg + `","to":"` + toArg + `"}` } else { - jsonArgs = `["` + ci.Args[0].(string) + `","` + ci.Args[1].(string) + `"]` + jsonArgs = `["` + nameArg + `","` + toArg + `"]` } events = append(events, &types.Event{ ContractAddress: receiver.ID(), @@ -75,7 +71,8 @@ func ExecuteNameTx(bs *state.BlockState, scs *state.ContractState, txBody *types JsonArgs: jsonArgs, }) case types.SetContractOwner: - ownerState, err := SetContractOwner(bs, scs, ci.Args[0].(string), nameState) + ownerArg := ci.Args[0].(string) + ownerState, err := SetContractOwner(bs, scs, ownerArg, nameState) if err != nil { return nil, err } @@ -87,9 +84,7 @@ func ExecuteNameTx(bs *state.BlockState, scs *state.ContractState, txBody *types return events, nil } -func ValidateNameTx(tx *types.TxBody, sender *state.V, - scs, systemcs *state.ContractState) (*types.CallInfo, error) { - +func ValidateNameTx(tx *types.TxBody, sender *state.V, scs *state.ContractState) (*types.CallInfo, error) { if sender != nil && sender.Balance().Cmp(tx.GetAmountBigInt()) < 0 { return nil, types.ErrInsufficientBalance } @@ -99,30 +94,25 @@ func ValidateNameTx(tx *types.TxBody, sender *state.V, return nil, err } - name := ci.Args[0].(string) - + nameArg := ci.Args[0].(string) switch ci.Name { case types.NameCreate: - namePrice := system.GetNamePriceFromState(systemcs) - if namePrice.Cmp(tx.GetAmountBigInt()) > 0 { + if system.GetNamePrice().Cmp(tx.GetAmountBigInt()) > 0 { return nil, types.ErrTooSmallAmount } - owner := getOwner(scs, []byte(name), false) - if owner != nil { - return nil, fmt.Errorf("aleady occupied %s", string(name)) + if owner := getOwner(scs, []byte(nameArg), false); owner != nil { + return nil, fmt.Errorf("aleady occupied %s", string(nameArg)) } case types.NameUpdate: - namePrice := system.GetNamePriceFromState(systemcs) - if namePrice.Cmp(tx.GetAmountBigInt()) > 0 { + if system.GetNamePrice().Cmp(tx.GetAmountBigInt()) > 0 { return nil, types.ErrTooSmallAmount } - if (!bytes.Equal(tx.Account, []byte(name))) && - (!bytes.Equal(tx.Account, getOwner(scs, []byte(name), false))) { - return nil, fmt.Errorf("owner not matched : %s", name) + if (!bytes.Equal(tx.Account, []byte(nameArg))) && + (!bytes.Equal(tx.Account, getOwner(scs, []byte(nameArg), false))) { + return nil, fmt.Errorf("owner not matched : %s", nameArg) } case types.SetContractOwner: - owner := getOwner(scs, []byte(types.AergoName), false) - if owner != nil { + if owner := getOwner(scs, []byte(types.AergoName), false); owner != nil { return nil, fmt.Errorf("owner aleady set to %s", types.EncodeAddress(owner)) } default: @@ -135,8 +125,6 @@ func ValidateNameTx(tx *types.TxBody, sender *state.V, func SetContractOwner(bs *state.BlockState, scs *state.ContractState, address string, nameState *state.V) (*state.V, error) { - name := []byte(types.AergoName) - rawaddr, err := types.DecodeAddress(address) if err != nil { return nil, err @@ -150,6 +138,7 @@ func SetContractOwner(bs *state.BlockState, scs *state.ContractState, ownerState.AddBalance(nameState.Balance()) nameState.SubBalance(nameState.Balance()) + name := []byte(types.AergoName) if err = registerOwner(scs, name, rawaddr, name); err != nil { return nil, err } diff --git a/contract/name/name.go b/contract/name/name.go index 39e7efebb..9a6373a04 100644 --- a/contract/name/name.go +++ b/contract/name/name.go @@ -7,10 +7,9 @@ import ( "github.com/aergoio/aergo/v2/state" "github.com/aergoio/aergo/v2/types" + "github.com/aergoio/aergo/v2/types/dbkey" ) -var prefix = []byte("name") - type NameMap struct { Version byte Owner []byte @@ -37,19 +36,20 @@ func createName(scs *state.ContractState, name []byte, owner []byte) error { // UpdateName is avaliable after bid implement func UpdateName(bs *state.BlockState, scs *state.ContractState, tx *types.TxBody, sender, receiver *state.V, name, to string) error { - amount := tx.GetAmountBigInt() if len(getAddress(scs, []byte(name))) <= types.NameLength { return fmt.Errorf("%s is not created yet", string(name)) } destination, _ := types.DecodeAddress(to) destination = GetAddress(scs, destination) + + amount := tx.GetAmountBigInt() sender.SubBalance(amount) receiver.AddBalance(amount) contract, err := bs.StateDB.OpenContractStateAccount(types.ToAccountID(destination)) if err != nil { return types.ErrTxInvalidRecipient } - creator, err := contract.GetData([]byte("Creator")) + creator, err := contract.GetData(dbkey.CreatorMeta()) if err != nil { return err } @@ -88,7 +88,7 @@ func Resolve(bs *state.BlockState, name []byte, legacy bool) ([]byte, error) { } func openContract(bs *state.BlockState) (*state.ContractState, error) { - v, err := bs.GetAccountStateV([]byte("aergo.name")) + v, err := bs.GetAccountStateV([]byte(types.AergoName)) if err != nil { return nil, err } @@ -101,8 +101,7 @@ func openContract(bs *state.BlockState) (*state.ContractState, error) { // GetAddress is resolve name for mempool func GetAddress(scs *state.ContractState, name []byte) []byte { - if len(name) == types.AddressLength || - types.IsSpecialAccount(name) { + if len(name) == types.AddressLength || types.IsSpecialAccount(name) { return name } return getAddress(scs, name) @@ -110,8 +109,7 @@ func GetAddress(scs *state.ContractState, name []byte) []byte { // GetAddressLegacy is resolve name for mempool by buggy logic, leaved for backward compatibility func GetAddressLegacy(scs *state.ContractState, name []byte) []byte { - if len(name) == types.AddressLength || - strings.Contains(string(name), ".") { + if len(name) == types.AddressLength || strings.Contains(string(name), ".") { return name } return getAddress(scs, name) @@ -138,14 +136,12 @@ func getOwner(scs *state.ContractState, name []byte, useInitial bool) []byte { } func getNameMap(scs *state.ContractState, name []byte, useInitial bool) *NameMap { - lowerCaseName := strings.ToLower(string(name)) - key := append(prefix, lowerCaseName...) var err error var ownerdata []byte if useInitial { - ownerdata, err = scs.GetInitialData(key) + ownerdata, err = scs.GetInitialData(dbkey.Name(name)) } else { - ownerdata, err = scs.GetData(key) + ownerdata, err = scs.GetData(dbkey.Name(name)) } if err != nil { return nil @@ -168,9 +164,7 @@ func registerOwner(scs *state.ContractState, name, owner, destination []byte) er } func setNameMap(scs *state.ContractState, name []byte, n *NameMap) error { - lowerCaseName := strings.ToLower(string(name)) - key := append(prefix, lowerCaseName...) - return scs.SetData(key, serializeNameMap(n)) + return scs.SetData(dbkey.Name(name), serializeNameMap(n)) } func serializeNameMap(n *NameMap) []byte { diff --git a/contract/name/name_test.go b/contract/name/name_test.go index 2748dcdeb..4c6a5d274 100644 --- a/contract/name/name_test.go +++ b/contract/name/name_test.go @@ -45,13 +45,12 @@ func TestName(t *testing.T) { receiver, _ := sdb.GetStateDB().GetAccountStateV(tx.Recipient) bs := sdb.NewBlockState(sdb.GetRoot()) scs := openContractState(t, bs) - systemcs := openSystemContractState(t, bs) err := CreateName(scs, tx, sender, receiver, name) assert.NoError(t, err, "create name") scs = nextBlockContractState(t, bs, scs) - _, err = ValidateNameTx(tx, sender, scs, systemcs) + _, err = ValidateNameTx(tx, sender, scs) assert.Error(t, err, "same name") ret := getAddress(scs, []byte(name)) diff --git a/contract/state_module.c b/contract/state_module.c index 48e0b1ef8..4a0c6507a 100644 --- a/contract/state_module.c +++ b/contract/state_module.c @@ -23,6 +23,22 @@ static int state_map_delete(lua_State *L); static int state_array_append(lua_State *L); static int state_array_pairs(lua_State *L); +/* +** If this is a sub-element, update the index at position 2 with +** the parent's element key. +*/ +static void update_key_with_parent(lua_State *L, char *parent_key) { + if (parent_key != NULL) { + // concatenate the key at this level with the given index + lua_pushstring(L, parent_key); + lua_pushstring(L, "-"); + lua_pushvalue(L, 2); + lua_concat(L, 3); + // update the index at position 2 + lua_replace(L, 2); + } +} + /* map */ typedef struct { @@ -33,7 +49,7 @@ typedef struct { } state_map_t; static int state_map(lua_State *L) { - int argn = lua_gettop(L); + int nargs = lua_gettop(L); state_map_t *m = lua_newuserdata(L, sizeof(state_map_t)); /* m */ m->id = NULL; @@ -42,7 +58,7 @@ static int state_map(lua_State *L) { if (luaL_isinteger(L, 1)) m->dimension = luaL_checkint(L, 1); - else if (argn == 0) + else if (nargs == 0) m->dimension = 1; else luaL_typerror(L, 1, "integer"); @@ -57,32 +73,46 @@ static int state_map(lua_State *L) { return 1; } -static void state_map_check_index(lua_State *L, state_map_t *m) { - /* m key */ - int key_type = lua_type(L, 2); +/* +** Once a state map is accessed with one type, it can only +** be used with that type (string or number). +** Probably to make it more compatible with Lua tables, +** where m[1] ~= m['1'] +*/ +static void state_map_check_index_type(lua_State *L, state_map_t *m) { + // get the type used for the key on the current access + int key_type = lua_type(L, 2); /* m key */ + // get the type used on the given map int stored_type = m->key_type; - + // maps can be accessed with only string and number if (key_type != LUA_TNUMBER && key_type != LUA_TSTRING) { luaL_error(L, "invalid key type: " LUA_QS ", state.map: " LUA_QS, lua_typename(L, key_type), m->id); } + // if the key type for this map is not loaded yet... if (stored_type == LUA_TNONE) { + // load it from state lua_pushcfunction(L, getItemWithPrefix); /* m key f */ - lua_pushstring(L, m->id); /* m key f id */ - lua_pushstring(L, STATE_VAR_META_TYPE); /* m key f id prefix */ - lua_call(L, 2, 1); /* m key t */ + lua_pushstring(L, m->id); /* m key f id */ + lua_pushstring(L, STATE_VAR_META_TYPE); /* m key f id prefix */ + lua_call(L, 2, 1); /* m key t */ + // is any type stored for this map? if (!lua_isnil(L, -1)) { + // if yes, check the type stored_type = luaL_checkint(L, -1); if (stored_type != LUA_TNUMBER && stored_type != LUA_TSTRING) { luaL_error(L, "invalid stored key type: " LUA_QS ", state.map:", lua_typename(L, stored_type), m->id); } } + // store the type on the map if (vm_is_hardfork(L, 2)) { m->key_type = stored_type; } + // remove it from stack lua_pop(L, 1); } + // make sure the map is accessed with the same type if (stored_type != LUA_TNONE && key_type != stored_type) { luaL_typerror(L, 2, lua_typename(L, stored_type)); } @@ -90,15 +120,15 @@ static void state_map_check_index(lua_State *L, state_map_t *m) { static void state_map_push_key(lua_State *L, state_map_t *m) { lua_pushstring(L, m->id); /* m key value f id */ - lua_pushstring(L, "-"); + lua_pushstring(L, "-"); /* m key value f id '-' */ lua_pushvalue(L, 2); /* m key value f id '-' key */ lua_concat(L, 3); /* m key value f id-key */ } static int state_map_get(lua_State *L) { int key_type = LUA_TNONE; - int arg = lua_gettop(L); - state_map_t *m = luaL_checkudata(L, 1, STATE_MAP_ID); /* m key */ + int nargs = lua_gettop(L); /* map key [blockheight] */ + state_map_t *m = luaL_checkudata(L, 1, STATE_MAP_ID); key_type = lua_type(L, 2); if (key_type == LUA_TSTRING) { @@ -109,7 +139,7 @@ static int state_map_get(lua_State *L) { } } - state_map_check_index(L, m); + state_map_check_index_type(L, m); if (m->dimension > 1) { state_map_t *subm = lua_newuserdata(L, sizeof(state_map_t)); /* m */ @@ -117,37 +147,32 @@ static int state_map_get(lua_State *L) { subm->key_type = m->key_type; subm->dimension = m->dimension - 1; - luaL_getmetatable(L, STATE_MAP_ID); /* m mt */ - lua_setmetatable(L, -2); /* m */ - if (m->key == NULL) { + luaL_getmetatable(L, STATE_MAP_ID); /* m mt */ + lua_setmetatable(L, -2); /* m */ + + if (m->key == NULL) { /* m key */ subm->key = strdup(lua_tostring(L, 2)); } else { - lua_pushstring(L, m->key); /* a key value f id '-' */ - lua_pushstring(L, "-"); /* a key value f id '-' */ - lua_pushvalue(L, 2); /* m key f id-key prefix */ - lua_concat(L, 3); /* m key value f id-key */ + lua_pushstring(L, m->key); /* m key id */ + lua_pushstring(L, "-"); /* m key id '-' */ + lua_pushvalue(L, 2); /* m key id '-' key */ + lua_concat(L, 3); /* m key id-key */ subm->key = strdup(lua_tostring(L, -1)); - lua_pop(L, 1); + lua_pop(L, 1); /* m key */ } return 1; } + // read the value associated with the given key lua_pushcfunction(L, getItemWithPrefix); /* m key f */ - if (m->key != NULL) { - lua_pushstring(L, m->key); - lua_pushstring(L, "-"); - lua_pushvalue(L, 2); - lua_concat(L, 3); - lua_replace(L, 2); - } - + // if this is a sub-map, update the index with the parent's map key + update_key_with_parent(L, m->key); state_map_push_key(L, m); /* m key f id-key */ - if (arg == 3) { - lua_pushvalue(L, 3); + if (nargs == 3) { /* m key h f id-key */ + lua_pushvalue(L, 3); /* m key h f id-key h */ } - - lua_pushstring(L, STATE_VAR_KEY_PREFIX); /* m key value f id-key value prefix */ - lua_call(L, arg, 1); /* m key rv */ + lua_pushstring(L, STATE_VAR_KEY_PREFIX); /* m key f id-key prefix */ + lua_call(L, nargs, 1); /* m key value */ return 1; } @@ -168,28 +193,24 @@ static int state_map_set(lua_State *L) { } } - state_map_check_index(L, m); + state_map_check_index_type(L, m); + // store the data type used for keys on this map if (m->key_type == LUA_TNONE) { - lua_pushcfunction(L, setItemWithPrefix); /* m key f */ - lua_pushstring(L, m->id); /* m key f id */ - lua_pushinteger(L, key_type); /* m key f id type */ - lua_pushstring(L, STATE_VAR_META_TYPE); /* m key f id type prefix */ - lua_call(L, 3, 0); /* m key */ + lua_pushcfunction(L, setItemWithPrefix); /* m key value f */ + lua_pushstring(L, m->id); /* m key value f id */ + lua_pushinteger(L, key_type); /* m key value f id type */ + lua_pushstring(L, STATE_VAR_META_TYPE); /* m key value f id type prefix */ + lua_call(L, 3, 0); /* m key value */ m->key_type = key_type; } luaL_checkany(L, 3); - lua_pushcfunction(L, setItemWithPrefix); /* m key value f */ - - if (m->key != NULL) { - lua_pushstring(L, m->key); - lua_pushstring(L, "-"); - lua_pushvalue(L, 2); - lua_concat(L, 3); - lua_replace(L, 2); - } + // save the value with the given key + lua_pushcfunction(L, setItemWithPrefix); /* m key value f */ + // if this is a sub-map, update the index with the parent's map key + update_key_with_parent(L, m->key); state_map_push_key(L, m); /* m key value f id-key */ lua_pushvalue(L, 3); /* m key value f id-key value */ lua_pushstring(L, STATE_VAR_KEY_PREFIX); /* m key value f id-key value prefix */ @@ -205,16 +226,12 @@ static int state_map_delete(lua_State *L) { luaL_error(L, "not permitted to set intermediate dimension of map"); } - state_map_check_index(L, m); - lua_pushcfunction(L, delItemWithPrefix); /* m key f */ + state_map_check_index_type(L, m); - if (m->key != NULL) { - lua_pushstring(L, m->key); - lua_pushstring(L, "-"); - lua_pushvalue(L, 2); - lua_concat(L, 3); - lua_replace(L, 2); - } + // delete the item with the given key + lua_pushcfunction(L, delItemWithPrefix); /* m key f */ + // if this is a sub-map, update the index with the parent's map key + update_key_with_parent(L, m->key); state_map_push_key(L, m); /* m key f id-key */ lua_pushstring(L, STATE_VAR_KEY_PREFIX); /* m key f id-key prefix */ lua_call(L, 2, 1); /* m key rv */ @@ -292,9 +309,9 @@ static int state_array_len(lua_State *L) { static void state_array_load_len(lua_State *L, state_array_t *arr) { if (!arr->is_fixed && arr->lens == NULL) { lua_pushcfunction(L, getItemWithPrefix); /* a i f */ - lua_pushstring(L, arr->id); /* a i f id */ - lua_pushstring(L, STATE_VAR_META_LEN); /* a i f id prefix */ - lua_call(L, 2, 1); /* a i n */ + lua_pushstring(L, arr->id); /* a i f id */ + lua_pushstring(L, STATE_VAR_META_LEN); /* a i f id prefix */ + lua_call(L, 2, 1); /* a i n */ arr->lens = malloc(sizeof(int32_t)); arr->lens[0] = luaL_optinteger(L, -1, 0); lua_pop(L, 1); @@ -311,15 +328,15 @@ static void state_array_checkarg(lua_State *L, state_array_t *arr) { } static void state_array_push_key(lua_State *L, const char *id) { - lua_pushstring(L, id); /* a key value f id */ - lua_pushstring(L, "-"); /* a key value f id '-' */ - lua_pushvalue(L, 2); /* m key value f id '-' key */ - lua_concat(L, 3); /* m key value f id-key */ + lua_pushstring(L, id); /* a i value f id */ + lua_pushstring(L, "-"); /* a i value f id '-' */ + lua_pushvalue(L, 2); /* a i value f id '-' key */ + lua_concat(L, 3); /* a i value f id-key */ } static int state_array_get(lua_State *L) { state_array_t *arr; - int arg = lua_gettop(L); + int nargs = lua_gettop(L); /* arr index [blockheight] */ int key_type = LUA_TNONE; arr = luaL_checkudata(L, 1, STATE_ARRAY_ID); @@ -339,6 +356,7 @@ static int state_array_get(lua_State *L) { } luaL_typerror(L, 2, "integer"); } + if (arr->dimension > 1) { state_array_t *suba = lua_newuserdata(L, sizeof(state_array_t)); /* m */ suba->id = strdup(arr->id); @@ -348,38 +366,36 @@ static int state_array_get(lua_State *L) { memcpy(suba->lens, arr->lens + 1, sizeof(int32_t) * suba->dimension); luaL_getmetatable(L, STATE_ARRAY_ID); /* m mt */ - lua_setmetatable(L, -2); /* m */ - if (arr->key == NULL) { + lua_setmetatable(L, -2); /* m */ + + if (arr->key == NULL) { /* a i */ suba->key = strdup(lua_tostring(L, 2)); } else { - lua_pushstring(L, arr->key); /* a key value f id '-' */ - lua_pushstring(L, "-"); /* a key value f id '-' */ - lua_pushvalue(L, 2); /* m key f id-key prefix */ - lua_concat(L, 3); /* m key value f id-key */ + lua_pushstring(L, arr->key); /* a i key */ + lua_pushstring(L, "-"); /* a i key '-' */ + lua_pushvalue(L, 2); /* a i key '-' i */ + lua_concat(L, 3); /* a i key-i */ suba->key = strdup(lua_tostring(L, -1)); - lua_pop(L, 1); + lua_pop(L, 1); /* a i */ } return 1; } - if (arg == 3) { - lua_pushvalue(L, 2); + + if (nargs == 3) { + lua_pushvalue(L, 2); //? why? } state_array_checkarg(L, arr); /* a i */ - lua_pushcfunction(L, getItemWithPrefix); /* a i f */ - if (arr->key != NULL) { - lua_pushstring(L, arr->key); - lua_pushstring(L, "-"); - lua_pushvalue(L, 2); - lua_concat(L, 3); - lua_replace(L, 2); - } - state_array_push_key(L, arr->id); /* a i f id-i */ - if (arg == 3) { - lua_pushvalue(L, 3); /* a i s i f id-i s */ - } - lua_pushstring(L, STATE_VAR_KEY_PREFIX); /* a i f id-i prefix */ - lua_call(L, arg, 1); /* a i rv */ + // read the value at the given position + lua_pushcfunction(L, getItemWithPrefix); /* a i f */ + // if this is a sub-array, update the index with the parent's array key + update_key_with_parent(L, arr->key); + state_array_push_key(L, arr->id); /* a i [h] f id-i */ + if (nargs == 3) { /* a i h f id-i */ + lua_pushvalue(L, 3); /* a i h f id-i h */ + } + lua_pushstring(L, STATE_VAR_KEY_PREFIX); /* a i [h] f id-i [h] prefix */ + lua_call(L, nargs, 1); /* a i value */ return 1; } @@ -394,41 +410,48 @@ static int state_array_set(lua_State *L) { state_array_load_len(L, arr); state_array_checkarg(L, arr); /* a i v */ - if (arr->key != NULL) { - lua_pushstring(L, arr->key); - lua_pushstring(L, "-"); - lua_pushvalue(L, 2); - lua_concat(L, 3); - lua_replace(L, 2); - } + + // if this is a sub-array, update the index with the parent's array key + update_key_with_parent(L, arr->key); + + // save the value at the given position lua_pushcfunction(L, setItemWithPrefix); /* a i v f */ state_array_push_key(L, arr->id); /* a i v f id-i */ lua_pushvalue(L, 3); /* a i v f id-i v */ lua_pushstring(L, STATE_VAR_KEY_PREFIX); /* a i v f id-i v prefix */ lua_call(L, 3, 0); /* a i v */ + return 0; } static int state_array_append(lua_State *L) { + // get reference to the array state_array_t *arr = luaL_checkudata(L, 1, STATE_ARRAY_ID); - luaL_checkany(L, 2); + // ensure there is a value of any type + luaL_checkany(L, 2); /* a v */ + // append() function only allowed on variable size arrays if (arr->is_fixed) { luaL_error(L, "the fixed array cannot use " LUA_QL("append") " method"); } + // check for overflow in size if (arr->lens[0] + 1 <= 0) { luaL_error(L, "state.array " LUA_QS " overflow", arr->id); } + // increment the size of the array arr->lens[0]++; + // save the value at the given position lua_pushcfunction(L, state_array_set); /* a v f */ lua_pushvalue(L, 1); /* a v f a */ - lua_pushinteger(L, arr->lens[0]); /* a v f a i */ + lua_pushinteger(L, arr->lens[0]); /* a v f a i */ lua_pushvalue(L, 2); /* a v f a i v */ lua_call(L, 3, 0); - lua_pushcfunction(L, setItemWithPrefix); - lua_pushstring(L, arr->id); - lua_pushinteger(L, arr->lens[0]); - lua_pushstring(L, STATE_VAR_META_LEN); + // save the new array size on the state + lua_pushcfunction(L, setItemWithPrefix); /* a v f */ + lua_pushstring(L, arr->id); /* a v f id */ + lua_pushinteger(L, arr->lens[0]); /* a v f id size */ + lua_pushstring(L, STATE_VAR_META_LEN); /* a v f id size prefix */ lua_call(L, 3, 0); + // nothing to return return 0; } @@ -496,29 +519,29 @@ static int state_value_get(lua_State *L) { } static int state_value_snapget(lua_State *L) { - int arg = lua_gettop(L); + int nargs = lua_gettop(L); state_value_t *v = luaL_checkudata(L, 1, STATE_VALUE_ID); /* v */ lua_pushcfunction(L, getItemWithPrefix); /* v f */ lua_pushstring(L, v->id); /* v f id */ - if (arg == 2) { + if (nargs == 2) { lua_pushvalue(L, 2); } lua_pushstring(L, STATE_VAR_KEY_PREFIX); /* v f id prefix */ - lua_call(L, arg + 1, 1); /* v rv */ + lua_call(L, nargs + 1, 1); /* v rv */ return 1; } static int state_value_set(lua_State *L) { - state_value_t *v = luaL_checkudata(L, 1, STATE_VALUE_ID); /* v */ - luaL_checkany(L, 2); - lua_pushcfunction(L, setItemWithPrefix); /* t f */ + state_value_t *v = luaL_checkudata(L, 1, STATE_VALUE_ID); + luaL_checkany(L, 2); /* s v */ + lua_pushcfunction(L, setItemWithPrefix); /* s v f */ if (v->id == NULL) { luaL_error(L, "invalid state.value: (nil)"); } - lua_pushstring(L, v->id); /* v f id */ - lua_pushvalue(L, 2); /* t f id value */ - lua_pushstring(L, STATE_VAR_KEY_PREFIX); /* v f id value prefix */ - lua_call(L, 3, 0); /* v */ + lua_pushstring(L, v->id); /* s v f id */ + lua_pushvalue(L, 2); /* s v f id value */ + lua_pushstring(L, STATE_VAR_KEY_PREFIX); /* s v f id value prefix */ + lua_call(L, 3, 0); /* s v */ return 0; } diff --git a/contract/statesql.go b/contract/statesql.go index d5fd02547..06c0ff14a 100644 --- a/contract/statesql.go +++ b/contract/statesql.go @@ -15,7 +15,7 @@ import ( "sync" "github.com/aergoio/aergo-lib/log" - "github.com/aergoio/aergo/v2/internal/enc" + "github.com/aergoio/aergo/v2/internal/enc/base58" "github.com/aergoio/aergo/v2/state" "github.com/aergoio/aergo/v2/types" ) @@ -49,7 +49,7 @@ func init() { sql.Register(statesqlDriver, &SQLiteDriver{ ConnectHook: func(conn *SQLiteConn) error { if _, ok := database.DBs[database.OpenDbName]; !ok { - b, err := enc.ToBytes(database.OpenDbName) + b, err := base58.Decode(database.OpenDbName) if err != nil { sqlLgr.Error().Err(err).Msg("Open SQL Connection") return nil diff --git a/contract/system/execute.go b/contract/system/execute.go index b971c414a..a785ac674 100644 --- a/contract/system/execute.go +++ b/contract/system/execute.go @@ -10,9 +10,9 @@ import ( "fmt" "math/big" + "github.com/aergoio/aergo/v2/internal/enc/base58" "github.com/aergoio/aergo/v2/state" "github.com/aergoio/aergo/v2/types" - "github.com/mr-tron/base58" ) // SystemContext is context of executing aergo.system transaction and filled after validation. diff --git a/contract/system/execute_test.go b/contract/system/execute_test.go index 4d3fe2907..479c75951 100644 --- a/contract/system/execute_test.go +++ b/contract/system/execute_test.go @@ -9,8 +9,8 @@ import ( "testing" "github.com/aergoio/aergo/v2/config" + "github.com/aergoio/aergo/v2/internal/enc/base58" "github.com/aergoio/aergo/v2/types" - "github.com/mr-tron/base58/base58" "github.com/stretchr/testify/assert" ) @@ -720,6 +720,8 @@ func TestProposalExecute2(t *testing.T) { blockInfo.No++ blockInfo.ForkVersion = config.AllEnabledHardforkConfig.Version(blockInfo.No) + // BP Count + votingTx := &types.Tx{ Body: &types.TxBody{ Account: sender.ID(), @@ -747,6 +749,8 @@ func TestProposalExecute2(t *testing.T) { internalVoteResult, err := loadVoteResult(scs, GenProposalKey(bpCount.ID())) assert.Equal(t, new(big.Int).Mul(balance2, big.NewInt(3)), internalVoteResult.GetTotal(), "check result total") + // Staking Min + votingTx = &types.Tx{ Body: &types.TxBody{ Account: sender.ID(), @@ -765,6 +769,10 @@ func TestProposalExecute2(t *testing.T) { _, err = ExecuteSystemTx(scs, votingTx.GetBody(), sender3, receiver, blockInfo) assert.NoError(t, err, "could not execute system tx") + // Gas Price + + origGasPrice := GetGasPrice() + votingTx = &types.Tx{ Body: &types.TxBody{ Account: sender.ID(), @@ -782,8 +790,15 @@ func TestProposalExecute2(t *testing.T) { votingTx.Body.Payload = []byte(`{"Name":"v1voteDAO", "Args":["GASPRICE", "1004"]}`) _, err = ExecuteSystemTx(scs, votingTx.GetBody(), sender3, receiver, blockInfo) assert.NoError(t, err, "could not execute system tx") - gasPrice := GetGasPrice() - assert.Equal(t, balance0_5, gasPrice, "result of gas price voting") + + // check the value for the current block + assert.Equal(t, origGasPrice, GetGasPrice(), "result of gas price voting") + // check the value for the next block + assert.Equal(t, balance0_5, GetNextBlockParam("GASPRICE"), "result of gas price voting") + // commit the new value + CommitParams(true) + // check the value for the current block + assert.Equal(t, balance0_5, GetGasPrice(), "result of gas price voting") blockInfo.No += StakingDelay unstakingTx := &types.Tx{ @@ -815,6 +830,8 @@ func TestProposalExecute2(t *testing.T) { _, err = ExecuteSystemTx(scs, unstakingTx.GetBody(), sender, receiver, blockInfo) assert.NoError(t, err, "could not execute system tx") + oldNamePrice := GetNamePrice() + votingTx.Body.Account = sender2.ID() votingTx.Body.Payload = []byte(`{"Name":"v1voteDAO", "Args":["NAMEPRICE", "1004"]}`) _, err = ExecuteSystemTx(scs, votingTx.GetBody(), sender2, receiver, blockInfo) @@ -830,8 +847,15 @@ func TestProposalExecute2(t *testing.T) { internalVoteResult, err = loadVoteResult(scs, GenProposalKey(namePrice.ID())) assert.Equal(t, new(big.Int).Mul(balance2, big.NewInt(2)), internalVoteResult.GetTotal(), "check result total") assert.Equal(t, "1004", string(voteResult.Votes[0].Candidate), "1st place") - currentNamePrice := GetNamePrice() - assert.Equal(t, "1004", currentNamePrice.String(), "current name price") + + // check the value for the current block + assert.Equal(t, oldNamePrice, GetNamePrice(), "check name price") + // check the value for the next block + assert.Equal(t, big.NewInt(1004), GetNextBlockParam("NAMEPRICE"), "check name price") + // commit the new value + CommitParams(true) + // check the value for the current block + assert.Equal(t, big.NewInt(1004), GetNamePrice(), "check name price") /* blockInfo += StakingDelay diff --git a/contract/system/param.go b/contract/system/param.go index a4fe2ba1a..cf0b0bd87 100644 --- a/contract/system/param.go +++ b/contract/system/param.go @@ -2,13 +2,57 @@ package system import ( "math/big" - "strings" + "sync" "github.com/aergoio/aergo/v2/state" "github.com/aergoio/aergo/v2/types" + "github.com/aergoio/aergo/v2/types/dbkey" ) -type parameters map[string]*big.Int +type parameters struct { + mutex sync.RWMutex + params map[string]*big.Int +} + +func (p *parameters) setParam(proposalID string, value *big.Int) { + p.mutex.Lock() + defer p.mutex.Unlock() + + p.params[proposalID] = value +} + +// save the new value for the param, to be active on the next block +func (p *parameters) setNextBlockParam(proposalID string, value *big.Int) { + p.mutex.Lock() + defer p.mutex.Unlock() + + p.params[nextBlockParamKey(proposalID)] = value +} + +func (p *parameters) delNextBlockParam(proposalID string) { + p.mutex.Lock() + defer p.mutex.Unlock() + + delete(p.params, nextBlockParamKey(proposalID)) +} + +func (p *parameters) getNextBlockParam(proposalID string) *big.Int { + p.mutex.Lock() + defer p.mutex.Unlock() + + return p.params[nextBlockParamKey(proposalID)] +} + +func (p *parameters) getParam(proposalID string) *big.Int { + p.mutex.Lock() + defer p.mutex.Unlock() + + return p.params[proposalID] +} + +func nextBlockParamKey(id string) string { + return id + "next" +} const ( RESET = -1 @@ -26,7 +70,10 @@ const ( ) var ( - systemParams parameters + systemParams *parameters = ¶meters{ + mutex: sync.RWMutex{}, + params: map[string]*big.Int{}, + } //DefaultParams is for aergo v1 compatibility DefaultParams = map[string]*big.Int{ @@ -36,52 +83,95 @@ var ( } ) +// This is also called on chain reorganization func InitSystemParams(g dataGetter, bpCount int) { + // discard any new params computed for the next block + CommitParams(false) + // (re)load param values from database initDefaultBpCount(bpCount) - systemParams = loadParam(g) + systemParams = loadParams(g) } -func genParamKey(id string) []byte { - return []byte("param\\" + strings.ToUpper(id)) +// This function must be called before all the aergosvr +// services start. +func initDefaultBpCount(count int) { + // Ensure that it is not modified after it is initialized. + if DefaultParams[bpCount.ID()] == nil { + DefaultParams[bpCount.ID()] = big.NewInt(int64(count)) + } } -func loadParam(g dataGetter) parameters { +// load the params from the database or use the default values +func loadParams(g dataGetter) *parameters { ret := map[string]*big.Int{} for i := sysParamIndex(0); i < sysParamMax; i++ { id := i.ID() - data, err := g.GetData(genParamKey(id)) + data, err := g.GetData(dbkey.SystemParam(id)) if err != nil { panic("could not load blockchain parameter") } - if data == nil { + if data != nil { + ret[id] = new(big.Int).SetBytes(data) + } else { ret[id] = DefaultParams[id] - continue } - ret[id] = new(big.Int).SetBytes(data) } - return ret + return ¶meters{ + mutex: sync.RWMutex{}, + params: ret, + } } -func (p parameters) getLastParam(proposalID string) *big.Int { - if val, ok := p[proposalID]; ok { - return val +func updateParam(s dataSetter, id string, value *big.Int) error { + // save the param to the database (in a db txn, commit when the block is connected) + if err := s.SetData(dbkey.SystemParam(id), value.Bytes()); err != nil { + return err + } + // save the new value for the param, only active on the next block + systemParams.setNextBlockParam(id, value) + return nil +} + +// if a system param was changed, apply or discard its new value +func CommitParams(apply bool) { + for i := sysParamIndex(0); i < sysParamMax; i++ { + id := i.ID() + // check if the param has a new value + if param := systemParams.getNextBlockParam(id); param != nil { + if apply { + // set the new value for the current block + systemParams.setParam(id, param) + } + // delete the new value + systemParams.delNextBlockParam(id) + } } - return DefaultParams[proposalID] } -func (p parameters) setLastParam(proposalID string, value *big.Int) *big.Int { - p[proposalID] = value - return value +// get the param value for the next block +func GetNextBlockParam(proposalID string) *big.Int { + // check the value for the next block + if val := systemParams.getNextBlockParam(proposalID); val != nil { + return val + } + // check the value for the current block + if val := systemParams.getParam(proposalID); val != nil { + return val + } + // default value + return DefaultParams[proposalID] } -func updateParam(s dataSetter, id string, value *big.Int) (*big.Int, error) { - if err := s.SetData(genParamKey(id), value.Bytes()); err != nil { - return nil, err +// get the param value for the current block +func GetParam(proposalID string) *big.Int { + if val := systemParams.getParam(proposalID); val != nil { + return val } - ret := systemParams.setLastParam(id, value) - return ret, nil + return DefaultParams[proposalID] } +// these 4 functions are reading the param value for the current block + func GetStakingMinimum() *big.Int { return GetParam(stakingMin.ID()) } @@ -94,6 +184,12 @@ func GetNamePrice() *big.Int { return GetParam(namePrice.ID()) } +func GetBpCount() int { + return int(GetParam(bpCount.ID()).Uint64()) +} + +// these functions are reading the param value directly from the state + func GetNamePriceFromState(scs *state.ContractState) *big.Int { return getParamFromState(scs, namePrice) } @@ -111,7 +207,7 @@ func GetGasPriceFromState(ar AccountStateReader) *big.Int { } func getParamFromState(scs *state.ContractState, id sysParamIndex) *big.Int { - data, err := scs.GetInitialData(genParamKey(id.ID())) + data, err := scs.GetInitialData(dbkey.SystemParam(id.ID())) if err != nil { panic("could not get blockchain parameter") } diff --git a/contract/system/param_test.go b/contract/system/param_test.go index e9812c92e..f23c601ab 100644 --- a/contract/system/param_test.go +++ b/contract/system/param_test.go @@ -8,17 +8,17 @@ import ( func TestValidateDefaultParams(t *testing.T) { // Staking minimum amount ( 10,000 aergo ) - stakingMin, ok := DefaultParams[stakingMin.ID()] - assert.Truef(t, ok, "stakingMin is not valid. check contract/system/param.go") + stakingMin := DefaultParams[stakingMin.ID()] + assert.NotNilf(t, stakingMin, "stakingMin is not valid. check contract/system/param.go") assert.Equalf(t, "10000000000000000000000", stakingMin.String(), "StakingMinimum is not valid. check contract/system/param.go") // gas price ( 50 gaer ) - gasPrice, ok := DefaultParams[gasPrice.ID()] - assert.Truef(t, ok, "gasPrice is not valid. check contract/system/param.go") + gasPrice := DefaultParams[gasPrice.ID()] + assert.NotNilf(t, gasPrice, "gasPrice is not valid. check contract/system/param.go") assert.Equalf(t, "50000000000", gasPrice.String(), "GasPrice is not valid. check contract/system/param.go") // Proposal price ( 1 aergo ) namePrice := DefaultParams[namePrice.ID()] - assert.Truef(t, ok, "namePrice is not valid. check contract/system/param.go") + assert.NotNilf(t, namePrice, "namePrice is not valid. check contract/system/param.go") assert.Equalf(t, "1000000000000000000", namePrice.String(), "ProposalPrice is not valid. check contract/system/param.go") } diff --git a/contract/system/proposal.go b/contract/system/proposal.go index d79d6df1e..ccb27f10f 100644 --- a/contract/system/proposal.go +++ b/contract/system/proposal.go @@ -9,8 +9,6 @@ import ( "github.com/aergoio/aergo/v2/types" ) -const proposalPrefixKey = "proposal" //aergo proposal format - func (i sysParamIndex) ID() string { return strings.ToUpper(i.String()) } @@ -82,12 +80,6 @@ func GenProposalKey(id string) []byte { return []byte(strings.ToUpper(id)) } -/* -func ProposalIDfromKey(key []byte) string { - return strings.Replace(string(key), proposalPrefixKey+"\\", "", 1) -} -*/ - // getProposal find proposal using id func getProposal(id string) (*Proposal, error) { if val, ok := SystemProposal[id]; ok { diff --git a/contract/system/proposal_test.go b/contract/system/proposal_test.go index e462508d9..77365d114 100644 --- a/contract/system/proposal_test.go +++ b/contract/system/proposal_test.go @@ -123,6 +123,14 @@ func TestProposalBPCount(t *testing.T) { _, err = ExecuteSystemTx(scs, validCandiTx.GetBody(), sender2, receiver, blockInfo) assert.NoError(t, err, "valid") + + // check the value for the current block + assert.Equal(t, 3, GetBpCount(), "check bp") + // check the value for the next block + assert.Equal(t, big.NewInt(13), GetNextBlockParam("BPCOUNT"), "check bp") + // commit the new value + CommitParams(true) + // check the value for the current block assert.Equal(t, 13, GetBpCount(), "check bp") } @@ -203,8 +211,20 @@ func TestFailProposals(t *testing.T) { _, err = ExecuteSystemTx(scs, validCandiTx.GetBody(), sender2, receiver, blockInfo) assert.NoError(t, err, "valid") + + // check the value for the current block + assert.Equal(t, 3, GetBpCount(), "check bp") + // check the value for the next block + assert.Equal(t, big.NewInt(13), GetNextBlockParam("BPCOUNT"), "check bp") + // commit the new value + CommitParams(true) + // check the value for the current block assert.Equal(t, 13, GetBpCount(), "check bp") + // gas price + + oldGasPrice := GetGasPrice() + invalidCandiTx.Body.Payload = []byte(`{"Name":"v1voteDAO", "Args":["gasprice", "500000000000000000000000001"]}`) _, err = ExecuteSystemTx(scs, invalidCandiTx.GetBody(), sender, receiver, blockInfo) assert.Error(t, err, "invalid range") @@ -221,5 +241,13 @@ func TestFailProposals(t *testing.T) { validCandiTx.Body.Payload = []byte(`{"Name":"v1voteDAO", "Args":["gasprice", "101"]}`) _, err = ExecuteSystemTx(scs, validCandiTx.GetBody(), sender2, receiver, blockInfo) assert.NoError(t, err, "valid") + + // check the value for the current block + assert.Equal(t, oldGasPrice, GetGasPrice(), "check gas price") + // check the value for the next block + assert.Equal(t, big.NewInt(101), GetNextBlockParam("GASPRICE"), "check gas price") + // commit the new value + CommitParams(true) + // check the value for the current block assert.Equal(t, big.NewInt(101), GetGasPrice(), "check gas price") } diff --git a/contract/system/staking.go b/contract/system/staking.go index fec058c84..50ea82098 100644 --- a/contract/system/staking.go +++ b/contract/system/staking.go @@ -11,24 +11,16 @@ import ( "github.com/aergoio/aergo/v2/state" "github.com/aergoio/aergo/v2/types" + "github.com/aergoio/aergo/v2/types/dbkey" ) -var consensusType string - var ( - stakingKey = []byte("staking") - stakingTotalKey = []byte("stakingtotal") - ErrInvalidCandidate = errors.New("invalid candidate") ) const StakingDelay = 60 * 60 * 24 //block interval //const StakingDelay = 5 -func InitGovernance(consensus string) { - consensusType = consensus -} - type stakeCmd struct { *SystemContext amount *big.Int @@ -61,23 +53,18 @@ func (c *stakeCmd) run() (*types.Event, error) { } sender.SubBalance(amount) receiver.AddBalance(amount) + + jsonArgs := "" if c.SystemContext.BlockInfo.ForkVersion < 2 { - return &types.Event{ - ContractAddress: receiver.ID(), - EventIdx: 0, - EventName: "stake", - JsonArgs: `{"who":"` + - types.EncodeAddress(sender.ID()) + - `", "amount":"` + amount.String() + `"}`, - }, nil + jsonArgs = `{"who":"` + types.EncodeAddress(sender.ID()) + `", "amount":"` + amount.String() + `"}` + } else { + jsonArgs = `["` + types.EncodeAddress(sender.ID()) + `", {"_bignum":"` + amount.String() + `"}]` } return &types.Event{ ContractAddress: receiver.ID(), EventIdx: 0, EventName: "stake", - JsonArgs: `["` + - types.EncodeAddress(sender.ID()) + - `", {"_bignum":"` + amount.String() + `"}]`, + JsonArgs: jsonArgs, }, nil } @@ -114,34 +101,27 @@ func (c *unstakeCmd) run() (*types.Event, error) { } sender.AddBalance(balanceAdjustment) receiver.SubBalance(balanceAdjustment) + + jsonArgs := "" if c.SystemContext.BlockInfo.ForkVersion < 2 { - return &types.Event{ - ContractAddress: receiver.ID(), - EventIdx: 0, - EventName: "unstake", - JsonArgs: `{"who":"` + - types.EncodeAddress(sender.ID()) + - `", "amount":"` + balanceAdjustment.String() + `"}`, - }, nil + jsonArgs = `{"who":"` + types.EncodeAddress(sender.ID()) + `", "amount":"` + balanceAdjustment.String() + `"}` + } else { + jsonArgs = `["` + types.EncodeAddress(sender.ID()) + `", {"_bignum":"` + balanceAdjustment.String() + `"}]` } return &types.Event{ ContractAddress: receiver.ID(), EventIdx: 0, EventName: "unstake", - JsonArgs: `["` + - types.EncodeAddress(sender.ID()) + - `", {"_bignum":"` + balanceAdjustment.String() + `"}]`, + JsonArgs: jsonArgs, }, nil } -func setStaking(scs *state.ContractState, who []byte, staking *types.Staking) error { - key := append(stakingKey, who...) - return scs.SetData(key, serializeStaking(staking)) +func setStaking(scs *state.ContractState, account []byte, staking *types.Staking) error { + return scs.SetData(dbkey.SystemStaking(account), serializeStaking(staking)) } -func getStaking(scs *state.ContractState, who []byte) (*types.Staking, error) { - key := append(stakingKey, who...) - data, err := scs.GetData(key) +func getStaking(scs *state.ContractState, account []byte) (*types.Staking, error) { + data, err := scs.GetData(dbkey.SystemStaking(account)) if err != nil { return nil, err } @@ -168,7 +148,7 @@ func GetStakingTotal(ar AccountStateReader) (*big.Int, error) { } func getStakingTotal(scs *state.ContractState) (*big.Int, error) { - data, err := scs.GetData(stakingTotalKey) + data, err := scs.GetData(dbkey.SystemStakingTotal()) if err != nil { return nil, err } @@ -176,21 +156,21 @@ func getStakingTotal(scs *state.ContractState) (*big.Int, error) { } func addTotal(scs *state.ContractState, amount *big.Int) error { - data, err := scs.GetData(stakingTotalKey) + data, err := scs.GetData(dbkey.SystemStakingTotal()) if err != nil { return err } total := new(big.Int).SetBytes(data) - return scs.SetData(stakingTotalKey, new(big.Int).Add(total, amount).Bytes()) + return scs.SetData(dbkey.SystemStakingTotal(), new(big.Int).Add(total, amount).Bytes()) } func subTotal(scs *state.ContractState, amount *big.Int) error { - data, err := scs.GetData(stakingTotalKey) + data, err := scs.GetData(dbkey.SystemStakingTotal()) if err != nil { return err } total := new(big.Int).SetBytes(data) - return scs.SetData(stakingTotalKey, new(big.Int).Sub(total, amount).Bytes()) + return scs.SetData(dbkey.SystemStakingTotal(), new(big.Int).Sub(total, amount).Bytes()) } func serializeStaking(v *types.Staking) []byte { diff --git a/contract/system/validation.go b/contract/system/validation.go index cf3fcd37c..33573835c 100644 --- a/contract/system/validation.go +++ b/contract/system/validation.go @@ -130,7 +130,7 @@ func validateForStaking(account []byte, txBody *types.TxBody, scs *state.Contrac return nil, types.ErrLessTimeHasPassed } toBe := new(big.Int).Add(staked.GetAmountBigInt(), txBody.GetAmountBigInt()) - stakingMin := GetStakingMinimumFromState(scs) + stakingMin := GetStakingMinimum() if stakingMin.Cmp(toBe) > 0 { return nil, types.ErrTooSmallAmount } @@ -164,7 +164,7 @@ func validateForUnstaking(account []byte, txBody *types.TxBody, scs *state.Contr return nil, types.ErrLessTimeHasPassed } toBe := new(big.Int).Sub(staked.GetAmountBigInt(), txBody.GetAmountBigInt()) - stakingMin := GetStakingMinimumFromState(scs) + stakingMin := GetStakingMinimum() if toBe.Cmp(big.NewInt(0)) != 0 && stakingMin.Cmp(toBe) > 0 { return nil, types.ErrTooSmallAmount } diff --git a/contract/system/vote.go b/contract/system/vote.go index 5d2ee9187..afee0a0ac 100644 --- a/contract/system/vote.go +++ b/contract/system/vote.go @@ -12,10 +12,10 @@ import ( "math/big" "strings" - "github.com/aergoio/aergo/v2/internal/enc" + "github.com/aergoio/aergo/v2/internal/enc/base58" "github.com/aergoio/aergo/v2/state" "github.com/aergoio/aergo/v2/types" - "github.com/mr-tron/base58" + "github.com/aergoio/aergo/v2/types/dbkey" ) const ( @@ -25,13 +25,8 @@ const ( ) var ( - votingCatalog []types.VotingIssue - - lastBpCount int - - voteKey = []byte("vote") - totalKey = []byte("total") - sortKey = []byte("sort") + votingCatalog []types.VotingIssue + lastBpCount int defaultVoteKey = []byte(types.OpvoteBP.ID()) ) @@ -94,7 +89,6 @@ func (c *vprCmd) subVote(v *types.Vote) error { votingPowerRank.sub(c.Sender.AccountID(), c.Sender.ID(), v.GetAmountBigInt()) // Hotfix - reproduce vpr calculation for block 138015125 // When block is reverted, votingPowerRank is not reverted and calculated three times. - // TODO : implement commit, revert, reorg for governance variables. if c.BlockInfo.No == 138015125 && c.Sender.AccountID().String() == "36t2u7Q31HmEbkkYZng7DHNm3xepxHKUfgGrAXNA8pMW" { for i := 0; i < 2; i++ { votingPowerRank.sub(c.Sender.AccountID(), c.Sender.ID(), v.GetAmountBigInt()) @@ -107,7 +101,6 @@ func (c *vprCmd) addVote(v *types.Vote) error { votingPowerRank.add(c.Sender.AccountID(), c.Sender.ID(), v.GetAmountBigInt()) // Hotfix - reproduce vpr calculation for block 138015125 // When block is reverted, votingPowerRank is not reverted and calculated three times. - // TODO : implement commit, revert, reorg for governance variables. if c.BlockInfo.No == 138015125 && c.Sender.AccountID().String() == "36t2u7Q31HmEbkkYZng7DHNm3xepxHKUfgGrAXNA8pMW" { for i := 0; i < 2; i++ { votingPowerRank.add(c.Sender.AccountID(), c.Sender.ID(), v.GetAmountBigInt()) @@ -198,23 +191,18 @@ func (c *voteCmd) run() (*types.Event, error) { if err := c.updateVoteResult(); err != nil { return nil, err } + + jsonArgs := "" if c.SystemContext.BlockInfo.ForkVersion < 2 { - return &types.Event{ - ContractAddress: c.Receiver.ID(), - EventIdx: 0, - EventName: c.op.ID(), - JsonArgs: `{"who":"` + - types.EncodeAddress(c.txBody.Account) + - `", "vote":` + string(c.args) + `}`, - }, nil + jsonArgs = `{"who":"` + types.EncodeAddress(c.txBody.Account) + `", "vote":` + string(c.args) + `}` + } else { + jsonArgs = `["` + types.EncodeAddress(c.txBody.Account) + `", ` + string(c.args) + `]` } return &types.Event{ ContractAddress: c.Receiver.ID(), EventIdx: 0, EventName: c.op.ID(), - JsonArgs: `["` + - types.EncodeAddress(c.txBody.Account) + - `", ` + string(c.args) + `]`, + JsonArgs: jsonArgs, }, nil } @@ -302,8 +290,7 @@ func GetVote(scs *state.ContractState, voter []byte, issue []byte) (*types.Vote, } func getVote(scs *state.ContractState, key, voter []byte) (*types.Vote, error) { - dataKey := append(append(voteKey, key...), voter...) - data, err := scs.GetData(dataKey) + data, err := scs.GetData(dbkey.SystemVote(key, voter)) if err != nil { return nil, err } @@ -320,11 +307,10 @@ func getVote(scs *state.ContractState, key, voter []byte) (*types.Vote, error) { } func setVote(scs *state.ContractState, key, voter []byte, vote *types.Vote) error { - dataKey := append(append(voteKey, key...), voter...) if bytes.Equal(key, defaultVoteKey) { - return scs.SetData(dataKey, serializeVote(vote)) + return scs.SetData(dbkey.SystemVote(key, voter), serializeVote(vote)) } else { - return scs.SetData(dataKey, serializeVoteEx(vote)) + return scs.SetData(dbkey.SystemVote(key, voter), serializeVoteEx(vote)) } } @@ -336,7 +322,7 @@ func BuildOrderedCandidates(vote map[string]*big.Int) []string { l := voteResult.buildVoteList() bps := make([]string, 0, len(l.Votes)) for _, v := range l.Votes { - bp := enc.ToString(v.Candidate) + bp := base58.Encode(v.Candidate) bps = append(bps, bp) } return bps @@ -359,21 +345,6 @@ func GetVoteResult(ar AccountStateReader, id []byte, n int) (*types.VoteList, er return getVoteResult(scs, id, n) } -// initDefaultBpCount sets lastBpCount to bpCount. -// -// Caution: This function must be called only once before all the aergosvr -// services start. -func initDefaultBpCount(count int) { - // Ensure that it is not modified after it is initialized. - if DefaultParams[bpCount.ID()] == nil { - DefaultParams[bpCount.ID()] = big.NewInt(int64(count)) - } -} - -func GetBpCount() int { - return int(GetParam(bpCount.ID()).Uint64()) -} - // GetRankers returns the IDs of the top n rankers. func GetRankers(ar AccountStateReader) ([]string, error) { n := GetBpCount() @@ -385,15 +356,11 @@ func GetRankers(ar AccountStateReader) ([]string, error) { bps := make([]string, 0, n) for _, v := range vl.Votes { - bps = append(bps, enc.ToString(v.Candidate)) + bps = append(bps, base58.Encode(v.Candidate)) } return bps, nil } -func GetParam(proposalID string) *big.Int { - return systemParams.getLastParam(proposalID) -} - func serializeVoteList(vl *types.VoteList, ex bool) []byte { var data []byte for _, v := range vl.GetVotes() { diff --git a/contract/system/vote_test.go b/contract/system/vote_test.go index 57b0562f4..0d8bb233b 100644 --- a/contract/system/vote_test.go +++ b/contract/system/vote_test.go @@ -14,10 +14,10 @@ import ( "testing" "github.com/aergoio/aergo-lib/db" + "github.com/aergoio/aergo/v2/internal/enc/base58" "github.com/aergoio/aergo/v2/state" "github.com/aergoio/aergo/v2/types" "github.com/libp2p/go-libp2p-core/crypto" - "github.com/mr-tron/base58" "github.com/stretchr/testify/assert" ) @@ -35,7 +35,6 @@ func initTest(t *testing.T) (*state.ContractState, *state.V, *state.V) { t.Fatalf("failed init : %s", err.Error()) } // Need to pass the - InitGovernance("dpos") const testSender = "AmPNYHyzyh9zweLwDyuoiUuTVCdrdksxkRWDjVJS76WQLExa2Jr4" scs, err := bs.GetSystemAccountState() diff --git a/contract/system/voteresult.go b/contract/system/voteresult.go index 33d9aded0..386726de9 100644 --- a/contract/system/voteresult.go +++ b/contract/system/voteresult.go @@ -8,10 +8,10 @@ import ( "math/big" "sort" - "github.com/aergoio/aergo/v2/internal/enc" + "github.com/aergoio/aergo/v2/internal/enc/base58" "github.com/aergoio/aergo/v2/state" "github.com/aergoio/aergo/v2/types" - "github.com/mr-tron/base58" + "github.com/aergoio/aergo/v2/types/dbkey" ) type VoteResult struct { @@ -98,7 +98,7 @@ func (vr *VoteResult) buildVoteList() *types.VoteList { if vr.ex { vote.Candidate = []byte(k) } else { - vote.Candidate, _ = enc.ToBytes(k) + vote.Candidate, _ = base58.Decode(k) } voteList.Votes = append(voteList.Votes, vote) } @@ -117,15 +117,15 @@ func (vr *VoteResult) Sync() error { if !ok { return fmt.Errorf("abnormal winner is in vote %s", string(vr.key)) } - if _, err := updateParam(vr.scs, string(vr.key), value); err != nil { + if err := updateParam(vr.scs, string(vr.key), value); err != nil { return err } } - if err := vr.scs.SetData(append(totalKey, vr.key...), vr.total.Bytes()); err != nil { + if err := vr.scs.SetData(dbkey.SystemVoteTotal(vr.key), vr.total.Bytes()); err != nil { return err } } - return vr.scs.SetData(append(sortKey, vr.key...), serializeVoteList(resultList, vr.ex)) + return vr.scs.SetData(dbkey.SystemVoteSort(vr.key), serializeVoteList(resultList, vr.ex)) } func (vr *VoteResult) threshold(power *big.Int) bool { @@ -143,11 +143,11 @@ func (vr *VoteResult) threshold(power *big.Int) bool { } func loadVoteResult(scs *state.ContractState, key []byte) (*VoteResult, error) { - data, err := scs.GetData(append(sortKey, key...)) + data, err := scs.GetData(dbkey.SystemVoteSort(key)) if err != nil { return nil, err } - total, err := scs.GetData(append(totalKey, key...)) + total, err := scs.GetData(dbkey.SystemVoteTotal(key)) if err != nil { return nil, err } @@ -181,7 +181,7 @@ func InitVoteResult(scs *state.ContractState, voteResult map[string]*big.Int) er } func getVoteResult(scs *state.ContractState, key []byte, n int) (*types.VoteList, error) { - data, err := scs.GetData(append(sortKey, key...)) + data, err := scs.GetData(dbkey.SystemVoteSort(key)) if err != nil { return nil, err } diff --git a/contract/system/vprt.go b/contract/system/vprt.go index 6d7ed9f63..0a4eadacb 100644 --- a/contract/system/vprt.go +++ b/contract/system/vprt.go @@ -12,9 +12,10 @@ import ( "reflect" "github.com/aergoio/aergo-lib/log" - "github.com/aergoio/aergo/v2/internal/enc" + "github.com/aergoio/aergo/v2/internal/enc/base58" "github.com/aergoio/aergo/v2/state" "github.com/aergoio/aergo/v2/types" + "github.com/aergoio/aergo/v2/types/dbkey" rb "github.com/emirpasic/gods/trees/redblacktree" jsoniter "github.com/json-iterator/go" "github.com/sanity-io/litter" @@ -37,7 +38,6 @@ var ( ErrNoVotingRewardRank = errors.New("voting reward rank: not initialized") zeroValue = types.NewZeroAmount() - vprKeyPrefix = []byte("VotingPowerBucket/") million = types.NewAmount(1e6, types.Aer) // 1,000,000 Aer annualRewardM = types.NewAmount(5045760000, types.Gaer) // 5,045,760,000 Gaer annualReward = new(big.Int).Mul(annualRewardM, million) // 5,045,760 AERGO @@ -281,11 +281,11 @@ func (b *vprStore) write(s dataSetter, i uint8) error { buf.Write(toVotingPower(e).marshal()) } - return s.SetData(vprKey(i), buf.Bytes()) + return s.SetData(dbkey.SystemVpr(i), buf.Bytes()) } func (b *vprStore) read(s dataGetter, i uint8) ([]*votingPower, error) { - buf, err := s.GetData(vprKey(i)) + buf, err := s.GetData(dbkey.SystemVpr(i)) if err != nil { return nil, err } @@ -611,7 +611,7 @@ func (v *vpr) add(id types.AccountID, addr []byte, power *big.Int) { if vprLogger.IsDebugEnabled() { vprLogger.Debug(). Str("op", "add"). - Str("addr", enc.ToString(addr)). + Str("addr", base58.Encode(addr)). Str("orig", lhs.String()). Str("delta", power.String()). Msg("prepare voting power change") @@ -631,7 +631,7 @@ func (v *vpr) sub(id types.AccountID, addr []byte, power *big.Int) { if vprLogger.IsDebugEnabled() { vprLogger.Debug(). Str("op", "sub"). - Str("addr", enc.ToString(addr)). + Str("addr", base58.Encode(addr)). Str("orig", lhs.String()). Str("delta", power.String()). Msg("prepare voting power change") @@ -710,7 +710,7 @@ func (v *vpr) pickVotingRewardWinner(seed int64) (types.Address, error) { if vprLogger.IsDebugEnabled() { vprLogger.Debug(). Str("total voting power", totalVp.String()). - Str("addr", enc.ToString(winner)). + Str("addr", base58.Encode(winner)). Msg("pick voting reward winner") } @@ -723,11 +723,6 @@ func (v *vpr) pickVotingRewardWinner(seed int64) (types.Address, error) { return nil, ErrNoVotingRewardWinner } -func vprKey(i uint8) []byte { - var vk []byte = vprKeyPrefix - return append(vk, []byte(fmt.Sprintf("%v", i))...) -} - func toVotingPower(e *list.Element) *votingPower { return e.Value.(*votingPower) } diff --git a/contract/system/vprt_test.go b/contract/system/vprt_test.go index 2cd9582b3..ee418bc16 100644 --- a/contract/system/vprt_test.go +++ b/contract/system/vprt_test.go @@ -11,7 +11,7 @@ import ( "github.com/aergoio/aergo-lib/db" "github.com/aergoio/aergo-lib/log" - "github.com/aergoio/aergo/v2/internal/enc" + "github.com/aergoio/aergo/v2/internal/enc/base58" "github.com/aergoio/aergo/v2/state" "github.com/aergoio/aergo/v2/types" "github.com/stretchr/testify/assert" @@ -176,8 +176,8 @@ func openSystemAccount(t *testing.T) *state.ContractState { assert.NoError(t, err, "fail to open the system contract state") logger.Debug().Msgf( "(after) state, contract: %s, %s\n", - enc.ToString(vprStateDB.GetRoot()), - enc.ToString(s.GetStorageRoot())) + base58.Encode(vprStateDB.GetRoot()), + base58.Encode(s.GetStorageRoot())) return s } diff --git a/contract/system_module.c b/contract/system_module.c index 2a7917f8a..dc5d82613 100644 --- a/contract/system_module.c +++ b/contract/system_module.c @@ -303,7 +303,7 @@ static int os_date(lua_State *L) { #endif lua_gasuse(L, 100); if (*s == '!') { /* UTC? */ - s++; /* Skip '!' */ + s++; /* Skip '!' as it always use UTC */ } #if LJ_TARGET_POSIX stm = gmtime_r(&t, &rtm); @@ -322,7 +322,6 @@ static int os_date(lua_State *L) { setfield(L, "year", stm->tm_year+1900); setfield(L, "wday", stm->tm_wday+1); setfield(L, "yday", stm->tm_yday+1); - setboolfield(L, "isdst", stm->tm_isdst); } else { char cc[3]; luaL_Buffer b; @@ -332,15 +331,22 @@ static int os_date(lua_State *L) { if (*s != '%' || *(s + 1) == '\0') { /* No conversion specifier? */ luaL_addchar(&b, *s); } else { - size_t reslen; - char buff[200]; /* Should be big enough for any conversion result. */ + /* strftime specifiers with deterministic output */ + const char *allowed = "cCdDeFgGHjmMRSTuUVwWyY%"; cc[1] = *(++s); - if (cc[1] == 'c') { - reslen = strftime(buff, sizeof(buff), "%Y-%m-%d %H:%M:%S", stm); + if (strchr(allowed, cc[1])) { /* Check if the specifier is allowed */ + size_t reslen; + char buff[200]; /* Should be big enough for any conversion result. */ + if (cc[1] == 'c') { + reslen = strftime(buff, sizeof(buff), "%Y-%m-%d %H:%M:%S", stm); + } else { + reslen = strftime(buff, sizeof(buff), cc, stm); + } + luaL_addlstring(&b, buff, reslen); } else { - reslen = strftime(buff, sizeof(buff), cc, stm); + luaL_addchar(&b, '%'); /* Add the previously skipped '%' */ + luaL_addchar(&b, cc[1]); /* Add the not allowed character */ } - luaL_addlstring(&b, buff, reslen); } } luaL_pushresult(&b); @@ -351,19 +357,18 @@ static int os_date(lua_State *L) { static int os_time(lua_State *L) { time_t t; lua_gasuse(L, 100); - if (lua_isnoneornil(L, 1)) { - t = blocktime(L); + if (lua_isnoneornil(L, 1)) { /* called without args? */ + t = blocktime(L); /* get current time */ } else { - struct tm ts; + struct tm ts = {0}; luaL_checktype(L, 1, LUA_TTABLE); - lua_settop(L, 1); /* make sure table is at the top */ + lua_settop(L, 1); /* make sure table is at the top */ ts.tm_sec = getfield(L, "sec", 0); ts.tm_min = getfield(L, "min", 0); ts.tm_hour = getfield(L, "hour", 12); ts.tm_mday = getfield(L, "day", -1); ts.tm_mon = getfield(L, "month", -1) - 1; ts.tm_year = getfield(L, "year", -1) - 1900; - ts.tm_isdst = getboolfield(L, "isdst"); #if LJ_TARGET_POSIX t = timegm(&ts); #else diff --git a/contract/vm.go b/contract/vm.go index 5417501ef..2a6184dd8 100644 --- a/contract/vm.go +++ b/contract/vm.go @@ -22,7 +22,6 @@ import "C" import ( "bytes" "context" - "encoding/hex" "encoding/json" "errors" "fmt" @@ -39,9 +38,11 @@ import ( "github.com/aergoio/aergo-lib/log" luacUtil "github.com/aergoio/aergo/v2/cmd/aergoluac/util" "github.com/aergoio/aergo/v2/fee" - "github.com/aergoio/aergo/v2/internal/enc" + "github.com/aergoio/aergo/v2/internal/enc/base58" + "github.com/aergoio/aergo/v2/internal/enc/hex" "github.com/aergoio/aergo/v2/state" "github.com/aergoio/aergo/v2/types" + "github.com/aergoio/aergo/v2/types/dbkey" jsoniter "github.com/json-iterator/go" ) @@ -173,7 +174,7 @@ func newContractInfo(cs *callState, sender, contractId []byte, rp uint64, amount func getTraceFile(blkno uint64, tx []byte) *os.File { f, _ := os.OpenFile(fmt.Sprintf("%s%s%d.trace", os.TempDir(), string(os.PathSeparator), blkno), os.O_APPEND|os.O_WRONLY|os.O_CREATE, 0644) if f != nil { - _, _ = f.WriteString(fmt.Sprintf("[START TX]: %s\n", enc.ToString(tx))) + _, _ = f.WriteString(fmt.Sprintf("[START TX]: %s\n", base58.Encode(tx))) } return f } @@ -238,7 +239,7 @@ func NewVmContextQuery( } func (ctx *vmContext) IsGasSystem() bool { - return !ctx.isQuery && PubNet && ctx.blockInfo.ForkVersion >= 2 + return fee.GasEnabled(ctx.blockInfo.ForkVersion) && !ctx.isQuery } // get the remaining gas from the given LState @@ -256,17 +257,7 @@ func (ctx *vmContext) setRemainingGas(L *LState) { } func (ctx *vmContext) usedFee() *big.Int { - if fee.IsZeroFee() { - return fee.NewZeroFee() - } - if ctx.IsGasSystem() { - usedGas := ctx.usedGas() - if ctrLgr.IsDebugEnabled() { - ctrLgr.Debug().Uint64("gas used", usedGas).Str("lua vm", "executed").Msg("gas information") - } - return new(big.Int).Mul(ctx.bs.GasPrice, new(big.Int).SetUint64(usedGas)) - } - return fee.PaymentDataFee(ctx.dbUpdateTotalSize) + return fee.TxExecuteFee(ctx.blockInfo.ForkVersion, ctx.bs.GasPrice, ctx.usedGas(), ctx.dbUpdateTotalSize) } func (ctx *vmContext) usedGas() uint64 { @@ -913,8 +904,8 @@ func setRandomSeed(ctx *vmContext) { if ctx.isQuery { randSrc = rand.NewSource(ctx.blockInfo.Ts) } else { - b, _ := new(big.Int).SetString(enc.ToString(ctx.blockInfo.PrevBlockHash[:7]), 62) - t, _ := new(big.Int).SetString(enc.ToString(ctx.txHash[:7]), 62) + b, _ := new(big.Int).SetString(base58.Encode(ctx.blockInfo.PrevBlockHash[:7]), 62) + t, _ := new(big.Int).SetString(base58.Encode(ctx.txHash[:7]), 62) b.Add(b, t) randSrc = rand.NewSource(b.Int64()) } @@ -1073,7 +1064,7 @@ func Create( } // set the creator - err = contractState.SetData(creatorMetaKey, []byte(types.EncodeAddress(ctx.curContract.sender))) + err = contractState.SetData(dbkey.CreatorMeta(), []byte(types.EncodeAddress(ctx.curContract.sender))) if err != nil { return "", nil, ctx.usedFee(), err } @@ -1458,7 +1449,7 @@ func (ce *executor) vmLoadCode(id []byte) { if ce.ctx.blockInfo.ForkVersion >= 3 { chunkId = C.CString("@" + types.EncodeAddress(id)) } else { - chunkId = C.CString(hex.EncodeToString(id)) + chunkId = C.CString(hex.Encode(id)) } defer C.free(unsafe.Pointer(chunkId)) if cErrMsg := C.vm_loadbuff( diff --git a/contract/vm_callback.go b/contract/vm_callback.go index 5997b0840..7613a960d 100644 --- a/contract/vm_callback.go +++ b/contract/vm_callback.go @@ -26,31 +26,29 @@ struct rlp_obj { import "C" import ( "bytes" - "encoding/hex" "errors" "fmt" - "github.com/aergoio/aergo-lib/log" - "index/suffixarray" "math/big" - "regexp" "strconv" "strings" "unsafe" + "github.com/aergoio/aergo-lib/log" "github.com/aergoio/aergo/v2/cmd/aergoluac/util" "github.com/aergoio/aergo/v2/contract/name" "github.com/aergoio/aergo/v2/contract/system" "github.com/aergoio/aergo/v2/internal/common" - "github.com/aergoio/aergo/v2/internal/enc" + "github.com/aergoio/aergo/v2/internal/enc/base58" + "github.com/aergoio/aergo/v2/internal/enc/hex" "github.com/aergoio/aergo/v2/state" "github.com/aergoio/aergo/v2/types" + "github.com/aergoio/aergo/v2/types/dbkey" "github.com/btcsuite/btcd/btcec" "github.com/minio/sha256-simd" ) var ( mulAergo, mulGaer, zeroBig *big.Int - creatorMetaKey = []byte("Creator") vmLogger = log.NewLogger("contract.vm") ) @@ -787,7 +785,7 @@ func luaGetSender(L *LState, service C.int) *C.char { //export luaGetHash func luaGetHash(L *LState, service C.int) *C.char { ctx := contexts[service] - return C.CString(enc.ToString(ctx.txHash)) + return C.CString(base58.Encode(ctx.txHash)) } //export luaGetBlockNo @@ -825,7 +823,7 @@ func luaGetOrigin(L *LState, service C.int) *C.char { //export luaGetPrevBlockHash func luaGetPrevBlockHash(L *LState, service C.int) *C.char { ctx := contexts[service] - return C.CString(enc.ToString(ctx.blockInfo.PrevBlockHash)) + return C.CString(base58.Encode(ctx.blockInfo.PrevBlockHash)) } //export luaGetDbHandle @@ -873,7 +871,7 @@ func luaCryptoSha256(L *LState, arg unsafe.Pointer, argLen C.int) (*C.char, *C.c if checkHexString(string(data)) { dataStr := data[2:] var err error - data, err = hex.DecodeString(string(dataStr)) + data, err = hex.Decode(string(dataStr)) if err != nil { return nil, C.CString("[Contract.LuaCryptoSha256] hex decoding error: " + err.Error()) } @@ -882,14 +880,14 @@ func luaCryptoSha256(L *LState, arg unsafe.Pointer, argLen C.int) (*C.char, *C.c h.Write(data) resultHash := h.Sum(nil) - return C.CString("0x" + hex.EncodeToString(resultHash)), nil + return C.CString("0x" + hex.Encode(resultHash)), nil } func decodeHex(hexStr string) ([]byte, error) { if checkHexString(hexStr) { hexStr = hexStr[2:] } - return hex.DecodeString(hexStr) + return hex.Decode(hexStr) } //export luaECVerify @@ -973,7 +971,7 @@ func luaCryptoToBytes(data unsafe.Pointer, dataLen C.int) ([]byte, bool) { isHex := checkHexString(string(b)) if isHex { var err error - d, err = hex.DecodeString(string(b[2:])) + d, err = hex.Decode(string(b[2:])) if err != nil { isHex = false } @@ -1025,80 +1023,90 @@ func luaCryptoKeccak256(data unsafe.Pointer, dataLen C.int) (unsafe.Pointer, int d, isHex := luaCryptoToBytes(data, dataLen) h := keccak256(d) if isHex { - hexb := []byte("0x" + hex.EncodeToString(h)) + hexb := []byte("0x" + hex.Encode(h)) return C.CBytes(hexb), len(hexb) } else { return C.CBytes(h), len(h) } } +// transformAmount processes the input string to calculate the total amount, +// taking into account the different units ("aergo", "gaer", "aer") func transformAmount(amountStr string) (*big.Int, error) { - var ret *big.Int - var prev int if len(amountStr) == 0 { return zeroBig, nil } - index := suffixarray.New([]byte(amountStr)) - r := regexp.MustCompile("(?i)aergo|gaer|aer") - res := index.FindAllIndex(r, -1) - for _, pair := range res { - amountBig, _ := new(big.Int).SetString(strings.TrimSpace(amountStr[prev:pair[0]]), 10) - if amountBig == nil { - return nil, errors.New("converting error for BigNum: " + amountStr[prev:]) - } - cmp := amountBig.Cmp(zeroBig) - if cmp < 0 { - return nil, errors.New("negative amount not allowed") - } else if cmp == 0 { - prev = pair[1] - continue - } - switch pair[1] - pair[0] { - case 3: - case 4: - amountBig = new(big.Int).Mul(amountBig, mulGaer) - case 5: - amountBig = new(big.Int).Mul(amountBig, mulAergo) - } - if ret != nil { - ret = new(big.Int).Add(ret, amountBig) - } else { - ret = amountBig - } - prev = pair[1] - } + totalAmount := new(big.Int) + remainingStr := amountStr + + // Define the units and corresponding multipliers + for _, data := range []struct { + unit string + multiplier *big.Int + }{ + {"aergo", mulAergo}, + {"gaer", mulGaer}, + {"aer", zeroBig}, + } { + idx := strings.Index(strings.ToLower(remainingStr), data.unit) + if idx != -1 { + // Extract the part before the unit + subStr := remainingStr[:idx] + + // Parse and convert the amount + partialAmount, err := parseAndConvert(subStr, data.unit, data.multiplier, amountStr) + if err != nil { + return nil, err + } - if prev >= len(amountStr) { - if ret != nil { - return ret, nil - } else { - return zeroBig, nil + // Add to the total amount + totalAmount.Add(totalAmount, partialAmount) + + // Adjust the remaining string to process + remainingStr = remainingStr[idx+len(data.unit):] } } - num := strings.TrimSpace(amountStr[prev:]) - if len(num) == 0 { - if ret != nil { - return ret, nil - } else { - return zeroBig, nil + + // Process the rest of the string, if there is some + if len(remainingStr) > 0 { + partialAmount, err := parseAndConvert(remainingStr, "", zeroBig, amountStr) + if err != nil { + return nil, err } + + // Add to the total amount + totalAmount.Add(totalAmount, partialAmount) } - amountBig, _ := new(big.Int).SetString(num, 10) + return totalAmount, nil +} + +// parseAndConvert is a helper function to parse the substring as a big integer +// and apply the necessary multiplier based on the unit. +func parseAndConvert(subStr, unit string, mulUnit *big.Int, amountStr string) (*big.Int, error) { + trimmedStr := strings.TrimSpace(subStr) - if amountBig == nil { - return nil, errors.New("converting error for Integer: " + amountStr[prev:]) + // Convert the trimmed string to a big integer + amountBig, valid := new(big.Int).SetString(trimmedStr, 10) + if !valid { + // Emits a backwards compatible error message + // the same as: dataType := len(unit) > 0 ? "BigNum" : "Integer" + dataType := map[bool]string{true: "BigNum", false: "Integer"}[len(unit) > 0] + return nil, errors.New("converting error for " + dataType + ": " + strings.TrimSpace(amountStr)) } + + // Check for negative amounts if amountBig.Cmp(zeroBig) < 0 { return nil, errors.New("negative amount not allowed") } - if ret != nil { - ret = new(big.Int).Add(ret, amountBig) - } else { - ret = amountBig + + // Apply multiplier based on unit + if mulUnit != zeroBig { + amountBig.Mul(amountBig, mulUnit) } - return ret, nil + + return amountBig, nil } //export luaDeployContract @@ -1235,7 +1243,7 @@ func luaDeployContract( } // save the contract creator - err = contractState.SetData(creatorMetaKey, []byte(types.EncodeAddress(prevContractInfo.contractId))) + err = contractState.SetData(dbkey.CreatorMeta(), []byte(types.EncodeAddress(prevContractInfo.contractId))) if err != nil { return -1, C.CString("[Contract.LuaDeployContract]:" + err.Error()) } diff --git a/contract/vm_callback_test.go b/contract/vm_callback_test.go new file mode 100644 index 000000000..5f5b9d84f --- /dev/null +++ b/contract/vm_callback_test.go @@ -0,0 +1,138 @@ +package contract + +import ( + "errors" + "math/big" + "testing" + + "github.com/aergoio/aergo/v2/types" + "github.com/stretchr/testify/assert" +) + +func bigIntFromString(str string) *big.Int { + bigInt, success := new(big.Int).SetString(str, 10) + if !success { + panic("bigIntFromString: invalid number: " + str) + } + return bigInt +} + +func TestTransformAmount(t *testing.T) { + // Define the test cases + tests := []struct { + amountStr string + expectedAmount *big.Int + expectedError error + }{ + // Empty Input String + {"", big.NewInt(0), nil}, + // Valid Amount without Unit + {"1", big.NewInt(1), nil}, + {"10", big.NewInt(10), nil}, + {"123", big.NewInt(123), nil}, + {"123000000", big.NewInt(123000000), nil}, + // Valid Amount with Unit + {"100aergo", types.NewAmount(100, types.Aergo), nil}, + {"100 aergo", types.NewAmount(100, types.Aergo), nil}, + {"123gaer", types.NewAmount(123, types.Gaer), nil}, + {"123 gaer", types.NewAmount(123, types.Gaer), nil}, + {"123aer", types.NewAmount(123, types.Aer), nil}, + {"123 aer", types.NewAmount(123, types.Aer), nil}, + // Multipart Amount + {"100aergo 200gaer", bigIntFromString("100000000200000000000"), nil}, + {"100 aergo 123 gaer", bigIntFromString("100000000123000000000"), nil}, + {"123aergo 456aer", bigIntFromString("123000000000000000456"), nil}, + {"123 aergo 456 aer", bigIntFromString("123000000000000000456"), nil}, + {"123aergo 456gaer 789aer", bigIntFromString("123000000456000000789"), nil}, + {"123 aergo 456 gaer 789 aer", bigIntFromString("123000000456000000789"), nil}, + // Invalid Order + {"789aer 456gaer 123aergo", nil, errors.New("converting error for BigNum: 789aer 456gaer 123aergo")}, + {"789 aer 456 gaer 123 aergo", nil, errors.New("converting error for BigNum: 789 aer 456 gaer 123 aergo")}, + {"789aer 123aergo 456gaer", nil, errors.New("converting error for BigNum: 789aer 123aergo 456gaer")}, + {"789 aer 123 aergo 456 gaer", nil, errors.New("converting error for BigNum: 789 aer 123 aergo 456 gaer")}, + {"456gaer 789aer 123aergo", nil, errors.New("converting error for BigNum: 456gaer 789aer 123aergo")}, + {"123aergo 789aer 456gaer", nil, errors.New("converting error for BigNum: 123aergo 789aer 456gaer")}, + // Repeated Units + {"123aergo 456aergo", nil, errors.New("converting error for Integer: 123aergo 456aergo")}, + {"123gaer 456gaer", nil, errors.New("converting error for BigNum: 123gaer 456gaer")}, + {"123aer 456aer", nil, errors.New("converting error for Integer: 123aer 456aer")}, + {"123 aergo 456 aergo", nil, errors.New("converting error for Integer: 123 aergo 456 aergo")}, + {"123 gaer 456 gaer", nil, errors.New("converting error for BigNum: 123 gaer 456 gaer")}, + {"123 aer 456 aer", nil, errors.New("converting error for Integer: 123 aer 456 aer")}, + {"123aergo 456aergo 789aer", nil, errors.New("converting error for Integer: 123aergo 456aergo 789aer")}, + {"123aergo 456aergo 789gaer", nil, errors.New("converting error for BigNum: 123aergo 456aergo 789gaer")}, + {"123aergo 456gaer 789gaer", nil, errors.New("converting error for BigNum: 123aergo 456gaer 789gaer")}, + {"123aergo 456aer 789aer", nil, errors.New("converting error for Integer: 123aergo 456aer 789aer")}, + {"123 aergo 456 aergo 789 aer", nil, errors.New("converting error for Integer: 123 aergo 456 aergo 789 aer")}, + {"123 aergo 456 aergo 789 gaer", nil, errors.New("converting error for BigNum: 123 aergo 456 aergo 789 gaer")}, + {"123 aergo 456 gaer 789 gaer", nil, errors.New("converting error for BigNum: 123 aergo 456 gaer 789 gaer")}, + {"123 aergo 456 aer 789 aer", nil, errors.New("converting error for Integer: 123 aergo 456 aer 789 aer")}, + // Invalid Amount String + {"notanumber", nil, errors.New("converting error for Integer: notanumber")}, + {"e123", nil, errors.New("converting error for Integer: e123")}, + {"123e", nil, errors.New("converting error for Integer: 123e")}, + {"123 456", nil, errors.New("converting error for Integer: 123 456")}, + // Negative Amount + {"-100", nil, errors.New("negative amount not allowed")}, + {"-100aergo", nil, errors.New("negative amount not allowed")}, + {"-100 aergo", nil, errors.New("negative amount not allowed")}, + {"-100 aergo", nil, errors.New("negative amount not allowed")}, + {"-100aer", nil, errors.New("negative amount not allowed")}, + {"-100 aer", nil, errors.New("negative amount not allowed")}, + {"-100 aer", nil, errors.New("negative amount not allowed")}, + // Large Number + {"99999999999999999999999999", bigIntFromString("99999999999999999999999999"), nil}, + // Zero Value + {"0", big.NewInt(0), nil}, + {"0aergo", big.NewInt(0), nil}, + {"0 aergo", big.NewInt(0), nil}, + {"0gaer", big.NewInt(0), nil}, + {"0 gaer", big.NewInt(0), nil}, + {"0aer", big.NewInt(0), nil}, + {"0 aer", big.NewInt(0), nil}, + // Only Unit + {"aergo", nil, errors.New("converting error for BigNum: aergo")}, + {"gaer", nil, errors.New("converting error for BigNum: gaer")}, + {"aer", nil, errors.New("converting error for BigNum: aer")}, + // Invalid Content + {"100 invalid 200", nil, errors.New("converting error for Integer: 100 invalid 200")}, + {"invalid 200", nil, errors.New("converting error for Integer: invalid 200")}, + {"100 invalid", nil, errors.New("converting error for Integer: 100 invalid")}, + // Non-Integer Values + {"123.456", nil, errors.New("converting error for Integer: 123.456")}, + {"123.456 aergo", nil, errors.New("converting error for BigNum: 123.456 aergo")}, + {".1", nil, errors.New("converting error for Integer: .1")}, + {".1aergo", nil, errors.New("converting error for BigNum: .1aergo")}, + {".1 aergo", nil, errors.New("converting error for BigNum: .1 aergo")}, + {".10", nil, errors.New("converting error for Integer: .10")}, + // Exponents + {"1e+18", nil, errors.New("converting error for Integer: 1e+18")}, + {"2e18", nil, errors.New("converting error for Integer: 2e18")}, + {"3e08", nil, errors.New("converting error for Integer: 3e08")}, + {"1e+18 aer", nil, errors.New("converting error for BigNum: 1e+18 aer")}, + {"2e+18 aer", nil, errors.New("converting error for BigNum: 2e+18 aer")}, + {"3e18 aer", nil, errors.New("converting error for BigNum: 3e18 aer")}, + {"1e+18aer", nil, errors.New("converting error for BigNum: 1e+18aer")}, + {"2e+18aer", nil, errors.New("converting error for BigNum: 2e+18aer")}, + {"3e18aer", nil, errors.New("converting error for BigNum: 3e18aer")}, + {"3e+5 aergo", nil, errors.New("converting error for BigNum: 3e+5 aergo")}, + {"3e5 aergo", nil, errors.New("converting error for BigNum: 3e5 aergo")}, + {"3e05 aergo", nil, errors.New("converting error for BigNum: 3e05 aergo")}, + {"5e+3aergo", nil, errors.New("converting error for BigNum: 5e+3aergo")}, + } + + for _, tt := range tests { + result, err := transformAmount(tt.amountStr) + + if tt.expectedError != nil { + if assert.Error(t, err, "Expected error: %s", tt.expectedError.Error()) { + assert.Equal(t, tt.expectedError.Error(), err.Error()) + } + } else { + if assert.NoError(t, err) && tt.expectedAmount != nil { + assert.Equal(t, tt.expectedAmount, result) + } + } + } + +} diff --git a/contract/vm_direct/vm_direct.go b/contract/vm_direct/vm_direct.go new file mode 100644 index 000000000..ecf42f402 --- /dev/null +++ b/contract/vm_direct/vm_direct.go @@ -0,0 +1,646 @@ +package vm_direct + +import ( + "bytes" + "context" + "encoding/json" + "errors" + "fmt" + "math/big" + "os" + "time" + + "github.com/aergoio/aergo-lib/db" + "github.com/aergoio/aergo-lib/log" + "github.com/aergoio/aergo/v2/config" + "github.com/aergoio/aergo/v2/consensus" + "github.com/aergoio/aergo/v2/contract" + "github.com/aergoio/aergo/v2/contract/name" + "github.com/aergoio/aergo/v2/contract/system" + "github.com/aergoio/aergo/v2/fee" + "github.com/aergoio/aergo/v2/internal/enc/base58" + "github.com/aergoio/aergo/v2/state" + "github.com/aergoio/aergo/v2/types" +) + +type ChainType int + +const ( + ChainTypeMainNet ChainType = iota + ChainTypeTestNet + ChainTypeUnitTest +) + +const ( + lStateMaxSize = 10 * 7 +) + +var ( + logger *log.Logger +) + +func init() { + logger = log.NewLogger("vm_dummy") +} + +type DummyChain struct { + chaintype ChainType + HardforkConfig *config.HardforkConfig + sdb *state.ChainStateDB + cBlock *types.Block + bestBlock *types.Block + bestBlockNo types.BlockNo + bestBlockId types.BlockID + tmpDir string + gasPrice *big.Int + timestamp int64 + coinbaseAccount []byte +} + +func LoadDummyChainEx(chainType ChainType) (*DummyChain, error) { + var err error + var gasPrice *big.Int + + switch chainType { + case ChainTypeMainNet: + gasPrice = types.NewAmount(50, types.Gaer) + case ChainTypeTestNet: + gasPrice = types.NewAmount(50, types.Gaer) + case ChainTypeUnitTest: + gasPrice = types.NewAmount(1, types.Aer) + } + + dataPath := "./data/state" + + bc := &DummyChain{ + sdb: state.NewChainStateDB(), + tmpDir: dataPath, + chaintype: chainType, + gasPrice: gasPrice, + } + defer func() { + if err != nil { + bc.Release() + } + }() + + if chainType == ChainTypeMainNet { + bc.HardforkConfig = config.MainNetHardforkConfig + } else if chainType == ChainTypeTestNet { + bc.HardforkConfig = config.TestNetHardforkConfig + } else { + bc.HardforkConfig = config.AllEnabledHardforkConfig + } + + // mainnet and testnet use badger db. the dummy tests use memory db. + dbImpl := db.BadgerImpl + if chainType == ChainTypeUnitTest { + dbImpl = db.MemoryImpl + } + + // clear folder if exists + _ = os.RemoveAll(dataPath) + // initialize the state database + err = bc.sdb.Init(string(dbImpl), dataPath, nil, false) + if err != nil { + return nil, err + } + + var genesis *types.Genesis + + switch chainType { + case ChainTypeMainNet: + genesis = types.GetMainNetGenesis() + case ChainTypeTestNet: + genesis = types.GetTestNetGenesis() + case ChainTypeUnitTest: + genesis = types.GetTestGenesis() + } + + bc.sdb.SetGenesis(genesis, nil) + bc.bestBlock = genesis.Block() + bc.bestBlockNo = genesis.Block().BlockNo() + bc.bestBlockId = genesis.Block().BlockID() + + // before starting the LState factory + if chainType == ChainTypeUnitTest { + fee.EnableZeroFee() + } else { + contract.PubNet = true + } + + // state sql database + contract.LoadTestDatabase(dataPath) + contract.SetStateSQLMaxDBSize(1024) + + contract.StartLStateFactory(lStateMaxSize, config.GetDefaultNumLStateClosers(), 1) + contract.InitContext(3) + + // To pass the governance tests. + types.InitGovernance("dpos", true) + + // To pass dao parameters test + scs, err := bc.sdb.GetStateDB().OpenContractStateAccount(types.ToAccountID([]byte("aergo.system"))) + system.InitSystemParams(scs, 3) + + return bc, nil +} + +func (bc *DummyChain) Release() { + _ = os.RemoveAll(bc.tmpDir) +} + +func (bc *DummyChain) SetBestBlockId(value []byte) { + bc.bestBlockId = types.ToBlockID(value) +} + +func (bc *DummyChain) SetBestBlockNo(value uint64) { + bc.bestBlockNo = value +} + +func (bc *DummyChain) BestBlockNo() uint64 { + return bc.bestBlockNo +} + +func (bc *DummyChain) GetBestBlock() (*types.Block, error) { + return bc.bestBlock, nil +} + +func (bc *DummyChain) GetBlockByNo(blockNo types.BlockNo) (*types.Block, error) { + //return bc.blocks[blockNo], nil + return bc.bestBlock, nil +} + +func (bc *DummyChain) SetTimestamp(value int64) { + bc.timestamp = value +} + +func (bc *DummyChain) getTimestamp() int64 { + + if bc.timestamp != 0 { + return bc.timestamp + } else { + return time.Now().UnixNano() + } + +} + +func (bc *DummyChain) SetCoinbaseAccount(address []byte) { + bc.coinbaseAccount = address +} + +//////////////////////////////////////////////////////////////////////// + +func (bc *DummyChain) newBlockState() *state.BlockState { + bc.cBlock = &types.Block{ + Header: &types.BlockHeader{ + PrevBlockHash: bc.bestBlockId[:], + BlockNo: bc.bestBlockNo + 1, + Timestamp: bc.getTimestamp(), + ChainID: types.MakeChainId(bc.bestBlock.GetHeader().ChainID, bc.HardforkConfig.Version(bc.bestBlockNo+1)), + }, + } + return state.NewBlockState( + bc.sdb.OpenNewStateDB(bc.sdb.GetRoot()), + state.SetPrevBlockHash(bc.cBlock.GetHeader().PrevBlockHash), // or .GetPrevBlockHash() + state.SetGasPrice(bc.gasPrice), + ) +} + +func (bc *DummyChain) ExecuteTxs(txs []*types.Tx) ([]*types.Receipt, error) { + + ex, err := newBlockExecutor(bc, txs) + if err != nil { + return nil, err + } + + if err := ex.execute(); err != nil { + return nil, err + } + + bc.cBlock.SetBlocksRootHash(bc.sdb.GetRoot()) + bc.bestBlock = bc.cBlock + bc.bestBlockNo = bc.bestBlockNo + 1 + bc.bestBlockId = types.ToBlockID(bc.cBlock.BlockHash()) + + receipts := ex.BlockState.Receipts().Get() + + return receipts, nil +} + +type TxExecFn func(blockState *state.BlockState, tx types.Transaction) error +type ValidatePostFn func() error + +type blockExecutor struct { + *state.BlockState + sdb *state.ChainStateDB + execTx TxExecFn + txs []*types.Tx + validatePost ValidatePostFn + coinbaseAcccount []byte + bi *types.BlockHeaderInfo +} + +func newBlockExecutor(bc *DummyChain, txs []*types.Tx) (*blockExecutor, error) { + var exec TxExecFn + var bi *types.BlockHeaderInfo + + blockState := bc.newBlockState() + bi = types.NewBlockHeaderInfo(bc.cBlock) + + exec = NewTxExecutor(context.Background(), nil, bc, bi, contract.ChainService) + + blockState.SetGasPrice(system.GetGasPriceFromState(blockState)) + + blockState.Receipts().SetHardFork(bc.HardforkConfig, bc.bestBlockNo+1) + + return &blockExecutor{ + BlockState: blockState, + sdb: bc.sdb, + execTx: exec, + txs: txs, + coinbaseAcccount: bc.coinbaseAccount, + //validatePost: func() error { + // return cs.validator.ValidatePost(blockState.GetRoot(), blockState.Receipts(), block) + //}, + bi: bi, + }, nil + +} + +func NewTxExecutor(execCtx context.Context, ccc consensus.ChainConsensusCluster, cdb contract.ChainAccessor, bi *types.BlockHeaderInfo, preloadService int) TxExecFn { + + return func(blockState *state.BlockState, tx types.Transaction) error { + + if blockState == nil { + return errors.New("blockState is nil in txexec") + } + if bi.ForkVersion < 0 { + return errors.New("ChainID.ForkVersion < 0") + } + + blockSnap := blockState.Snapshot() + + err := executeTx(execCtx, ccc, cdb, blockState, tx, bi, preloadService) + if err != nil { + logger.Error().Err(err).Str("hash", base58.Encode(tx.GetHash())).Msg("tx failed") + if err2 := blockState.Rollback(blockSnap); err2 != nil { + logger.Panic().Err(err).Msg("failed to rollback block state") + } + return err + } + + return nil + } + +} + +// execute all transactions in the block +func (e *blockExecutor) execute() error { + + defer contract.CloseDatabase() + + var preloadTx *types.Tx + + numTxs := len(e.txs) + + for i, tx := range e.txs { + // if tx is not the last one, preload the next tx + if i != numTxs-1 { + preloadTx = e.txs[i+1] + contract.RequestPreload(e.BlockState, e.bi, preloadTx, tx, contract.ChainService) + } + // execute the transaction + if err := e.execTx(e.BlockState, types.NewTransaction(tx)); err != nil { + return err + } + // mark the next preload tx to be executed + contract.SetPreloadTx(preloadTx, contract.ChainService) + } + + if err := SendBlockReward(e.BlockState, e.coinbaseAcccount); err != nil { + return err + } + + if err := contract.SaveRecoveryPoint(e.BlockState); err != nil { + return err + } + + if err := e.Update(); err != nil { + return err + } + + //if err := e.validatePost(); err != nil { + // return err + //} + + if err := e.commit(); err != nil { + return err + } + + return nil +} + +func (e *blockExecutor) commit() error { + + if err := e.BlockState.Commit(); err != nil { + return err + } + + if err := e.sdb.UpdateRoot(e.BlockState); err != nil { + return err + } + + return nil +} + +const maxRetSize = 1024 + +func adjustReturnValue(ret string) string { + if len(ret) > maxRetSize { + modified, _ := json.Marshal(ret[:maxRetSize-4] + " ...") + return string(modified) + } + return ret +} + +func resetAccount(account *state.V, fee *big.Int, nonce *uint64) error { + account.Reset() + if fee != nil { + if account.Balance().Cmp(fee) < 0 { + return &types.InternalError{Reason: "fee is greater than balance"} + } + account.SubBalance(fee) + } + if nonce != nil { + account.SetNonce(*nonce) + } + return account.PutState() +} + +func executeTx( + execCtx context.Context, + ccc consensus.ChainConsensusCluster, + cdb contract.ChainAccessor, + bs *state.BlockState, + tx types.Transaction, + bi *types.BlockHeaderInfo, + preloadService int, +) error { + + var ( + txBody = tx.GetBody() + isQuirkTx = types.IsQuirkTx(tx.GetHash()) + account []byte + recipient []byte + err error + ) + + if account, err = name.Resolve(bs, txBody.GetAccount(), isQuirkTx); err != nil { + return err + } + + if tx.HasVerifedAccount() { + txAcc := tx.GetVerifedAccount() + tx.RemoveVerifedAccount() + if !bytes.Equal(txAcc, account) { + return types.ErrSignNotMatch + } + } + + err = tx.Validate(bi.ChainIdHash(), IsPublic()) + if err != nil { + return err + } + + sender, err := bs.GetAccountStateV(account) + if err != nil { + return err + } + + // check for sufficient balance + senderState := sender.State() + amount := tx.GetBody().GetAmountBigInt() + balance := senderState.GetBalanceBigInt() + + switch tx.GetBody().GetType() { + case types.TxType_NORMAL, types.TxType_REDEPLOY, types.TxType_TRANSFER, types.TxType_CALL, types.TxType_DEPLOY: + if balance.Cmp(amount) <= 0 { + // set the balance as amount + fee + to_add := new(big.Int).SetUint64(1000000000000000000) + balance = new(big.Int).Add(amount, to_add) + senderState.Balance = balance.Bytes() + } + case types.TxType_GOVERNANCE: + switch string(tx.GetBody().GetRecipient()) { + case types.AergoSystem: + if balance.Cmp(amount) <= 0 { + // set the balance as amount + fee + to_add := new(big.Int).SetUint64(1000000000000000000) + balance = new(big.Int).Add(amount, to_add) + senderState.Balance = balance.Bytes() + } + case types.AergoName: + if balance.Cmp(amount) <= 0 { + // set the balance as = amount + senderState.Balance = amount.Bytes() + } + } + case types.TxType_FEEDELEGATION: + if balance.Cmp(amount) <= 0 { + // set the balance as = amount + senderState.Balance = amount.Bytes() + } + } + + err = tx.ValidateWithSenderState(senderState, bs.GasPrice, bi.ForkVersion) + if err != nil { + err = fmt.Errorf("%w: balance %s, amount %s, gasPrice %s, block %v, txhash: %s", + err, + sender.Balance().String(), + tx.GetBody().GetAmountBigInt().String(), + bs.GasPrice.String(), + bi.No, base58.Encode(tx.GetHash())) + return err + } + + if recipient, err = name.Resolve(bs, txBody.Recipient, isQuirkTx); err != nil { + return err + } + var receiver *state.V + status := "SUCCESS" + if len(recipient) > 0 { + receiver, err = bs.GetAccountStateV(recipient) + if receiver != nil && txBody.Type == types.TxType_REDEPLOY { + status = "RECREATED" + receiver.SetRedeploy() + } + } else { + receiver, err = bs.CreateAccountStateV(contract.CreateContractID(txBody.Account, txBody.Nonce)) + status = "CREATED" + } + if err != nil { + return err + } + + var txFee *big.Int + var rv string + var events []*types.Event + switch txBody.Type { + case types.TxType_NORMAL, types.TxType_REDEPLOY, types.TxType_TRANSFER, types.TxType_CALL, types.TxType_DEPLOY: + rv, events, txFee, err = contract.Execute(execCtx, bs, cdb, tx.GetTx(), sender, receiver, bi, preloadService, false) + sender.SubBalance(txFee) + case types.TxType_GOVERNANCE: + txFee = new(big.Int).SetUint64(0) + events, err = executeGovernanceTx(ccc, bs, txBody, sender, receiver, bi) + if err != nil { + logger.Warn().Err(err).Str("txhash", base58.Encode(tx.GetHash())).Msg("governance tx Error") + } + case types.TxType_FEEDELEGATION: + err = tx.ValidateMaxFee(receiver.Balance(), bs.GasPrice, bi.ForkVersion) + if err != nil { + return err + } + var contractState *state.ContractState + contractState, err = bs.OpenContractState(receiver.AccountID(), receiver.State()) + if err != nil { + return err + } + err = contract.CheckFeeDelegation(recipient, bs, bi, cdb, contractState, txBody.GetPayload(), + tx.GetHash(), txBody.GetAccount(), txBody.GetAmount()) + if err != nil { + if err != types.ErrNotAllowedFeeDelegation { + logger.Warn().Err(err).Str("txhash", base58.Encode(tx.GetHash())).Msg("checkFeeDelegation Error") + return err + } + return types.ErrNotAllowedFeeDelegation + } + rv, events, txFee, err = contract.Execute(execCtx, bs, cdb, tx.GetTx(), sender, receiver, bi, preloadService, true) + receiver.SubBalance(txFee) + } + + if err != nil { + // Reset events on error + if bi.ForkVersion >= 3 { + events = nil + } + + if !contract.IsRuntimeError(err) { + return err + } + if txBody.Type != types.TxType_FEEDELEGATION || sender.AccountID() == receiver.AccountID() { + sErr := resetAccount(sender, txFee, &txBody.Nonce) + if sErr != nil { + return sErr + } + } else { + sErr := resetAccount(sender, nil, &txBody.Nonce) + if sErr != nil { + return sErr + } + sErr = resetAccount(receiver, txFee, nil) + if sErr != nil { + return sErr + } + } + status = "ERROR" + rv = err.Error() + } else { + if txBody.Type != types.TxType_FEEDELEGATION { + if sender.Balance().Sign() < 0 { + return &types.InternalError{Reason: "fee is greater than balance"} + } + } else { + if receiver.Balance().Sign() < 0 { + return &types.InternalError{Reason: "fee is greater than balance"} + } + } + sender.SetNonce(txBody.Nonce) + err = sender.PutState() + if err != nil { + return err + } + if sender.AccountID() != receiver.AccountID() { + err = receiver.PutState() + if err != nil { + return err + } + } + rv = adjustReturnValue(rv) + } + bs.BpReward.Add(&bs.BpReward, txFee) + + receipt := types.NewReceipt(receiver.ID(), status, rv) + receipt.FeeUsed = txFee.Bytes() + receipt.TxHash = tx.GetHash() + receipt.Events = events + receipt.FeeDelegation = txBody.Type == types.TxType_FEEDELEGATION + isGovernance := txBody.Type == types.TxType_GOVERNANCE + receipt.GasUsed = fee.ReceiptGasUsed(bi.ForkVersion, isGovernance, txFee, bs.GasPrice) + + return bs.AddReceipt(receipt) +} + +func executeGovernanceTx(ccc consensus.ChainConsensusCluster, bs *state.BlockState, txBody *types.TxBody, sender, receiver *state.V, + blockInfo *types.BlockHeaderInfo) ([]*types.Event, error) { + + if len(txBody.Payload) <= 0 { + return nil, types.ErrTxFormatInvalid + } + + governance := string(txBody.Recipient) + + scs, err := bs.StateDB.OpenContractState(receiver.AccountID(), receiver.State()) + if err != nil { + return nil, err + } + + var events []*types.Event + + switch governance { + case types.AergoSystem: + events, err = system.ExecuteSystemTx(scs, txBody, sender, receiver, blockInfo) + case types.AergoName: + events, err = name.ExecuteNameTx(bs, scs, txBody, sender, receiver, blockInfo) + default: + logger.Warn().Str("governance", governance).Msg("receive unknown recipient") + err = types.ErrTxInvalidRecipient + } + + if err == nil { + err = bs.StateDB.StageContractState(scs) + } + + return events, err +} + +func SendBlockReward(bState *state.BlockState, coinbaseAccount []byte) error { + bpReward := &bState.BpReward + if bpReward.Cmp(new(big.Int).SetUint64(0)) <= 0 || coinbaseAccount == nil { + logger.Debug().Str("reward", bpReward.String()).Msg("coinbase is skipped") + return nil + } + + receiverID := types.ToAccountID(coinbaseAccount) + receiverState, err := bState.GetAccountState(receiverID) + if err != nil { + return err + } + + receiverChange := types.State(*receiverState) + receiverChange.Balance = new(big.Int).Add(receiverChange.GetBalanceBigInt(), bpReward).Bytes() + + err = bState.PutState(receiverID, &receiverChange) + if err != nil { + return err + } + + logger.Debug().Str("reward", bpReward.String()). + Str("newbalance", receiverChange.GetBalanceBigInt().String()).Msg("send reward to coinbase account") + + return nil +} + +func IsPublic() bool { + return true +} diff --git a/contract/vm_dummy/test_files/contract_call_1.lua b/contract/vm_dummy/test_files/contract_call_1.lua index 94d89b088..8bf4f5807 100644 --- a/contract/vm_dummy/test_files/contract_call_1.lua +++ b/contract/vm_dummy/test_files/contract_call_1.lua @@ -1,3 +1,4 @@ + function constructor(init) system.setItem("count", init) end @@ -17,3 +18,20 @@ function set(val) end abi.register(inc, get, set) + + +function get_call_info(address, fname, info) + + local call_info = { + sender = system.getSender(), + origin = system.getOrigin(), + ctr_id = system.getContractID() + } + + if info == nil then info = {} end + table.insert(info, call_info) + + return contract.call(address, fname, info) +end + +abi.register(get_call_info) diff --git a/contract/vm_dummy/test_files/contract_call_2.lua b/contract/vm_dummy/test_files/contract_call_2.lua index ecb699093..3037b4d90 100644 --- a/contract/vm_dummy/test_files/contract_call_2.lua +++ b/contract/vm_dummy/test_files/contract_call_2.lua @@ -1,29 +1,40 @@ + function constructor(addr) system.setItem("count", 99) system.setItem("addr", addr) end -function add(amount) +function inc() + count = system.getItem("count") + system.setItem("count", count + 1) + return count +end + +function get() + return system.getItem("count") +end + +function set(val) + system.setItem("count", val) +end + +function cinc(amount) return contract.call.value(amount)(system.getItem("addr"), "inc") end -function dadd() +function dinc() return contract.delegatecall(system.getItem("addr"), "inc") end -function get() - addr = system.getItem("addr") - a = contract.call(addr, "get") - return a +function cget() + return contract.call(system.getItem("addr"), "get") end function dget() - addr = system.getItem("addr") - a = contract.delegatecall(addr, "get") - return a + return contract.delegatecall(system.getItem("addr"), "get") end -function set(val) +function cset(val) contract.call(system.getItem("addr"), "set", val) end @@ -31,4 +42,26 @@ function dset(val) contract.delegatecall(system.getItem("addr"), "set", val) end -abi.register(add, dadd, get, dget, set, dset) +abi.register(inc, cinc, dinc, get, cget, dget, set, cset, dset) + + +function get_call_info(address, fname, info) + info = get_call_info2(info) + return contract.delegatecall(system.getItem("addr"), "get_call_info", address, fname, info) +end + +function get_call_info2(info) + + local call_info = { + sender = system.getSender(), + origin = system.getOrigin(), + ctr_id = system.getContractID() + } + + if info == nil then info = {} end + table.insert(info, call_info) + + return info +end + +abi.register(get_call_info, get_call_info2) diff --git a/contract/vm_dummy/test_files/contract_call_3.lua b/contract/vm_dummy/test_files/contract_call_3.lua new file mode 100644 index 000000000..98f03a2b6 --- /dev/null +++ b/contract/vm_dummy/test_files/contract_call_3.lua @@ -0,0 +1,16 @@ + +function get_call_info(info) + + local call_info = { + sender = system.getSender(), + origin = system.getOrigin(), + ctr_id = system.getContractID() + } + + if info == nil then info = {} end + table.insert(info, call_info) + + return info +end + +abi.register(get_call_info) diff --git a/contract/vm_dummy/test_files/contract_call_self.lua b/contract/vm_dummy/test_files/contract_call_self.lua new file mode 100644 index 000000000..07644f9dc --- /dev/null +++ b/contract/vm_dummy/test_files/contract_call_self.lua @@ -0,0 +1,30 @@ +-- simple case + +function call_myself() + return contract.call(system.getContractID(), "test") +end + +function test() + return 123 +end + +abi.register(call_myself, test) + +-- recursive call with state variable + +state.var { + v = state.value() +} + +function call_me_again(n, max) + n = n + 1 + v:set(n) + if n < max then + contract.call(system.getContractID(), "call_me_again", n, max) + end + if n == 1 then + return v:get() + end +end + +abi.register(call_me_again) diff --git a/contract/vm_dummy/test_files/contract_pingpongcall_1.lua b/contract/vm_dummy/test_files/contract_pingpongcall_1.lua index f4b278cd0..afc23d284 100644 --- a/contract/vm_dummy/test_files/contract_pingpongcall_1.lua +++ b/contract/vm_dummy/test_files/contract_pingpongcall_1.lua @@ -5,6 +5,7 @@ end function start(addr) system.setItem("key", "start") contract.call(addr, "called") + return system.getItem("key") end function callback() diff --git a/contract/vm_dummy/test_files/feature_luacryptoverifyproof.lua b/contract/vm_dummy/test_files/feature_crypto_verify_proof.lua similarity index 100% rename from contract/vm_dummy/test_files/feature_luacryptoverifyproof.lua rename to contract/vm_dummy/test_files/feature_crypto_verify_proof.lua diff --git a/contract/vm_dummy/test_files/feature_isolation.lua b/contract/vm_dummy/test_files/feature_isolation.lua new file mode 100644 index 000000000..84fd6abb6 --- /dev/null +++ b/contract/vm_dummy/test_files/feature_isolation.lua @@ -0,0 +1,143 @@ +state.var { + v = state.value() +} + +function assert2(condition, message) + if not condition then + error(message or "Assertion failed!") + end +end + +function override_functions() + + -- override the assert function + assert = function(condition, message) + v:set("overridden") + end + + -- override system.getSender and system.getOrigin + system.getSender = function() return "overridden" end + system.getOrigin = function() return "overridden" end + + -- override contract.balance + contract.balance = function() return "123" end + + -- override the __add metamethod on bignum module + getmetatable(bignum.number(0)).__add = function(x,y) return x-y end + +end + +function check_local_overridden_functions() + + v:set("") + local success, ret = pcall(test_assert) + assert2(success, "assert override failed 1") + assert2(v:get() == "overridden", "assert override failed 2") + + assert2(test_sender() == "overridden", "system.getSender() override failed") + assert2(test_origin() == "overridden", "system.getOrigin() override failed") + assert2(test_balance() == "123", "contract.balance() override failed") + assert2(test_bignum() == bignum.number(3), "metamethod override failed") + +end + +function test_vm_isolation_forward(address) + + override_functions() + + check_local_overridden_functions() + + + -- test assert on another call to this contract - it should fail + v:set("") + local success, ret = pcall(contract.call, system.getContractID(), "test_assert") + assert2(success == false, "override worked on another instance 1") + assert2(v:get() ~= "overridden", "override worked on another instance 2") + + -- test assert on another contract - it should fail + local success, ret = pcall(contract.call, address, "test_assert") + assert2(success == false, "override worked on another contract 1") + ret = contract.call(address, "get") + assert2(ret ~= "overridden", "override worked on another contract 2") + + -- test them on another call to this instance + ret = contract.call(system.getContractID(), "test_sender") + assert2(ret ~= "overridden", "override worked on another instance 3") + ret = contract.call(system.getContractID(), "test_origin") + assert2(ret ~= "overridden", "override worked on another instance 4") + ret = contract.call(system.getContractID(), "test_balance") + assert2(ret ~= "123", "override worked on another instance 5") + ret = contract.call(system.getContractID(), "test_bignum") + assert2(ret ~= "7", "override worked on another instance 6") + + -- test them on another contract + ret = contract.call(address, "test_sender") + assert2(ret ~= "overridden", "override worked on another contract 3") + ret = contract.call(address, "test_origin") + assert2(ret ~= "overridden", "override worked on another contract 4") + ret = contract.call(address, "test_balance") + assert2(ret ~= "123", "override worked on another contract 5") + ret = contract.call(address, "test_bignum") + assert2(ret ~= "7", "override worked on another contract 6") + +end + +function test_assert() + assert(1 == 0, "original assert") +end + +function test_sender() + return system.getSender() +end + +function test_origin() + return system.getOrigin() +end + +function test_balance() + return contract.balance() +end + +function test_bignum() + return bignum.number(5) + bignum.number(2) +end + +function get() + return v:get() +end + +abi.register(test_vm_isolation_forward, test_assert, test_sender, test_origin, test_balance, test_bignum) +abi.register_view(get) + +--[[ +The above is used when contract A overrides the functions and test on called contract B. +Below is the opposite: contract A calls B, B overrides the functions and return, then +A checks if the functions were overridden on its contract +]] + +function test_vm_isolation_reverse(address) + + -- contract A calls B (it can be the same contract) + local ret = contract.call(address, "override_and_return") + assert2(ret == "overridden", "override did not work on contract B") + + -- check if the functions on this contract were overridden + v:set("") + local success, ret = pcall(test_assert) + assert2(success == false, "assert reverse override worked 1") + assert2(v:get() ~= "overridden", "assert reverse override worked 2") + + assert2(test_sender() ~= "overridden", "system.getSender() reverse override worked") + assert2(test_origin() ~= "overridden", "system.getOrigin() reverse override worked") + assert2(test_balance() ~= "123", "contract.balance() reverse override worked") + assert2(test_bignum() ~= "7", "bignum.number() reverse override worked") + +end + +function override_and_return() + override_functions() + check_local_overridden_functions() + return v:get() +end + +abi.register(test_vm_isolation_reverse, override_and_return) diff --git a/contract/vm_dummy/test_files/feature_pcallnested.lua b/contract/vm_dummy/test_files/feature_pcall_nested.lua similarity index 100% rename from contract/vm_dummy/test_files/feature_pcallnested.lua rename to contract/vm_dummy/test_files/feature_pcall_nested.lua diff --git a/contract/vm_dummy/test_files/feature_pcallrollback_1.lua b/contract/vm_dummy/test_files/feature_pcall_rollback_1.lua similarity index 84% rename from contract/vm_dummy/test_files/feature_pcallrollback_1.lua rename to contract/vm_dummy/test_files/feature_pcall_rollback_1.lua index 3f071280d..22a91ad4e 100644 --- a/contract/vm_dummy/test_files/feature_pcallrollback_1.lua +++ b/contract/vm_dummy/test_files/feature_pcall_rollback_1.lua @@ -4,10 +4,10 @@ end function init() db.exec([[create table if not exists r ( - id integer primary key - , n integer check(n >= 10) - , nonull text not null - , only integer unique) + id integer primary key, + n integer check(n >= 10), + nonull text not null, + norepeat integer unique) ]]) db.exec("insert into r values (1, 11, 'text', 1)") end @@ -24,9 +24,7 @@ end function pkget() local rs = db.query("select count(*) from r") if rs:next() then - local n = rs:get() - --rs:next() - return n + return rs:get() else return "error in count()" end diff --git a/contract/vm_dummy/test_files/feature_pcallrollback_2.lua b/contract/vm_dummy/test_files/feature_pcall_rollback_2.lua similarity index 100% rename from contract/vm_dummy/test_files/feature_pcallrollback_2.lua rename to contract/vm_dummy/test_files/feature_pcall_rollback_2.lua diff --git a/contract/vm_dummy/test_files/feature_pcallrollback_3.lua b/contract/vm_dummy/test_files/feature_pcall_rollback_3.lua similarity index 100% rename from contract/vm_dummy/test_files/feature_pcallrollback_3.lua rename to contract/vm_dummy/test_files/feature_pcall_rollback_3.lua diff --git a/contract/vm_dummy/test_files/feature_pcall_rollback_4.lua b/contract/vm_dummy/test_files/feature_pcall_rollback_4.lua new file mode 100644 index 000000000..d8765e13a --- /dev/null +++ b/contract/vm_dummy/test_files/feature_pcall_rollback_4.lua @@ -0,0 +1,128 @@ +state.var { + resolver = state.value(), + name = state.value(), + values = state.map() +} + +function constructor(resolver_address, contract_name) + -- initialize state variables + resolver:set(resolver_address) + name:set(contract_name) + -- initialize db + db.exec("create table config (value integer primary key) without rowid") + db.exec("insert into config values (0)") + db.exec([[create table products ( + id integer primary key, + name text not null, + price real) + ]]) + db.exec("insert into products (name,price) values ('first', 1234.56)") +end + +function resolve(name) + return contract.call(resolver:get(), "resolve", name) +end + +--[[ + ['set','x',111], + ['pcall','A'] +],[ + ['set','x',222], + ['pcall','A'], + ['fail'] +],[ + ['set','x',333] +]] + +function test(script) + -- get the commands for this function to execute + local commands = table.remove(script, 1) + + -- execute each command + for i, cmd in ipairs(commands) do + local action = cmd[1] + if action == "set" then + contract.event(name:get() .. ".set", cmd[2], cmd[3]) + values[cmd[2]] = cmd[3] + elseif action == "pcall" then + local to_call = cmd[2] + local amount = cmd[3] + if to_call == name:get() then + contract.pcall(test, script) + elseif amount ~= nil then + contract.event(name:get() .. " send " .. to_call, amount) + local address = resolve(to_call) + success, ret = contract.pcall(function() + return contract.call.value(amount)(address, "test", script) + end) + else + local address = resolve(to_call) + success, ret = contract.pcall(contract.call, address, "test", script) + end + --contract.event("result", success, ret) + elseif action == "send" then + local to = cmd[2] + contract.event(name:get() .. " send " .. to, amount) + contract.send(resolve(to), cmd[3]) + elseif action == "deploy" then + local code_or_address = resolve_deploy(cmd[2]) + contract.pcall(contract.deploy, code_or_address, unpack(cmd,3)) + elseif action == "deploy.send" then + contract.event(name:get() .. ".deploy.send", amount) + local code_or_address = resolve_deploy(cmd[3]) + contract.pcall(function() + contract.deploy.value(cmd[2])(code_or_address, unpack(cmd,4)) + end) + elseif action == "db.set" then + db.exec("update config set value = " .. cmd[2]) + elseif action == "db.insert" then + db.exec("insert into products (name,price) values ('another',1234.56)") + elseif action == "fail" then + assert(1 == 0, "failed") + end + end + +end + +function set(key, value) + values[key] = value +end + +function get(key) + return values[key] +end + +function db_reset() + db.exec("update config set value = 0") + db.exec("delete from products where id > 1") +end + +function db_get() + local rs = db.query("select value from config") + if rs:next() then + return rs:get() + else + return "error" + end +end + +function db_count() + local rs = db.query("select count(*) from products") + if rs:next() then + return rs:get() + else + return "error" + end +end + +function default() + -- only receive +end + +function send_back(to) + contract.send(resolve(to), contract.balance()) +end + +abi.payable(constructor, test, default) +abi.register(set, send_back, db_reset) +abi.register_view(get, db_get, db_count) diff --git a/contract/vm_dummy/test_files/gas_per_function.lua b/contract/vm_dummy/test_files/gas_per_function.lua index 3b27a8192..bd1bf0be4 100644 --- a/contract/vm_dummy/test_files/gas_per_function.lua +++ b/contract/vm_dummy/test_files/gas_per_function.lua @@ -1286,9 +1286,9 @@ function run_test(function_name, ...) end -function deposit() +function default() -- do nothing, only receive native aergo tokens end abi.register(run_test) -abi.payable(deposit) +abi.payable(default) diff --git a/contract/vm_dummy/test_files/resolver.lua b/contract/vm_dummy/test_files/resolver.lua new file mode 100644 index 000000000..55f694b45 --- /dev/null +++ b/contract/vm_dummy/test_files/resolver.lua @@ -0,0 +1,14 @@ +state.var { + xx = state.map() +} + +function set(name, address) + xx[name] = address +end + +function resolve(name) + return xx[name] +end + +abi.register(set) +abi.register_view(resolve) diff --git a/contract/vm_dummy/test_files/type_datetime.lua b/contract/vm_dummy/test_files/type_datetime.lua index b72b8c460..0f6385d6b 100644 --- a/contract/vm_dummy/test_files/type_datetime.lua +++ b/contract/vm_dummy/test_files/type_datetime.lua @@ -3,26 +3,32 @@ state.var { } function constructor() - cdate:set(906000490) + cdate:set(905465118) end -function CreateDate() - return system.date("%c", cdate:get()) +function SetTimestamp(value) + cdate:set(value) end -function Extract(fmt) - return system.date(fmt, cdate:get()) +function CreateDate(format, timestamp) + return system.date(format, timestamp) +end + +function Extract(format) + return system.date(format, cdate:get()) end function Difftime() - system.print(system.date("%c", cdate:get())) + -- test convertion to table s = system.date("*t", cdate:get()) - system.print(s) + -- modification of table s.hour = 2 s.min = 0 s.sec = 0 - system.print(system.date("*t", system.time(s))) - return system.difftime(cdate:get(), system.time(s)) + -- system.difftime() and system.time() + diff = system.difftime(cdate:get(), system.time(s)) + -- conversion of diff to hours + return diff, system.date("%T",diff) end -abi.register(CreateDate, Extract, Difftime) +abi.register(CreateDate, SetTimestamp, Extract, Difftime) diff --git a/contract/vm_dummy/test_files/type_random.lua b/contract/vm_dummy/test_files/type_random.lua index e7fe68929..47f63d23c 100644 --- a/contract/vm_dummy/test_files/type_random.lua +++ b/contract/vm_dummy/test_files/type_random.lua @@ -1,5 +1,16 @@ function random(...) - return system.random(...) + return system.random(...) end -abi.register(random) +function get_numbers(count) + local list = {} + + for i = 1, count do + local num = system.random(1, 100) + table.insert(list, num) + end + + return list +end + +abi.register(random, get_numbers) diff --git a/contract/vm_dummy/test_files/type_random_caller.lua b/contract/vm_dummy/test_files/type_random_caller.lua new file mode 100644 index 000000000..9e87c9c6d --- /dev/null +++ b/contract/vm_dummy/test_files/type_random_caller.lua @@ -0,0 +1,35 @@ +-- check if numbers generated by a called contract are +-- the same if called on the same transaction +function check_if_equal(address) + + local list1 = contract.call(address, 'get_numbers', 10) + local list2 = contract.call(address, 'get_numbers', 10) + local list3 = contract.call(address, 'get_numbers', 10) + + if lists_are_equal(list1, list2) then + return true + end + if lists_are_equal(list2, list3) then + return true + end + + return false +end + +function lists_are_equal(list1, list2) + -- check if lengths are different + if #list1 ~= #list2 then + return false + end + + -- compare each element + for i = 1, #list1 do + if list1[i] ~= list2[i] then + return false + end + end + + return true +end + +abi.register(check_if_equal) diff --git a/contract/vm_dummy/vm_dummy.go b/contract/vm_dummy/vm_dummy.go index 3ded2810c..8443a896f 100644 --- a/contract/vm_dummy/vm_dummy.go +++ b/contract/vm_dummy/vm_dummy.go @@ -20,7 +20,7 @@ import ( "github.com/aergoio/aergo/v2/contract" "github.com/aergoio/aergo/v2/contract/system" "github.com/aergoio/aergo/v2/fee" - "github.com/aergoio/aergo/v2/internal/enc" + "github.com/aergoio/aergo/v2/internal/enc/base58" "github.com/aergoio/aergo/v2/state" "github.com/aergoio/aergo/v2/types" sha256 "github.com/minio/sha256-simd" @@ -134,7 +134,6 @@ func LoadDummyChain(opts ...DummyChainOptions) (*DummyChain, error) { // To pass the governance tests. types.InitGovernance("dpos", true) - system.InitGovernance("dpos") // To pass dao parameters test scs, err := bc.sdb.GetStateDB().GetSystemAccountState() @@ -466,7 +465,7 @@ func contractFrame(l luaTxContract, bs *state.BlockState, cdb contract.ChainAcce if err != nil { return err } - usedFee := contract.TxFee(len(l.payload()), types.NewAmount(1, types.Aer), 2) + usedFee := fee.TxBaseFee(2, types.NewAmount(1, types.Aer), len(l.payload())) if l.isFeeDelegate() { balance := contractState.Balance() @@ -478,7 +477,7 @@ func contractFrame(l luaTxContract, bs *state.BlockState, cdb contract.ChainAcce l.Hash(), l.sender(), l.amount().Bytes()) if err != nil { if err != types.ErrNotAllowedFeeDelegation { - logger.Debug().Err(err).Str("txhash", enc.ToString(l.Hash())).Msg("checkFeeDelegation Error") + logger.Debug().Err(err).Str("txhash", base58.Encode(l.Hash())).Msg("checkFeeDelegation Error") return err } return types.ErrNotAllowedFeeDelegation diff --git a/contract/vm_dummy/vm_dummy_pub_test.go b/contract/vm_dummy/vm_dummy_pub_test.go index 988f6d8a4..4f41f0395 100644 --- a/contract/vm_dummy/vm_dummy_pub_test.go +++ b/contract/vm_dummy/vm_dummy_pub_test.go @@ -28,36 +28,38 @@ func TestContractSendF(t *testing.T) { code := readLuaCode(t, "contract_sendf_1.lua") code2 := readLuaCode(t, "contract_sendf_2.lua") - bc, err := LoadDummyChain(SetPubNet()) - require.NoErrorf(t, err, "failed to create dummy chain") - defer bc.Release() - - err = bc.ConnectBlock( - NewLuaTxAccount("user1", 1, types.Aergo), - NewLuaTxDeploy("user1", "test1", 50000000000000000, code), - NewLuaTxDeploy("user1", "test2", 0, code2), - ) - require.NoErrorf(t, err, "failed to connect new block") - - tx := NewLuaTxCall("user1", "test1", 0, fmt.Sprintf(`{"Name":"send", "Args":["%s"]}`, nameToAddress("test2"))) - err = bc.ConnectBlock(tx) - require.NoErrorf(t, err, "failed to connect new block") + for version := int32(3); version <= max_version; version++ { + bc, err := LoadDummyChain(SetHardForkVersion(version), SetPubNet()) + require.NoErrorf(t, err, "failed to create dummy chain") + defer bc.Release() + + err = bc.ConnectBlock( + NewLuaTxAccount("user1", 1, types.Aergo), + NewLuaTxDeploy("user1", "test1", 50000000000000000, code), + NewLuaTxDeploy("user1", "test2", 0, code2), + ) + require.NoErrorf(t, err, "failed to connect new block") + + tx := NewLuaTxCall("user1", "test1", 0, fmt.Sprintf(`{"Name":"send", "Args":["%s"]}`, nameToAddress("test2"))) + err = bc.ConnectBlock(tx) + require.NoErrorf(t, err, "failed to connect new block") - r := bc.GetReceipt(tx.Hash()) - assert.Equalf(t, int64(105087), int64(r.GetGasUsed()), "gas used not equal") + r := bc.GetReceipt(tx.Hash()) + assert.Equalf(t, int64(105087), int64(r.GetGasUsed()), "gas used not equal") - state, err := bc.GetAccountState("test2") - assert.Equalf(t, int64(2), state.GetBalanceBigInt().Int64(), "balance state not equal") + state, err := bc.GetAccountState("test2") + assert.Equalf(t, int64(2), state.GetBalanceBigInt().Int64(), "balance state not equal") - tx = NewLuaTxCall("user1", "test1", 0, fmt.Sprintf(`{"Name":"send2", "Args":["%s"]}`, nameToAddress("test2"))) - err = bc.ConnectBlock(tx) - require.NoErrorf(t, err, "failed to connect new block") + tx = NewLuaTxCall("user1", "test1", 0, fmt.Sprintf(`{"Name":"send2", "Args":["%s"]}`, nameToAddress("test2"))) + err = bc.ConnectBlock(tx) + require.NoErrorf(t, err, "failed to connect new block") - r = bc.GetReceipt(tx.Hash()) - assert.Equalf(t, int64(105179), int64(r.GetGasUsed()), "gas used not equal") + r = bc.GetReceipt(tx.Hash()) + assert.Equalf(t, int64(105179), int64(r.GetGasUsed()), "gas used not equal") - state, err = bc.GetAccountState("test2") - assert.Equalf(t, int64(6), state.GetBalanceBigInt().Int64(), "balance state not equal") + state, err = bc.GetAccountState("test2") + assert.Equalf(t, int64(6), state.GetBalanceBigInt().Int64(), "balance state not equal") + } } func TestGasPerFunction(t *testing.T) { @@ -81,8 +83,8 @@ func TestGasPerFunction(t *testing.T) { // transfer funds to the contracts err = bc.ConnectBlock( - NewLuaTxCall("user", "contract_v2", uint64(10e18), `{"Name":"deposit"}`), - NewLuaTxCall("user", "contract_v3", uint64(10e18), `{"Name":"deposit"}`), + NewLuaTxCall("user", "contract_v2", uint64(10e18), `{"Name":"default"}`), + NewLuaTxCall("user", "contract_v3", uint64(10e18), `{"Name":"default"}`), ) assert.NoError(t, err, "sending funds to contracts") @@ -477,7 +479,7 @@ func TestGasBF(t *testing.T) { func TestGasLuaCryptoVerifyProof(t *testing.T) { skipNotOnAmd64(t) - code := readLuaCode(t, "feature_luacryptoverifyproof.lua") + code := readLuaCode(t, "feature_crypto_verify_proof.lua") // v2 raw err := expectGas(string(code), 0, `"verifyProofRaw"`, ``, 154137, SetHardForkVersion(2)) @@ -553,33 +555,35 @@ func TestTypeInvalidKey(t *testing.T) { code := readLuaCode(t, "type_invalidkey.lua") - bc, err := LoadDummyChain() - require.NoErrorf(t, err, "failed to create dummy chain") - defer bc.Release() + for version := int32(3); version <= max_version; version++ { + bc, err := LoadDummyChain(SetHardForkVersion(version)) + require.NoErrorf(t, err, "failed to create dummy chain") + defer bc.Release() - err = bc.ConnectBlock(NewLuaTxAccount("user1", 1, types.Aergo), NewLuaTxDeploy("user1", "invalidkey", 0, code)) - require.NoErrorf(t, err, "failed to deploy") + err = bc.ConnectBlock(NewLuaTxAccount("user1", 1, types.Aergo), NewLuaTxDeploy("user1", "invalidkey", 0, code)) + require.NoErrorf(t, err, "failed to deploy") - err = bc.ConnectBlock(NewLuaTxCall("user1", "invalidkey", 0, `{"Name":"key_table"}`).Fail("cannot use 'table' as a key")) - require.NoErrorf(t, err, "failed to call tx") + err = bc.ConnectBlock(NewLuaTxCall("user1", "invalidkey", 0, `{"Name":"key_table"}`).Fail("cannot use 'table' as a key")) + require.NoErrorf(t, err, "failed to call tx") - err = bc.ConnectBlock(NewLuaTxCall("user1", "invalidkey", 0, `{"Name":"key_func"}`).Fail("cannot use 'function' as a key")) - require.NoErrorf(t, err, "failed to call tx") + err = bc.ConnectBlock(NewLuaTxCall("user1", "invalidkey", 0, `{"Name":"key_func"}`).Fail("cannot use 'function' as a key")) + require.NoErrorf(t, err, "failed to call tx") - err = bc.ConnectBlock(NewLuaTxCall("user1", "invalidkey", 0, `{"Name":"key_statemap"}`).Fail("cannot use 'userdata' as a key")) - require.NoErrorf(t, err, "failed to call tx") + err = bc.ConnectBlock(NewLuaTxCall("user1", "invalidkey", 0, `{"Name":"key_statemap"}`).Fail("cannot use 'userdata' as a key")) + require.NoErrorf(t, err, "failed to call tx") - err = bc.ConnectBlock(NewLuaTxCall("user1", "invalidkey", 0, `{"Name":"key_statearray"}`).Fail("cannot use 'userdata' as a key")) - require.NoErrorf(t, err, "failed to call tx") + err = bc.ConnectBlock(NewLuaTxCall("user1", "invalidkey", 0, `{"Name":"key_statearray"}`).Fail("cannot use 'userdata' as a key")) + require.NoErrorf(t, err, "failed to call tx") - err = bc.ConnectBlock(NewLuaTxCall("user1", "invalidkey", 0, `{"Name":"key_statevalue"}`).Fail("cannot use 'userdata' as a key")) - require.NoErrorf(t, err, "failed to call tx") + err = bc.ConnectBlock(NewLuaTxCall("user1", "invalidkey", 0, `{"Name":"key_statevalue"}`).Fail("cannot use 'userdata' as a key")) + require.NoErrorf(t, err, "failed to call tx") - err = bc.ConnectBlock(NewLuaTxCall("user1", "invalidkey", 0, `{"Name":"key_upval"}`).Fail("cannot use 'table' as a key")) - require.NoErrorf(t, err, "failed to call tx") + err = bc.ConnectBlock(NewLuaTxCall("user1", "invalidkey", 0, `{"Name":"key_upval"}`).Fail("cannot use 'table' as a key")) + require.NoErrorf(t, err, "failed to call tx") - err = bc.ConnectBlock(NewLuaTxCall("user1", "invalidkey", 0, `{"Name":"key_nil"}`).Fail("invalid key type: 'nil', state.map: 'h'")) - require.NoErrorf(t, err, "failed to call tx") + err = bc.ConnectBlock(NewLuaTxCall("user1", "invalidkey", 0, `{"Name":"key_nil"}`).Fail("invalid key type: 'nil', state.map: 'h'")) + require.NoErrorf(t, err, "failed to call tx") + } } func TestTypeBigTable(t *testing.T) { @@ -591,25 +595,27 @@ func TestTypeBigTable(t *testing.T) { code := readLuaCode(t, "type_bigtable_1.lua") code2 := readLuaCode(t, "type_bigtable_2.lua") - bc, err := LoadDummyChain() - require.NoErrorf(t, err, "failed to create dummy chain") - defer bc.Release() + for version := int32(3); version <= max_version; version++ { + bc, err := LoadDummyChain(SetHardForkVersion(version)) + require.NoErrorf(t, err, "failed to create dummy chain") + defer bc.Release() - err = bc.ConnectBlock(NewLuaTxAccount("user1", 1, types.Aergo), NewLuaTxDeploy("user1", "big", 0, code)) - require.NoErrorf(t, err, "failed to deploy") + err = bc.ConnectBlock(NewLuaTxAccount("user1", 1, types.Aergo), NewLuaTxDeploy("user1", "big", 0, code)) + require.NoErrorf(t, err, "failed to deploy") - // About 900MB - err = bc.ConnectBlock(NewLuaTxCall("user1", "big", 0, `{"Name": "inserts", "Args":[25]}`)) - require.NoErrorf(t, err, "failed to call tx") + // About 900MB + err = bc.ConnectBlock(NewLuaTxCall("user1", "big", 0, `{"Name": "inserts", "Args":[25]}`)) + require.NoErrorf(t, err, "failed to call tx") - contract.SetStateSQLMaxDBSize(20) - err = bc.ConnectBlock(NewLuaTxAccount("user1", 100, types.Aer), NewLuaTxDeploy("user1", "big20", 0, code2)) - require.NoErrorf(t, err, "failed to deploy") + contract.SetStateSQLMaxDBSize(20) + err = bc.ConnectBlock(NewLuaTxAccount("user1", 100, types.Aer), NewLuaTxDeploy("user1", "big20", 0, code2)) + require.NoErrorf(t, err, "failed to deploy") - for i := 0; i < 17; i++ { - err = bc.ConnectBlock(NewLuaTxCall("user1", "big20", 0, `{"Name": "inserts"}`)) + for i := 0; i < 17; i++ { + err = bc.ConnectBlock(NewLuaTxCall("user1", "big20", 0, `{"Name": "inserts"}`)) + require.NoErrorf(t, err, "failed to call tx") + } + err = bc.ConnectBlock(NewLuaTxCall("user1", "big20", 0, `{"Name": "inserts"}`).Fail("database or disk is full")) require.NoErrorf(t, err, "failed to call tx") } - err = bc.ConnectBlock(NewLuaTxCall("user1", "big20", 0, `{"Name": "inserts"}`).Fail("database or disk is full")) - require.NoErrorf(t, err, "failed to call tx") } diff --git a/contract/vm_dummy/vm_dummy_test.go b/contract/vm_dummy/vm_dummy_test.go index a8fcd305b..aa591ebfc 100644 --- a/contract/vm_dummy/vm_dummy_test.go +++ b/contract/vm_dummy/vm_dummy_test.go @@ -497,8 +497,9 @@ func TestContractQuery(t *testing.T) { } func TestContractCall(t *testing.T) { - code := readLuaCode(t, "contract_call_1.lua") + code1 := readLuaCode(t, "contract_call_1.lua") code2 := readLuaCode(t, "contract_call_2.lua") + code3 := readLuaCode(t, "contract_call_3.lua") for version := min_version; version <= max_version; version++ { bc, err := LoadDummyChain(SetHardForkVersion(version)) @@ -507,49 +508,156 @@ func TestContractCall(t *testing.T) { err = bc.ConnectBlock( NewLuaTxAccount("user1", 1, types.Aergo), - NewLuaTxDeploy("user1", "counter", 0, code).Constructor("[1]"), + // deploy the counter contract + NewLuaTxDeploy("user1", "counter", 0, code1).Constructor("[1]"), + // increment the value NewLuaTxCall("user1", "counter", 0, `{"Name":"inc", "Args":[]}`), ) require.NoErrorf(t, err, "failed to connect new block") + // check the value + err = bc.Query("counter", `{"Name":"get", "Args":[]}`, "", "2") require.NoErrorf(t, err, "failed to query") err = bc.ConnectBlock( + // deploy the caller contract NewLuaTxDeploy("user1", "caller", 0, code2).Constructor(fmt.Sprintf(`["%s"]`, nameToAddress("counter"))), - NewLuaTxCall("user1", "caller", 0, `{"Name":"add", "Args":[]}`), + // indirectly increment the value on the counter contract + NewLuaTxCall("user1", "caller", 0, `{"Name":"cinc", "Args":[]}`), ) require.NoErrorf(t, err, "failed to connect new block") - err = bc.Query("caller", `{"Name":"get", "Args":[]}`, "", "3") + // check the value on both contracts + + err = bc.Query("caller", `{"Name":"cget", "Args":[]}`, "", "3") + require.NoErrorf(t, err, "failed to query") + + err = bc.Query("counter", `{"Name":"get", "Args":[]}`, "", "3") require.NoErrorf(t, err, "failed to query") err = bc.Query("caller", `{"Name":"dget", "Args":[]}`, "", "99") require.NoErrorf(t, err, "failed to query") - tx := NewLuaTxCall("user1", "caller", 0, `{"Name":"dadd", "Args":[]}`) + err = bc.Query("caller", `{"Name":"get", "Args":[]}`, "", "99") + require.NoErrorf(t, err, "failed to query") + + // use delegate call to increment the value on the same contract + + tx := NewLuaTxCall("user1", "caller", 0, `{"Name":"dinc", "Args":[]}`) err = bc.ConnectBlock(tx) require.NoErrorf(t, err, "failed to connect new block") - receipt := bc.GetReceipt(tx.Hash()) assert.Equalf(t, `99`, receipt.GetRet(), "contract Call ret error") - tx = NewLuaTxCall("user1", "caller", 0, `{"Name":"dadd", "Args":[]}`) + // do it again + + tx = NewLuaTxCall("user1", "caller", 0, `{"Name":"dinc", "Args":[]}`) err = bc.ConnectBlock(tx) require.NoErrorf(t, err, "failed to connect new block") - receipt = bc.GetReceipt(tx.Hash()) assert.Equalf(t, `100`, receipt.GetRet(), "contract Call ret error") - err = bc.Query("caller", `{"Name":"get", "Args":[]}`, "", "3") + // check the value on both contracts + + err = bc.Query("caller", `{"Name":"cget", "Args":[]}`, "", "3") + require.NoErrorf(t, err, "failed to query") + + err = bc.Query("counter", `{"Name":"get", "Args":[]}`, "", "3") + require.NoErrorf(t, err, "failed to query") + + err = bc.Query("caller", `{"Name":"dget", "Args":[]}`, "", "101") + require.NoErrorf(t, err, "failed to query") + + err = bc.Query("caller", `{"Name":"get", "Args":[]}`, "", "101") + require.NoErrorf(t, err, "failed to query") + + // use delegate call to set the value on the same contract + + tx = NewLuaTxCall("user1", "caller", 0, `{"Name":"dset", "Args":[500]}`) + err = bc.ConnectBlock(tx) + require.NoErrorf(t, err, "failed to connect new block") + receipt = bc.GetReceipt(tx.Hash()) + assert.Equalf(t, ``, receipt.GetRet(), "contract Call ret error") + + // check the value on both contracts + + err = bc.Query("caller", `{"Name":"cget", "Args":[]}`, "", "3") + require.NoErrorf(t, err, "failed to query") + + err = bc.Query("counter", `{"Name":"get", "Args":[]}`, "", "3") + require.NoErrorf(t, err, "failed to query") + + err = bc.Query("caller", `{"Name":"dget", "Args":[]}`, "", "500") + require.NoErrorf(t, err, "failed to query") + + err = bc.Query("caller", `{"Name":"get", "Args":[]}`, "", "500") + require.NoErrorf(t, err, "failed to query") + + // indirectly set the value on the counter contract + + tx = NewLuaTxCall("user1", "caller", 0, `{"Name":"cset", "Args":[750]}`) + err = bc.ConnectBlock(tx) + require.NoErrorf(t, err, "failed to connect new block") + receipt = bc.GetReceipt(tx.Hash()) + assert.Equalf(t, ``, receipt.GetRet(), "contract Call ret error") + + // check the value on both contracts + + err = bc.Query("caller", `{"Name":"cget", "Args":[]}`, "", "750") + require.NoErrorf(t, err, "failed to query") + + err = bc.Query("counter", `{"Name":"get", "Args":[]}`, "", "750") + require.NoErrorf(t, err, "failed to query") + + err = bc.Query("caller", `{"Name":"dget", "Args":[]}`, "", "500") + require.NoErrorf(t, err, "failed to query") + + err = bc.Query("caller", `{"Name":"get", "Args":[]}`, "", "500") + require.NoErrorf(t, err, "failed to query") + + // collect call info using delegate call: A -> delegate_call(B) -> A + + tx = NewLuaTxCall("user1", "caller", 0, `{"Name":"get_call_info", "Args":["AmggmgtWPXtsDkC5hkYYx2iYaWfGs8D4ZvZNwxwdm4gxGSDaCqKn","get_call_info2"]}`) + err = bc.ConnectBlock(tx) + require.NoErrorf(t, err, "failed to connect new block") + receipt = bc.GetReceipt(tx.Hash()) + expected := `[{"ctr_id":"AmggmgtWPXtsDkC5hkYYx2iYaWfGs8D4ZvZNwxwdm4gxGSDaCqKn","origin":"Amg25cfD4ibjmjPYbtWnMKocrF147gJJxKy5uuFymEBNF2YiPwzr","sender":"Amg25cfD4ibjmjPYbtWnMKocrF147gJJxKy5uuFymEBNF2YiPwzr"},{"ctr_id":"AmggmgtWPXtsDkC5hkYYx2iYaWfGs8D4ZvZNwxwdm4gxGSDaCqKn","origin":"Amg25cfD4ibjmjPYbtWnMKocrF147gJJxKy5uuFymEBNF2YiPwzr","sender":"Amg25cfD4ibjmjPYbtWnMKocrF147gJJxKy5uuFymEBNF2YiPwzr"},{"ctr_id":"AmggmgtWPXtsDkC5hkYYx2iYaWfGs8D4ZvZNwxwdm4gxGSDaCqKn","origin":"Amg25cfD4ibjmjPYbtWnMKocrF147gJJxKy5uuFymEBNF2YiPwzr","sender":"AmggmgtWPXtsDkC5hkYYx2iYaWfGs8D4ZvZNwxwdm4gxGSDaCqKn"}]` + assert.Equalf(t, expected, receipt.GetRet(), "contract Call ret error") + + // collect call info via delegate call using query + + expected = `[{"ctr_id":"AmggmgtWPXtsDkC5hkYYx2iYaWfGs8D4ZvZNwxwdm4gxGSDaCqKn","origin":"","sender":""},{"ctr_id":"AmggmgtWPXtsDkC5hkYYx2iYaWfGs8D4ZvZNwxwdm4gxGSDaCqKn","origin":"","sender":""},{"ctr_id":"AmggmgtWPXtsDkC5hkYYx2iYaWfGs8D4ZvZNwxwdm4gxGSDaCqKn","origin":"","sender":"AmggmgtWPXtsDkC5hkYYx2iYaWfGs8D4ZvZNwxwdm4gxGSDaCqKn"}]` + err = bc.Query("caller", `{"Name":"get_call_info", "Args":["AmggmgtWPXtsDkC5hkYYx2iYaWfGs8D4ZvZNwxwdm4gxGSDaCqKn","get_call_info2"]}`, "", expected) + require.NoErrorf(t, err, "failed to query") + + // deploy the third contract + + err = bc.ConnectBlock( + NewLuaTxDeploy("user1", "third", 0, code3), + ) + require.NoErrorf(t, err, "failed to connect new block") + + // collect call info using delegate call: A -> delegate_call(B) -> C + + tx = NewLuaTxCall("user1", "caller", 0, `{"Name":"get_call_info", "Args":["AmhJ2JWVSDeXxYrMRtH38hjnGDLVkLJCLD1XCTGZSjoQV2xCQUEg","get_call_info"]}`) + err = bc.ConnectBlock(tx) + require.NoErrorf(t, err, "failed to connect new block") + receipt = bc.GetReceipt(tx.Hash()) + expected = `[{"ctr_id":"AmggmgtWPXtsDkC5hkYYx2iYaWfGs8D4ZvZNwxwdm4gxGSDaCqKn","origin":"Amg25cfD4ibjmjPYbtWnMKocrF147gJJxKy5uuFymEBNF2YiPwzr","sender":"Amg25cfD4ibjmjPYbtWnMKocrF147gJJxKy5uuFymEBNF2YiPwzr"},{"ctr_id":"AmggmgtWPXtsDkC5hkYYx2iYaWfGs8D4ZvZNwxwdm4gxGSDaCqKn","origin":"Amg25cfD4ibjmjPYbtWnMKocrF147gJJxKy5uuFymEBNF2YiPwzr","sender":"Amg25cfD4ibjmjPYbtWnMKocrF147gJJxKy5uuFymEBNF2YiPwzr"},{"ctr_id":"AmhJ2JWVSDeXxYrMRtH38hjnGDLVkLJCLD1XCTGZSjoQV2xCQUEg","origin":"Amg25cfD4ibjmjPYbtWnMKocrF147gJJxKy5uuFymEBNF2YiPwzr","sender":"AmggmgtWPXtsDkC5hkYYx2iYaWfGs8D4ZvZNwxwdm4gxGSDaCqKn"}]` + assert.Equalf(t, expected, receipt.GetRet(), "contract Call ret error") + + // collect call info via delegate call using query + + expected = `[{"ctr_id":"AmggmgtWPXtsDkC5hkYYx2iYaWfGs8D4ZvZNwxwdm4gxGSDaCqKn","origin":"","sender":""},{"ctr_id":"AmggmgtWPXtsDkC5hkYYx2iYaWfGs8D4ZvZNwxwdm4gxGSDaCqKn","origin":"","sender":""},{"ctr_id":"AmhJ2JWVSDeXxYrMRtH38hjnGDLVkLJCLD1XCTGZSjoQV2xCQUEg","origin":"","sender":"AmggmgtWPXtsDkC5hkYYx2iYaWfGs8D4ZvZNwxwdm4gxGSDaCqKn"}]` + err = bc.Query("caller", `{"Name":"get_call_info", "Args":["AmhJ2JWVSDeXxYrMRtH38hjnGDLVkLJCLD1XCTGZSjoQV2xCQUEg","get_call_info"]}`, "", expected) require.NoErrorf(t, err, "failed to query") } } -func TestContractPingpongCall(t *testing.T) { - code := readLuaCode(t, "contract_pingpongcall_1.lua") - code2 := readLuaCode(t, "contract_pingpongcall_2.lua") +func TestContractCallSelf(t *testing.T) { + code := readLuaCode(t, "contract_call_self.lua") for version := min_version; version <= max_version; version++ { bc, err := LoadDummyChain(SetHardForkVersion(version)) @@ -558,21 +666,56 @@ func TestContractPingpongCall(t *testing.T) { err = bc.ConnectBlock( NewLuaTxAccount("user1", 1, types.Aergo), - NewLuaTxDeploy("user1", "a", 0, code), + NewLuaTxDeploy("user1", "A", 0, code), ) require.NoErrorf(t, err, "failed to connect new block") - err = bc.ConnectBlock(NewLuaTxDeploy("user1", "b", 0, code2).Constructor(fmt.Sprintf(`["%s"]`, nameToAddress("a")))) + tx := NewLuaTxCall("user1", "A", 0, `{"Name":"call_myself", "Args":[]}`) + err = bc.ConnectBlock(tx) + require.NoErrorf(t, err, "failed to connect new block") + receipt := bc.GetReceipt(tx.Hash()) + require.Equalf(t, `123`, receipt.GetRet(), "contract call ret error") + + // make a recursive call like this: A -> A -> A -> A -> A + tx = NewLuaTxCall("user1", "A", 0, `{"Name":"call_me_again", "Args":[0,5]}`) + err = bc.ConnectBlock(tx) + require.NoErrorf(t, err, "failed to connect new block") + // make sure the first instance can read the updated state variable + receipt = bc.GetReceipt(tx.Hash()) + require.Equalf(t, `5`, receipt.GetRet(), "contract call ret error") + + } +} + +func TestContractPingPongCall(t *testing.T) { + code1 := readLuaCode(t, "contract_pingpongcall_1.lua") + code2 := readLuaCode(t, "contract_pingpongcall_2.lua") + + for version := min_version; version <= max_version; version++ { + bc, err := LoadDummyChain(SetHardForkVersion(version)) + require.NoErrorf(t, err, "failed to create dummy chain") + defer bc.Release() + + err = bc.ConnectBlock( + NewLuaTxAccount("user1", 1, types.Aergo), + NewLuaTxDeploy("user1", "A", 0, code1), + NewLuaTxDeploy("user1", "B", 0, code2).Constructor(fmt.Sprintf(`["%s"]`, nameToAddress("A"))), + ) require.NoErrorf(t, err, "failed to connect new block") - tx := NewLuaTxCall("user1", "a", 0, fmt.Sprintf(`{"Name":"start", "Args":["%s"]}`, nameToAddress("b"))) + // make a ping pong call like this: A -> B -> A + tx := NewLuaTxCall("user1", "A", 0, fmt.Sprintf(`{"Name":"start", "Args":["%s"]}`, nameToAddress("B"))) err = bc.ConnectBlock(tx) require.NoErrorf(t, err, "failed to connect new block") - err = bc.Query("a", `{"Name":"get", "Args":[]}`, "", `"callback"`) + // make sure the first instance can read the updated state variable + receipt := bc.GetReceipt(tx.Hash()) + require.Equalf(t, `"callback"`, receipt.GetRet(), "contract call ret error") + + err = bc.Query("A", `{"Name":"get"}`, "", `"callback"`) require.NoErrorf(t, err, "failed to query") - err = bc.Query("b", `{"Name":"get", "Args":[]}`, "", `"called"`) + err = bc.Query("B", `{"Name":"get"}`, "", `"called"`) require.NoErrorf(t, err, "failed to query") } @@ -1995,22 +2138,106 @@ func TestTypeDatetime(t *testing.T) { err = bc.ConnectBlock(NewLuaTxAccount("user1", 1, types.Aergo), NewLuaTxDeploy("user1", "datetime", 0, code)) require.NoErrorf(t, err, "failed to deploy") - err = bc.Query("datetime", `{"Name": "CreateDate"}`, "", `"1998-09-17 02:48:10"`) + // not allowed specifiers + + err = bc.Query("datetime", `{"Name": "Extract", "Args":["%a%A%b%B%h%I%n%p%r%t%x%X%z%Z"]}`, "", `"%a%A%b%B%h%I%n%p%r%t%x%X%z%Z"`) + require.NoErrorf(t, err, "failed to query") + + // allowed specifiers + + specifiers := map[string]string{ + "%c": "1998-09-10 22:05:18", + "%C": "19", + "%d": "10", + "%D": "09/10/98", + "%e": "10", + "%F": "1998-09-10", + "%g": "98", + "%G": "1998", + "%H": "22", + "%j": "253", // Day of the year [001,366] + "%m": "09", + "%M": "05", + "%R": "22:05", + "%S": "18", + "%T": "22:05:18", + "%u": "4", // Monday as 1 through Sunday as 7 + "%U": "36", // Week number of the year (Sunday as the first day of the week) + "%V": "37", // ISO 8601 week number + "%w": "4", // Sunday as 0, Saturday as 6 + "%W": "36", // Week number of the year (Monday as the first day of the week) + "%y": "98", + "%Y": "1998", + "%%": "%", + } + + for specifier, expected := range specifiers { + err := bc.Query("datetime", `{"Name": "Extract", "Args":["`+specifier+`"]}`, "", `"`+expected+`"`) + require.NoErrorf(t, err, "failed to query with specifier %s", specifier) + } + + err = bc.Query("datetime", `{"Name": "Extract", "Args":["%FT%T"]}`, "", `"1998-09-10T22:05:18"`) require.NoErrorf(t, err, "failed to query") - err = bc.Query("datetime", `{"Name": "Extract", "Args":["%x"]}`, "", `"09/17/98"`) + err = bc.Query("datetime", `{"Name": "Extract", "Args":["%Y-%m-%d %H:%M:%S"]}`, "", `"1998-09-10 22:05:18"`) require.NoErrorf(t, err, "failed to query") - err = bc.Query("datetime", `{"Name": "Extract", "Args":["%X"]}`, "", `"02:48:10"`) + err = bc.Query("datetime", `{"Name": "Difftime"}`, "", `[72318,"20:05:18"]`) require.NoErrorf(t, err, "failed to query") - err = bc.Query("datetime", `{"Name": "Extract", "Args":["%A"]}`, "", `"Thursday"`) + // set a fixed timestamp for the next block + bc.SetTimestamp(false, 1696286666) + // need to create the block for the next queries to use the value + err = bc.ConnectBlock( + NewLuaTxCall("user1", "datetime", 0, `{"Name": "SetTimestamp", "Args": [2527491900]}`), + ) + require.NoErrorf(t, err, "failed to call tx") + + // use the block timestamp + + err = bc.Query("datetime", `{"Name": "CreateDate", "Args":["%Y-%m-%d %H:%M:%S"]}`, "", `"2023-10-02 22:44:26"`) + require.NoErrorf(t, err, "failed to query") + + // used the new stored timestamp + + specifiers = map[string]string{ + "%c": "2050-02-03 09:05:00", + "%C": "20", + "%d": "03", + "%D": "02/03/50", + "%e": " 3", // Space-padded day of the month + "%F": "2050-02-03", + "%g": "50", + "%G": "2050", + "%H": "09", + "%j": "034", // Day of the year [001,366] + "%m": "02", + "%M": "05", + "%R": "09:05", + "%S": "00", + "%T": "09:05:00", + "%u": "4", // Thursday (Monday as 1, Sunday as 7) + "%U": "05", // Week number of the year (Sunday as the first day of the week) + "%V": "05", // ISO 8601 week number + "%w": "4", // Sunday as 0, Saturday as 6 + "%W": "05", // Week number of the year (Monday as the first day of the week) + "%y": "50", + "%Y": "2050", + "%%": "%", + } + + for specifier, expected := range specifiers { + err := bc.Query("datetime", `{"Name": "Extract", "Args":["`+specifier+`"]}`, "", `"`+expected+`"`) + require.NoErrorf(t, err, "failed to query with specifier %s", specifier) + } + + err = bc.Query("datetime", `{"Name": "Extract", "Args":["%FT%T"]}`, "", `"2050-02-03T09:05:00"`) require.NoErrorf(t, err, "failed to query") - err = bc.Query("datetime", `{"Name": "Extract", "Args":["%I:%M:%S %p"]}`, "", `"02:48:10 AM"`) + err = bc.Query("datetime", `{"Name": "Extract", "Args":["%Y-%m-%d %H:%M:%S"]}`, "", `"2050-02-03 09:05:00"`) require.NoErrorf(t, err, "failed to query") - err = bc.Query("datetime", `{"Name": "Difftime"}`, "", `2890`) + err = bc.Query("datetime", `{"Name": "Difftime"}`, "", `[25500,"07:05:00"]`) require.NoErrorf(t, err, "failed to query") } @@ -2171,14 +2398,19 @@ func checkRandomIntValue(v string, min, max int) error { } func TestTypeRandom(t *testing.T) { - code := readLuaCode(t, "type_random.lua") + code1 := readLuaCode(t, "type_random.lua") + code2 := readLuaCode(t, "type_random_caller.lua") for version := min_version; version <= max_version; version++ { bc, err := LoadDummyChain(SetHardForkVersion(version)) require.NoErrorf(t, err, "failed to create dummy chain") defer bc.Release() - err = bc.ConnectBlock(NewLuaTxAccount("user1", 1, types.Aergo), NewLuaTxDeploy("user1", "random", 0, code)) + err = bc.ConnectBlock( + NewLuaTxAccount("user1", 1, types.Aergo), + NewLuaTxDeploy("user1", "random", 0, code1), + NewLuaTxDeploy("user1", "caller", 0, code2), + ) require.NoErrorf(t, err, "failed to deploy") err = bc.ConnectBlock(NewLuaTxCall("user1", "random", 0, `{"Name": "random", "Args":[]}`).Fail("1 or 2 arguments required")) @@ -2215,6 +2447,12 @@ func TestTypeRandom(t *testing.T) { err = bc.Query("random", `{"Name": "random", "Args":[3,1]}`, "system.random: the maximum value must be greater than the minimum value", "") require.NoErrorf(t, err, "failed to query") + tx = NewLuaTxCall("user1", "caller", 0, `{"Name": "check_if_equal", "Args":["`+nameToAddress("random")+`"]}`) + err = bc.ConnectBlock(tx) + require.NoErrorf(t, err, "failed to call tx") + receipt = bc.GetReceipt(tx.Hash()) + assert.Equalf(t, `false`, receipt.GetRet(), "random numbers are the same on the same transaction") + } } @@ -2418,9 +2656,9 @@ func TestFeatureGovernance(t *testing.T) { } func TestFeaturePcallRollback(t *testing.T) { - code := readLuaCode(t, "feature_pcallrollback_1.lua") - code2 := readLuaCode(t, "feature_pcallrollback_2.lua") - code3 := readLuaCode(t, "feature_pcallrollback_3.lua") + code1 := readLuaCode(t, "feature_pcall_rollback_1.lua") + code2 := readLuaCode(t, "feature_pcall_rollback_2.lua") + code3 := readLuaCode(t, "feature_pcall_rollback_3.lua") for version := min_version; version <= max_version; version++ { bc, err := LoadDummyChain(SetHardForkVersion(version)) @@ -2429,7 +2667,7 @@ func TestFeaturePcallRollback(t *testing.T) { err = bc.ConnectBlock( NewLuaTxAccount("user1", 1, types.Aergo), - NewLuaTxDeploy("user1", "counter", 10, code).Constructor("[0]"), + NewLuaTxDeploy("user1", "counter", 10, code1).Constructor("[0]"), NewLuaTxCall("user1", "counter", 15, `{"Name":"inc", "Args":[]}`), ) require.NoErrorf(t, err, "failed to deploy") @@ -2459,6 +2697,8 @@ func TestFeaturePcallRollback(t *testing.T) { receipt := bc.GetReceipt(tx.Hash()) require.Equalf(t, "\""+nameToAddress("user1")+"\"", receipt.GetRet(), "contract Call ret error") + // create new dummy chain + bc, err = LoadDummyChain(SetHardForkVersion(version)) require.NoErrorf(t, err, "failed to create dummy chain") defer bc.Release() @@ -2499,7 +2739,7 @@ func TestFeaturePcallRollback(t *testing.T) { } func TestFeaturePcallNested(t *testing.T) { - code := readLuaCode(t, "feature_pcallnested.lua") + code := readLuaCode(t, "feature_pcall_nested.lua") for version := min_version; version <= max_version; version++ { bc, err := LoadDummyChain(SetHardForkVersion(version)) @@ -2529,8 +2769,1463 @@ func TestFeaturePcallNested(t *testing.T) { } } +// test rollback of state variable and balance +func TestPcallStateRollback1(t *testing.T) { + code := readLuaCode(t, "feature_pcall_rollback_4.lua") + resolver := readLuaCode(t, "resolver.lua") + + for version := min_version; version <= max_version; version++ { + bc, err := LoadDummyChain(SetHardForkVersion(version)) + require.NoErrorf(t, err, "failed to create dummy chain") + defer bc.Release() + + // deploy and setup the name resolver + err = bc.ConnectBlock( + NewLuaTxAccount("user", 10, types.Aergo), + NewLuaTxDeploy("user", "resolver", 0, resolver), + NewLuaTxCall("user", "resolver", 0, fmt.Sprintf(`{"Name":"set","Args":["A","%s"]}`, nameToAddress("A"))), + NewLuaTxCall("user", "resolver", 0, fmt.Sprintf(`{"Name":"set","Args":["B","%s"]}`, nameToAddress("B"))), + NewLuaTxCall("user", "resolver", 0, fmt.Sprintf(`{"Name":"set","Args":["C","%s"]}`, nameToAddress("C"))), + ) + require.NoErrorf(t, err, "failed to deploy and setup resolver") + + // deploy the contracts + err = bc.ConnectBlock( + NewLuaTxDeploy("user", "A", 3, code).Constructor(fmt.Sprintf(`["%s","A"]`, nameToAddress("resolver"))), + NewLuaTxDeploy("user", "B", 0, code).Constructor(fmt.Sprintf(`["%s","B"]`, nameToAddress("resolver"))), + NewLuaTxDeploy("user", "C", 0, code).Constructor(fmt.Sprintf(`["%s","C"]`, nameToAddress("resolver"))), + ) + require.NoErrorf(t, err, "failed to deploy the contracts") + + // A -> A -> A (3 calls on the same contract) + + script := `[[ + ['set','x',111], + ['pcall','A'] + ],[ + ['set','x',222], + ['pcall','A'] + ],[ + ['set','x',333] + ]]` + testStateRollback(t, bc, script, + map[string]int{"A": 333}, nil) + + script = `[[ + ['set','x',111], + ['pcall','A'] + ],[ + ['set','x',222], + ['pcall','A'] + ],[ + ['set','x',333], + ['fail'] + ]]` + testStateRollback(t, bc, script, + map[string]int{"A": 222}, nil) + + script = `[[ + ['set','x',111], + ['pcall','A'] + ],[ + ['set','x',222], + ['pcall','A'], + ['fail'] + ],[ + ['set','x',333] + ]]` + testStateRollback(t, bc, script, + map[string]int{"A": 111}, nil) + + script = `[[ + ['set','x',111], + ['pcall','A'], + ['fail'] + ],[ + ['set','x',222], + ['pcall','A'] + ],[ + ['set','x',333] + ]]` + testStateRollback(t, bc, script, + map[string]int{"A": 0}, nil) + + // A -> B -> C (3 different contracts) + + script = `[[ + ['set','x',111], + ['pcall','B',2] + ],[ + ['set','x',222], + ['pcall','C',1] + ],[ + ['set','x',333] + ]]` + testStateRollback(t, bc, script, + map[string]int{"A": 111, "B": 222, "C": 333}, + map[string]int64{"A": 1, "B": 1, "C": 1}) + + script = `[[ + ['set','x',111], + ['pcall','B',2] + ],[ + ['set','x',222], + ['pcall','C',1] + ],[ + ['set','x',333], + ['fail'] + ]]` + testStateRollback(t, bc, script, + map[string]int{"A": 111, "B": 222, "C": 0}, + map[string]int64{"A": 1, "B": 2, "C": 0}) + + script = `[[ + ['set','x',111], + ['pcall','B',2] + ],[ + ['set','x',222], + ['pcall','C',1], + ['fail'] + ],[ + ['set','x',333] + ]]` + testStateRollback(t, bc, script, + map[string]int{"A": 111, "B": 0, "C": 0}, + map[string]int64{"A": 3, "B": 0, "C": 0}) + + script = `[[ + ['set','x',111], + ['pcall','B',2], + ['fail'] + ],[ + ['set','x',222], + ['pcall','C',1] + ],[ + ['set','x',333] + ]]` + testStateRollback(t, bc, script, + map[string]int{"A": 0, "B": 0, "C": 0}, + map[string]int64{"A": 3, "B": 0, "C": 0}) + + // A -> B -> A (call back to original contract) + + script = `[[ + ['set','x',111], + ['pcall','B',2] + ],[ + ['set','x',222], + ['pcall','A',1] + ],[ + ['set','x',333] + ]]` + testStateRollback(t, bc, script, + map[string]int{"A": 333, "B": 222}, + map[string]int64{"A": 2, "B": 1}) + + script = `[[ + ['set','x',111], + ['pcall','B',2] + ],[ + ['set','x',222], + ['pcall','A',1] + ],[ + ['set','x',333], + ['fail'] + ]]` + testStateRollback(t, bc, script, + map[string]int{"A": 111, "B": 222}, + map[string]int64{"A": 1, "B": 2}) + + script = `[[ + ['set','x',111], + ['pcall','B',2] + ],[ + ['set','x',222], + ['pcall','A',1], + ['fail'] + ],[ + ['set','x',333] + ]]` + testStateRollback(t, bc, script, + map[string]int{"A": 111, "B": 0}, + map[string]int64{"A": 3, "B": 0}) + + script = `[[ + ['set','x',111], + ['pcall','B',2], + ['fail'] + ],[ + ['set','x',222], + ['pcall','A',1] + ],[ + ['set','x',333] + ]]` + testStateRollback(t, bc, script, + map[string]int{"A": 0, "B": 0}, + map[string]int64{"A": 3, "B": 0}) + + // A -> B -> B + + script = `[[ + ['set','x',111], + ['pcall','B',3] + ],[ + ['set','x',222], + ['pcall','B'] + ],[ + ['set','x',333] + ]]` + testStateRollback(t, bc, script, + map[string]int{"A": 111, "B": 333}, + map[string]int64{"A": 0, "B": 3}) + + script = `[[ + ['set','x',111], + ['pcall','B',3] + ],[ + ['set','x',222], + ['pcall','B'] + ],[ + ['set','x',333], + ['fail'] + ]]` + testStateRollback(t, bc, script, + map[string]int{"A": 111, "B": 222}, + map[string]int64{"A": 0, "B": 3}) + + script = `[[ + ['set','x',111], + ['pcall','B',3] + ],[ + ['set','x',222], + ['pcall','B'], + ['fail'] + ],[ + ['set','x',333] + ]]` + testStateRollback(t, bc, script, + map[string]int{"A": 111, "B": 0}, + map[string]int64{"A": 3, "B": 0}) + + script = `[[ + ['set','x',111], + ['pcall','B',3], + ['fail'] + ],[ + ['set','x',222], + ['pcall','B'] + ],[ + ['set','x',333] + ]]` + testStateRollback(t, bc, script, + map[string]int{"A": 0, "B": 0}, + map[string]int64{"A": 3, "B": 0}) + + // A -> A -> B + + script = `[[ + ['set','x',111], + ['pcall','A'] + ],[ + ['set','x',222], + ['pcall','B',3] + ],[ + ['set','x',333] + ]]` + testStateRollback(t, bc, script, + map[string]int{"A": 222, "B": 333}, + map[string]int64{"A": 0, "B": 3}) + + script = `[[ + ['set','x',111], + ['pcall','A'] + ],[ + ['set','x',222], + ['pcall','B',3] + ],[ + ['set','x',333], + ['fail'] + ]]` + testStateRollback(t, bc, script, + map[string]int{"A": 222, "B": 0}, + map[string]int64{"A": 3, "B": 0}) + + script = `[[ + ['set','x',111], + ['pcall','A'] + ],[ + ['set','x',222], + ['pcall','B',3], + ['fail'] + ],[ + ['set','x',333] + ]]` + testStateRollback(t, bc, script, + map[string]int{"A": 111, "B": 0}, + map[string]int64{"A": 3, "B": 0}) + + script = `[[ + ['set','x',111], + ['pcall','A'], + ['fail'] + ],[ + ['set','x',222], + ['pcall','B',3] + ],[ + ['set','x',333] + ]]` + testStateRollback(t, bc, script, + map[string]int{"A": 0, "B": 0}, + map[string]int64{"A": 3, "B": 0}) + + // A -> B -> A -> B -> A (zigzag) + + script = `[[ + ['set','x',111], + ['pcall','B',1] + ],[ + ['set','x',222], + ['pcall','A',1] + ],[ + ['set','x',333], + ['pcall','B',1] + ],[ + ['set','x',444], + ['pcall','A',1] + ],[ + ['set','x',555] + ]]` + testStateRollback(t, bc, script, + map[string]int{"A": 555, "B": 444}, + map[string]int64{"A": 3, "B": 0}) + + script = `[[ + ['set','x',111], + ['pcall','B',1] + ],[ + ['set','x',222], + ['pcall','A',1] + ],[ + ['set','x',333], + ['pcall','B',1] + ],[ + ['set','x',444], + ['pcall','A',1] + ],[ + ['set','x',555], + ['fail'] + ]]` + testStateRollback(t, bc, script, + map[string]int{"A": 333, "B": 444}, + map[string]int64{"A": 2, "B": 1}) + + script = `[[ + ['set','x',111], + ['pcall','B',1] + ],[ + ['set','x',222], + ['pcall','A',1] + ],[ + ['set','x',333], + ['pcall','B',1] + ],[ + ['set','x',444], + ['pcall','A',1], + ['fail'] + ],[ + ['set','x',555] + ]]` + testStateRollback(t, bc, script, + map[string]int{"A": 333, "B": 222}, + map[string]int64{"A": 3, "B": 0}) + + script = `[[ + ['set','x',111], + ['pcall','B',1] + ],[ + ['set','x',222], + ['pcall','A',1] + ],[ + ['set','x',333], + ['pcall','B',1], + ['fail'] + ],[ + ['set','x',444], + ['pcall','A',1] + ],[ + ['set','x',555] + ]]` + testStateRollback(t, bc, script, + map[string]int{"A": 111, "B": 222}, + map[string]int64{"A": 2, "B": 1}) + + script = `[[ + ['set','x',111], + ['pcall','B',1] + ],[ + ['set','x',222], + ['pcall','A',1], + ['fail'] + ],[ + ['set','x',333], + ['pcall','B',1] + ],[ + ['set','x',444], + ['pcall','A',1] + ],[ + ['set','x',555] + ]]` + testStateRollback(t, bc, script, + map[string]int{"A": 111, "B": 0}, + map[string]int64{"A": 3, "B": 0}) + + script = `[[ + ['set','x',111], + ['pcall','B',1], + ['fail'] + ],[ + ['set','x',222], + ['pcall','A',1] + ],[ + ['set','x',333], + ['pcall','B',1] + ],[ + ['set','x',444], + ['pcall','A',1] + ],[ + ['set','x',555] + ]]` + testStateRollback(t, bc, script, + map[string]int{"A": 0, "B": 0}, + map[string]int64{"A": 3, "B": 0}) + + } +} + +// test rollback of state variable and balance - send separate from call +func TestPcallStateRollback2(t *testing.T) { + t.Skip("disabled until bug with test is fixed") + code := readLuaCode(t, "feature_pcall_rollback_4.lua") + resolver := readLuaCode(t, "resolver.lua") + + for version := min_version; version <= max_version; version++ { + bc, err := LoadDummyChain(SetHardForkVersion(version)) + require.NoErrorf(t, err, "failed to create dummy chain") + defer bc.Release() + + // deploy and setup the name resolver + err = bc.ConnectBlock( + NewLuaTxAccount("user", 10, types.Aergo), + NewLuaTxDeploy("user", "resolver", 0, resolver), + NewLuaTxCall("user", "resolver", 0, fmt.Sprintf(`{"Name":"set","Args":["A","%s"]}`, nameToAddress("A"))), + NewLuaTxCall("user", "resolver", 0, fmt.Sprintf(`{"Name":"set","Args":["B","%s"]}`, nameToAddress("B"))), + NewLuaTxCall("user", "resolver", 0, fmt.Sprintf(`{"Name":"set","Args":["C","%s"]}`, nameToAddress("C"))), + NewLuaTxCall("user", "resolver", 0, fmt.Sprintf(`{"Name":"set","Args":["D","%s"]}`, nameToAddress("D"))), + NewLuaTxCall("user", "resolver", 0, fmt.Sprintf(`{"Name":"set","Args":["E","%s"]}`, nameToAddress("E"))), + ) + require.NoErrorf(t, err, "failed to deploy and setup resolver") + + // deploy the contracts + err = bc.ConnectBlock( + NewLuaTxDeploy("user", "A", 3, code).Constructor(fmt.Sprintf(`["%s","A"]`, nameToAddress("resolver"))), + NewLuaTxDeploy("user", "B", 0, code).Constructor(fmt.Sprintf(`["%s","B"]`, nameToAddress("resolver"))), + NewLuaTxDeploy("user", "C", 0, code).Constructor(fmt.Sprintf(`["%s","C"]`, nameToAddress("resolver"))), + ) + require.NoErrorf(t, err, "failed to deploy the contracts") + + // A -> A -> A (3 calls on the same contract) + + script := `[[ + ['set','x',111], + ['send','B',1], + ['pcall','A'] + ],[ + ['set','x',222], + ['send','C',1], + ['pcall','A'] + ],[ + ['set','x',333], + ['send','E',1] + ]]` + testStateRollback(t, bc, script, + map[string]int{"A": 333}, + map[string]int64{"A": 0, "B": 1, "C": 1, "E": 1}) + + script = `[[ + ['set','x',111], + ['send','B',1], + ['pcall','A'] + ],[ + ['set','x',222], + ['send','C',1], + ['pcall','A'] + ],[ + ['set','x',333], + ['send','D',1], + ['fail'] + ]]` + testStateRollback(t, bc, script, + map[string]int{"A": 222}, + map[string]int64{"A": 1, "B": 1, "C": 1, "D": 0}) + + script = `[[ + ['set','x',111], + ['send','B',1], + ['pcall','A'] + ],[ + ['set','x',222], + ['send','C',1], + ['pcall','A'], + ['fail'] + ],[ + ['set','x',333], + ['send','D',1] + ]]` + testStateRollback(t, bc, script, + map[string]int{"A": 111}, + map[string]int64{"A": 2, "B": 1, "C": 0, "D": 0}) + + script = `[[ + ['set','x',111], + ['send','B',1], + ['pcall','A'], + ['fail'] + ],[ + ['set','x',222], + ['send','C',1], + ['pcall','A'] + ],[ + ['set','x',333], + ['send','D',1] + ]]` + testStateRollback(t, bc, script, + map[string]int{"A": 0}, + map[string]int64{"A": 3, "B": 0, "C": 0, "D": 0}) + + // A -> B -> C (3 different contracts) + + script = `[[ + ['set','x',111], + ['send','B',3], + ['pcall','B'] + ],[ + ['set','x',222], + ['send','C',2], + ['pcall','C'] + ],[ + ['set','x',333], + ['send','A',1] + ]]` + testStateRollback(t, bc, script, + map[string]int{"A": 111, "B": 222, "C": 333}, + map[string]int64{"A": 1, "B": 1, "C": 1}) + + script = `[[ + ['set','x',111], + ['send','B',3], + ['pcall','B'] + ],[ + ['set','x',222], + ['send','C',2], + ['pcall','C'] + ],[ + ['set','x',333], + ['send','A',1], + ['fail'] + ]]` + testStateRollback(t, bc, script, + map[string]int{"A": 111, "B": 222, "C": 0}, + map[string]int64{"A": 0, "B": 1, "C": 2}) + + script = `[[ + ['set','x',111], + ['send','B',3], + ['pcall','B'] + ],[ + ['set','x',222], + ['send','C',2], + ['pcall','C'], + ['fail'] + ],[ + ['set','x',333], + ['send','A',1] + ]]` + testStateRollback(t, bc, script, + map[string]int{"A": 111, "B": 0, "C": 0}, + map[string]int64{"A": 0, "B": 3, "C": 0}) + + script = `[[ + ['set','x',111], + ['send','B',3], + ['pcall','B'], + ['fail'] + ],[ + ['set','x',222], + ['send','C',2], + ['pcall','C'] + ],[ + ['set','x',333], + ['send','A',1] + ]]` + testStateRollback(t, bc, script, + map[string]int{"A": 0, "B": 0, "C": 0}, + map[string]int64{"A": 3, "B": 0, "C": 0}) + + // A -> B -> A (call back to original contract) + + script = `[[ + ['set','x',111], + ['send','B',3], + ['pcall','B'] + ],[ + ['set','x',222], + ['send','A',2], + ['pcall','A'] + ],[ + ['set','x',333], + ['send','B',1] + ]]` + testStateRollback(t, bc, script, + map[string]int{"A": 333, "B": 222}, + map[string]int64{"A": 1, "B": 2}) + + script = `[[ + ['set','x',111], + ['send','B',3], + ['pcall','B'] + ],[ + ['set','x',222], + ['send','A',2], + ['pcall','A'] + ],[ + ['set','x',333], + ['send','B',1], + ['fail'] + ]]` + testStateRollback(t, bc, script, + map[string]int{"A": 111, "B": 222}, + map[string]int64{"A": 2, "B": 1}) + + script = `[[ + ['set','x',111], + ['send','B',3], + ['pcall','B'] + ],[ + ['set','x',222], + ['send','A',2], + ['pcall','A'], + ['fail'] + ],[ + ['set','x',333], + ['send','B',1] + ]]` + testStateRollback(t, bc, script, + map[string]int{"A": 111, "B": 0}, + map[string]int64{"A": 0, "B": 3}) + + script = `[[ + ['set','x',111], + ['send','B',3], + ['pcall','B'], + ['fail'] + ],[ + ['set','x',222], + ['send','A',2], + ['pcall','A'] + ],[ + ['set','x',333], + ['send','B',1] + ]]` + testStateRollback(t, bc, script, + map[string]int{"A": 0, "B": 0}, + map[string]int64{"A": 3, "B": 0}) + + // A -> B -> B + + script = `[[ + ['set','x',111], + ['send','B',3], + ['pcall','B'] + ],[ + ['set','x',222], + ['send','C',1], + ['pcall','B'] + ],[ + ['set','x',333], + ['send','A',1] + ]]` + testStateRollback(t, bc, script, + map[string]int{"A": 111, "B": 333}, + map[string]int64{"A": 1, "B": 1, "C": 1}) + + script = `[[ + ['set','x',111], + ['send','B',3], + ['pcall','B'] + ],[ + ['set','x',222], + ['send','C',1], + ['pcall','B'] + ],[ + ['set','x',333], + ['send','A',1], + ['fail'] + ]]` + testStateRollback(t, bc, script, + map[string]int{"A": 111, "B": 222}, + map[string]int64{"A": 0, "B": 2, "C": 1}) + + script = `[[ + ['set','x',111], + ['send','B',3], + ['pcall','B'] + ],[ + ['set','x',222], + ['send','C',1], + ['pcall','B'], + ['fail'] + ],[ + ['set','x',333], + ['send','A',1] + ]]` + testStateRollback(t, bc, script, + map[string]int{"A": 111, "B": 0}, + map[string]int64{"A": 0, "B": 3, "C": 0}) + + script = `[[ + ['set','x',111], + ['send','B',3], + ['pcall','B'], + ['fail'] + ],[ + ['set','x',222], + ['send','C',1], + ['pcall','B'] + ],[ + ['set','x',333], + ['send','A',1] + ]]` + testStateRollback(t, bc, script, + map[string]int{"A": 0, "B": 0}, + map[string]int64{"A": 3, "B": 0, "C": 0}) + + // A -> A -> B + + script = `[[ + ['set','x',111], + ['send','B',2], + ['pcall','A'] + ],[ + ['set','x',222], + ['send','C',1], + ['pcall','B'] + ],[ + ['set','x',333], + ['send','A',1] + ]]` + testStateRollback(t, bc, script, + map[string]int{"A": 222, "B": 333}, + map[string]int64{"A": 1, "B": 1, "C": 1}) + + script = `[[ + ['set','x',111], + ['send','B',2], + ['pcall','A'] + ],[ + ['set','x',222], + ['send','C',1], + ['pcall','B'] + ],[ + ['set','x',333], + ['send','A',1], + ['fail'] + ]]` + testStateRollback(t, bc, script, + map[string]int{"A": 222, "B": 0}, + map[string]int64{"A": 0, "B": 2, "C": 1}) + + script = `[[ + ['set','x',111], + ['send','B',2], + ['pcall','A'] + ],[ + ['set','x',222], + ['send','C',1], + ['pcall','B'], + ['fail'] + ],[ + ['set','x',333], + ['send','A',1] + ]]` + testStateRollback(t, bc, script, + map[string]int{"A": 111, "B": 0}, + map[string]int64{"A": 1, "B": 2, "C": 0}) + + script = `[[ + ['set','x',111], + ['send','B',2], + ['pcall','A'], + ['fail'] + ],[ + ['set','x',222], + ['send','C',1], + ['pcall','B'] + ],[ + ['set','x',333], + ['send','A',1] + ]]` + testStateRollback(t, bc, script, + map[string]int{"A": 0, "B": 0}, + map[string]int64{"A": 3, "B": 0, "C": 0}) + + // A -> B -> A -> B -> A (zigzag) + + script = `[[ + ['set','x',111], + ['send','B',1], + ['pcall','B'] + ],[ + ['set','x',222], + ['send','A',1], + ['pcall','A'] + ],[ + ['set','x',333], + ['send','B',1], + ['pcall','B'] + ],[ + ['set','x',444], + ['send','A',1], + ['pcall','A'] + ],[ + ['set','x',555], + ['send','B',1] + ]]` + testStateRollback(t, bc, script, + map[string]int{"A": 555, "B": 444}, + map[string]int64{"A": 2, "B": 1}) + + script = `[[ + ['set','x',111], + ['send','B',1], + ['pcall','B'] + ],[ + ['set','x',222], + ['send','A',1], + ['pcall','A'] + ],[ + ['set','x',333], + ['send','B',1], + ['pcall','B'] + ],[ + ['set','x',444], + ['send','A',1], + ['pcall','A'] + ],[ + ['set','x',555], + ['send','B',1], + ['fail'] + ]]` + testStateRollback(t, bc, script, + map[string]int{"A": 333, "B": 444}, + map[string]int64{"A": 3, "B": 0}) + + script = `[[ + ['set','x',111], + ['send','B',1], + ['pcall','B'] + ],[ + ['set','x',222], + ['send','A',1], + ['pcall','A'] + ],[ + ['set','x',333], + ['send','B',1], + ['pcall','B'] + ],[ + ['set','x',444], + ['send','A',1], + ['pcall','A'], + ['fail'] + ],[ + ['set','x',555], + ['send','B',1] + ]]` + testStateRollback(t, bc, script, + map[string]int{"A": 333, "B": 222}, + map[string]int64{"A": 2, "B": 1}) + + script = `[[ + ['set','x',111], + ['send','B',1], + ['pcall','B'] + ],[ + ['set','x',222], + ['send','A',1], + ['pcall','A'] + ],[ + ['set','x',333], + ['send','B',1], + ['pcall','B'], + ['fail'] + ],[ + ['set','x',444], + ['send','A',1], + ['pcall','A'] + ],[ + ['set','x',555], + ['send','B',1] + ]]` + testStateRollback(t, bc, script, + map[string]int{"A": 111, "B": 222}, + map[string]int64{"A": 3, "B": 0}) + + script = `[[ + ['set','x',111], + ['send','B',1], + ['pcall','B'] + ],[ + ['set','x',222], + ['send','A',1], + ['pcall','A'], + ['fail'] + ],[ + ['set','x',333], + ['send','B',1], + ['pcall','B'] + ],[ + ['set','x',444], + ['send','A',1], + ['pcall','A'] + ],[ + ['set','x',555], + ['send','B',1] + ]]` + testStateRollback(t, bc, script, + map[string]int{"A": 111, "B": 0}, + map[string]int64{"A": 2, "B": 1}) + + script = `[[ + ['set','x',111], + ['send','B',1], + ['pcall','B'], + ['fail'] + ],[ + ['set','x',222], + ['send','A',1], + ['pcall','A'] + ],[ + ['set','x',333], + ['send','B',1], + ['pcall','B'] + ],[ + ['set','x',444], + ['send','A',1], + ['pcall','A'] + ],[ + ['set','x',555], + ['send','B',1] + ]]` + testStateRollback(t, bc, script, + map[string]int{"A": 0, "B": 0}, + map[string]int64{"A": 3, "B": 0}) + + } +} + +// test rollback of db +func TestPcallStateRollback3(t *testing.T) { + t.Skip("disabled until bug with test is fixed") + resolver := readLuaCode(t, "resolver.lua") + code := readLuaCode(t, "feature_pcall_rollback_4.lua") + + for version := min_version; version <= max_version; version++ { + bc, err := LoadDummyChain(SetHardForkVersion(version)) + require.NoErrorf(t, err, "failed to create dummy chain") + defer bc.Release() + + err = bc.ConnectBlock( + NewLuaTxAccount("user", 1, types.Aergo), + NewLuaTxDeploy("user", "resolver", 0, resolver), + NewLuaTxDeploy("user", "A", 0, code).Constructor(fmt.Sprintf(`["%s","A"]`, nameToAddress("resolver"))), + NewLuaTxDeploy("user", "B", 0, code).Constructor(fmt.Sprintf(`["%s","B"]`, nameToAddress("resolver"))), + NewLuaTxDeploy("user", "C", 0, code).Constructor(fmt.Sprintf(`["%s","C"]`, nameToAddress("resolver"))), + ) + require.NoErrorf(t, err, "failed to deploy") + + err = bc.ConnectBlock( + NewLuaTxCall("user", "resolver", 0, fmt.Sprintf(`{"Name":"set","Args":["A","%s"]}`, nameToAddress("A"))), + NewLuaTxCall("user", "resolver", 0, fmt.Sprintf(`{"Name":"set","Args":["B","%s"]}`, nameToAddress("B"))), + NewLuaTxCall("user", "resolver", 0, fmt.Sprintf(`{"Name":"set","Args":["C","%s"]}`, nameToAddress("C"))), + ) + require.NoErrorf(t, err, "failed to call resolver contract") + + // A -> A -> A (3 calls on the same contract) + + script := `[[ + ['db.set',111], + ['pcall','A'] + ],[ + ['db.set',222], + ['pcall','A'] + ],[ + ['db.set',333] + ]]` + testDbStateRollback(t, bc, script, + map[string]int{"A": 333}) + + script = `[[ + ['db.set',111], + ['pcall','A'] + ],[ + ['db.set',222], + ['pcall','A'] + ],[ + ['db.set',333], + ['fail'] + ]]` + testDbStateRollback(t, bc, script, + map[string]int{"A": 222}) + + script = `[[ + ['db.set',111], + ['pcall','A'] + ],[ + ['db.set',222], + ['pcall','A'], + ['fail'] + ],[ + ['db.set',333] + ]]` + testDbStateRollback(t, bc, script, + map[string]int{"A": 111}) + + script = `[[ + ['db.set',111], + ['pcall','A'], + ['fail'] + ],[ + ['db.set',222], + ['pcall','A'] + ],[ + ['db.set',333] + ]]` + testDbStateRollback(t, bc, script, + map[string]int{"A": 0}) + + // A -> B -> C (3 different contracts) + + script = `[[ + ['db.set',111], + ['pcall','B'] + ],[ + ['db.set',222], + ['pcall','C'] + ],[ + ['db.set',333] + ]]` + testDbStateRollback(t, bc, script, + map[string]int{"A": 111, "B": 222, "C": 333}) + + script = `[[ + ['db.set',111], + ['pcall','B'] + ],[ + ['db.set',222], + ['pcall','C'] + ],[ + ['db.set',333], + ['fail'] + ]]` + testDbStateRollback(t, bc, script, + map[string]int{"A": 111, "B": 222, "C": 0}) + + script = `[[ + ['db.set',111], + ['pcall','B'] + ],[ + ['db.set',222], + ['pcall','C'], + ['fail'] + ],[ + ['db.set',333] + ]]` + testDbStateRollback(t, bc, script, + map[string]int{"A": 111, "B": 0, "C": 0}) + + script = `[[ + ['db.set',111], + ['pcall','B'], + ['fail'] + ],[ + ['db.set',222], + ['pcall','C'] + ],[ + ['db.set',333] + ]]` + testDbStateRollback(t, bc, script, + map[string]int{"A": 0, "B": 0, "C": 0}) + + // A -> B -> A (call back to original contract) + + script = `[[ + ['db.set',111], + ['pcall','B'] + ],[ + ['db.set',222], + ['pcall','A'] + ],[ + ['db.set',333] + ]]` + testDbStateRollback(t, bc, script, + map[string]int{"A": 333, "B": 222}) + + script = `[[ + ['db.set',111], + ['pcall','B'] + ],[ + ['db.set',222], + ['pcall','A'] + ],[ + ['db.set',333], + ['fail'] + ]]` + testDbStateRollback(t, bc, script, + map[string]int{"A": 111, "B": 222}) + + script = `[[ + ['db.set',111], + ['pcall','B'] + ],[ + ['db.set',222], + ['pcall','A'], + ['fail'] + ],[ + ['db.set',333] + ]]` + testDbStateRollback(t, bc, script, + map[string]int{"A": 111, "B": 0}) + + script = `[[ + ['db.set',111], + ['pcall','B'], + ['fail'] + ],[ + ['db.set',222], + ['pcall','A'] + ],[ + ['db.set',333] + ]]` + testDbStateRollback(t, bc, script, + map[string]int{"A": 0, "B": 0}) + + // A -> B -> B + + script = `[[ + ['db.set',111], + ['pcall','B'] + ],[ + ['db.set',222], + ['pcall','B'] + ],[ + ['db.set',333] + ]]` + testDbStateRollback(t, bc, script, + map[string]int{"A": 111, "B": 333}) + + script = `[[ + ['db.set',111], + ['pcall','B'] + ],[ + ['db.set',222], + ['pcall','B'] + ],[ + ['db.set',333], + ['fail'] + ]]` + testDbStateRollback(t, bc, script, + map[string]int{"A": 111, "B": 222}) + + script = `[[ + ['db.set',111], + ['pcall','B'] + ],[ + ['db.set',222], + ['pcall','B'], + ['fail'] + ],[ + ['db.set',333] + ]]` + testDbStateRollback(t, bc, script, + map[string]int{"A": 111, "B": 0}) + + script = `[[ + ['db.set',111], + ['pcall','B'], + ['fail'] + ],[ + ['db.set',222], + ['pcall','B'] + ],[ + ['db.set',333] + ]]` + testDbStateRollback(t, bc, script, + map[string]int{"A": 0, "B": 0}) + + // A -> A -> B + + script = `[[ + ['db.set',111], + ['pcall','A'] + ],[ + ['db.set',222], + ['pcall','B'] + ],[ + ['db.set',333] + ]]` + testDbStateRollback(t, bc, script, + map[string]int{"A": 222, "B": 333}) + + script = `[[ + ['db.set',111], + ['pcall','A'] + ],[ + ['db.set',222], + ['pcall','B'] + ],[ + ['db.set',333], + ['fail'] + ]]` + testDbStateRollback(t, bc, script, + map[string]int{"A": 222, "B": 0}) + + script = `[[ + ['db.set',111], + ['pcall','A'] + ],[ + ['db.set',222], + ['pcall','B'], + ['fail'] + ],[ + ['db.set',333] + ]]` + testDbStateRollback(t, bc, script, + map[string]int{"A": 111, "B": 0}) + + script = `[[ + ['db.set',111], + ['pcall','A'], + ['fail'] + ],[ + ['db.set',222], + ['pcall','B'] + ],[ + ['db.set',333] + ]]` + testDbStateRollback(t, bc, script, + map[string]int{"A": 0, "B": 0}) + + // A -> B -> A -> B -> A (zigzag) + + script = `[[ + ['db.set',111], + ['pcall','B'] + ],[ + ['db.set',222], + ['pcall','A'] + ],[ + ['db.set',333], + ['pcall','B'] + ],[ + ['db.set',444], + ['pcall','A'] + ],[ + ['db.set',555] + ]]` + testDbStateRollback(t, bc, script, + map[string]int{"A": 555, "B": 444}) + + script = `[[ + ['db.set',111], + ['pcall','B'] + ],[ + ['db.set',222], + ['pcall','A'] + ],[ + ['db.set',333], + ['pcall','B'] + ],[ + ['db.set',444], + ['pcall','A'] + ],[ + ['db.set',555], + ['fail'] + ]]` + testDbStateRollback(t, bc, script, + map[string]int{"A": 333, "B": 444}) + + script = `[[ + ['db.set',111], + ['pcall','B'] + ],[ + ['db.set',222], + ['pcall','A'] + ],[ + ['db.set',333], + ['pcall','B'] + ],[ + ['db.set',444], + ['pcall','A'], + ['fail'] + ],[ + ['db.set',555] + ]]` + testDbStateRollback(t, bc, script, + map[string]int{"A": 333, "B": 222}) + + script = `[[ + ['db.set',111], + ['pcall','B'] + ],[ + ['db.set',222], + ['pcall','A'] + ],[ + ['db.set',333], + ['pcall','B'], + ['fail'] + ],[ + ['db.set',444], + ['pcall','A'] + ],[ + ['db.set',555] + ]]` + testDbStateRollback(t, bc, script, + map[string]int{"A": 111, "B": 222}) + + script = `[[ + ['db.set',111], + ['pcall','B'] + ],[ + ['db.set',222], + ['pcall','A'], + ['fail'] + ],[ + ['db.set',333], + ['pcall','B'] + ],[ + ['db.set',444], + ['pcall','A'] + ],[ + ['db.set',555] + ]]` + testDbStateRollback(t, bc, script, + map[string]int{"A": 111, "B": 0}) + + script = `[[ + ['db.set',111], + ['pcall','B'], + ['fail'] + ],[ + ['db.set',222], + ['pcall','A'] + ],[ + ['db.set',333], + ['pcall','B'] + ],[ + ['db.set',444], + ['pcall','A'] + ],[ + ['db.set',555] + ]]` + testDbStateRollback(t, bc, script, + map[string]int{"A": 0, "B": 0}) + + } +} + +func testStateRollback(t *testing.T, bc *DummyChain, script string, expected_state map[string]int, expected_amount map[string]int64) { + t.Helper() + + err := bc.ConnectBlock( + NewLuaTxCall("user", "A", 0, `{"Name":"set","Args":["x",0]}`), + NewLuaTxCall("user", "B", 0, `{"Name":"set","Args":["x",0]}`), + NewLuaTxCall("user", "C", 0, `{"Name":"set","Args":["x",0]}`), + NewLuaTxCall("user", "B", 0, `{"Name":"send_back","Args":["A"]}`), + NewLuaTxCall("user", "C", 0, `{"Name":"send_back","Args":["A"]}`), + ) + require.NoErrorf(t, err, "failed to reset") + + account, _ := bc.GetAccountState("A") + if account.GetBalanceBigInt().Int64() != 3 { + amount := uint64(3 - account.GetBalanceBigInt().Int64()) + err = bc.ConnectBlock( + NewLuaTxSendBig("user", "A", types.NewAmount(amount, types.Aer)), + ) + require.NoErrorf(t, err, "failed to send") + } + + names := make(map[string]int64) + names["A"] = 3 + names["B"] = 0 + names["C"] = 0 + for name, amount := range names { + account, _ := bc.GetAccountState(name) + assert.Equal(t, amount, account.GetBalanceBigInt().Int64(), "balance of "+name+" is not reset") + err = bc.Query(name, `{"Name":"get", "Args":["x"]}`, "", "0") + require.NoErrorf(t, err, "failed to query on reset") + } + + script = strings.ReplaceAll(script, "'", "\"") + tx := NewLuaTxCall("user", "A", 0, fmt.Sprintf(`{"Name":"test", "Args":[%s]}`, script)) + err = bc.ConnectBlock(tx) + //require.NoErrorf(t, err, "failed to call tx") + //receipt := bc.GetReceipt(tx.Hash()) + //assert.Equal(t, ``, receipt.GetRet(), "receipt ret error") + //fmt.Printf("events: %v\n", receipt.GetEvents()) + + for contract, value := range expected_state { + err = bc.Query(contract, `{"Name":"get", "Args":["x"]}`, "", fmt.Sprintf("%d", value)) + require.NoErrorf(t, err, "query failed") + } + + for name, amount := range expected_amount { + account, err := bc.GetAccountState(name) + require.NoErrorf(t, err, "failed to get account state") + assert.Equal(t, amount, account.GetBalanceBigInt().Int64(), "balance is different") + } +} + +func testDbStateRollback(t *testing.T, bc *DummyChain, script string, expected map[string]int) { + t.Helper() + + err := bc.ConnectBlock( + NewLuaTxCall("user", "A", 0, `{"Name":"db_reset"}`), + NewLuaTxCall("user", "B", 0, `{"Name":"db_reset"}`), + NewLuaTxCall("user", "C", 0, `{"Name":"db_reset"}`), + ) + require.NoErrorf(t, err, "failed to reset") + + names := []string{"A", "B", "C"} + for _, name := range names { + err = bc.Query(name, `{"Name":"db_get"}`, "", "0") + require.NoErrorf(t, err, "failed to query on reset") + } + + script = strings.ReplaceAll(script, "'", "\"") + tx := NewLuaTxCall("user", "A", 0, fmt.Sprintf(`{"Name":"test", "Args":[%s]}`, script)) + err = bc.ConnectBlock(tx) + //require.NoErrorf(t, err, "failed to call tx") + //receipt := bc.GetReceipt(tx.Hash()) + //assert.Equal(t, ``, receipt.GetRet(), "receipt ret error") + //fmt.Printf("events: %v\n", receipt.GetEvents()) + + for contract, value := range expected { + err = bc.Query(contract, `{"Name":"db_get"}`, "", fmt.Sprintf("%d", value)) + require.NoErrorf(t, err, "query failed") + } +} + func TestFeatureLuaCryptoVerifyProof(t *testing.T) { - code := readLuaCode(t, "feature_luacryptoverifyproof.lua") + code := readLuaCode(t, "feature_crypto_verify_proof.lua") for version := min_version; version <= max_version; version++ { bc, err := LoadDummyChain(SetHardForkVersion(version)) @@ -2657,6 +4352,48 @@ func TestFeatureFeeDelegationLoop(t *testing.T) { } */ +// Make sure that changes made on one contract Lua VM do not affect other called contracts +func TestContractIsolation(t *testing.T) { + code := readLuaCode(t, "feature_isolation.lua") + + for version := min_version; version <= max_version; version++ { + bc, err := LoadDummyChain(SetHardForkVersion(version)) + require.NoErrorf(t, err, "failed to create dummy chain") + defer bc.Release() + + err = bc.ConnectBlock( + NewLuaTxAccount("user1", 1, types.Aergo), + NewLuaTxDeploy("user1", "A", 0, code), + NewLuaTxDeploy("user1", "B", 0, code), + ) + require.NoErrorf(t, err, "failed to connect new block") + + // forward order + tx := NewLuaTxCall("user1", "A", 0, fmt.Sprintf(`{"Name":"test_vm_isolation_forward", "Args":["%s"]}`, nameToAddress("B"))) + err = bc.ConnectBlock(tx) + require.NoErrorf(t, err, "failed to connect new block") + receipt := bc.GetReceipt(tx.Hash()) + require.Equalf(t, ``, receipt.GetRet(), "contract call ret error") + + // reverse order using A -> A + tx = NewLuaTxCall("user1", "A", 0, fmt.Sprintf(`{"Name":"test_vm_isolation_reverse", "Args":["%s"]}`, nameToAddress("A"))) + err = bc.ConnectBlock(tx) + require.NoErrorf(t, err, "failed to connect new block") + receipt = bc.GetReceipt(tx.Hash()) + require.Equalf(t, ``, receipt.GetRet(), "contract call ret error") + + // reverse order using A -> B + tx = NewLuaTxCall("user1", "A", 0, fmt.Sprintf(`{"Name":"test_vm_isolation_reverse", "Args":["%s"]}`, nameToAddress("B"))) + err = bc.ConnectBlock(tx) + require.NoErrorf(t, err, "failed to connect new block") + receipt = bc.GetReceipt(tx.Hash()) + require.Equalf(t, ``, receipt.GetRet(), "contract call ret error") + + } +} + +// ---------------------------------------------------------------------------- + const ( DEF_TEST_CONTRACT = "testcontract" DEF_TEST_ACCOUNT = "testaccount" @@ -2670,8 +4407,8 @@ func readLuaCode(t *testing.T, file string) (luaCode string) { return "" } raw, err := os.ReadFile(filepath.Join(filepath.Dir(filename), "test_files", file)) - require.NoErrorf(t, err, "failed to read "+filename) - require.NotEmpty(t, raw, "failed to read "+filename) + require.NoErrorf(t, err, "failed to read "+file) + require.NotEmpty(t, raw, "failed to read "+file) return string(raw) } diff --git a/fee/fee.go b/fee/fee.go new file mode 100644 index 000000000..8652a4c22 --- /dev/null +++ b/fee/fee.go @@ -0,0 +1,100 @@ +package fee + +import ( + "fmt" + "math/big" +) + +const ( + baseTxFee = "2000000000000000" // 0.002 AERGO + payloadMaxSize = 200 * 1024 + StateDbMaxUpdateSize = payloadMaxSize + freeByteSize = 200 +) + +var ( + baseTxAergo *big.Int + zeroFee bool + stateDbMaxFee *big.Int + aerPerByte *big.Int +) + +func init() { + baseTxAergo, _ = new(big.Int).SetString(baseTxFee, 10) + zeroFee = false + aerPerByte = big.NewInt(5000000000000) // 5,000 GAER, feePerBytes * PayloadMaxBytes = 1 AERGO + stateDbMaxFee = new(big.Int).Mul(aerPerByte, big.NewInt(StateDbMaxUpdateSize-freeByteSize)) +} + +//---------------------------------------------------------------// +// zerofee + +func EnableZeroFee() { + zeroFee = true +} + +func DisableZeroFee() { + zeroFee = false +} + +func IsZeroFee() bool { + return zeroFee +} + +func NewZeroFee() *big.Int { + return big.NewInt(0) +} + +//---------------------------------------------------------------// +// calc fee + +// fee = gas price * gas +func CalcFee(gasPrice *big.Int, gas uint64) *big.Int { + return new(big.Int).Mul(gasPrice, new(big.Int).SetUint64(gas)) +} + +// compute the base fee for a transaction +func TxBaseFee(version int32, gasPrice *big.Int, payloadSize int) *big.Int { + if version < 2 { + return PayloadFee(payloadSize) + } + + // after v2 + txGas := TxGas(payloadSize) + return CalcFee(gasPrice, txGas) +} + +// compute the execute fee for a transaction +func TxExecuteFee(version int32, gasPrice *big.Int, usedGas uint64, dbUpdateTotalSize int64) *big.Int { + if IsZeroFee() { + return NewZeroFee() + } + + if version < 2 { + return StateDataFee(dbUpdateTotalSize) + } + + // after v2 + return CalcFee(gasPrice, usedGas) +} + +// estimate the max fee for a transaction +func TxMaxFee(version int32, lenPayload int, gasLimit uint64, balance, gasPrice *big.Int) (*big.Int, error) { + if IsZeroFee() { + return NewZeroFee(), nil + } + + if version < 2 { + return MaxPayloadFee(lenPayload), nil + } + + // after v2 + minGasLimit := TxGas(lenPayload) + if gasLimit == 0 { + gasLimit = MaxGasLimit(balance, gasPrice) + } + if minGasLimit > gasLimit { + return nil, fmt.Errorf("the minimum required amount of gas: %d", minGasLimit) + } + return CalcFee(gasPrice, gasLimit), nil +} diff --git a/fee/fee_test.go b/fee/fee_test.go new file mode 100644 index 000000000..f206271a5 --- /dev/null +++ b/fee/fee_test.go @@ -0,0 +1,122 @@ +package fee + +import ( + "math" + "math/big" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func TestTxBaseFee(t *testing.T) { + DisableZeroFee() + defer EnableZeroFee() + + for _, test := range []struct { + forkVersion int32 + gasPrice *big.Int + payloadSize int + expectFee *big.Int + }{ + // v1 + {1, Gaer(1), 0, Gaer(2000000)}, // gas price not affect in v1 + {1, Gaer(5), 200, Gaer(2000000)}, // max freeByteSize + {1, Gaer(5), 201, Gaer(2005000)}, // 2000000+5000 + {1, Gaer(5), 2047800, Gaer(1026000000)}, // 2000000+5000*2048000 ( 2047800 + freeByteSize ) + {1, Gaer(5), 2048000, Gaer(1026000000)}, // exceed payload max size + {1, Gaer(5), 20480000, Gaer(1026000000)}, + + // v2 - 1 + {2, Gaer(1), 0, Gaer(100000)}, + {2, Gaer(1), 200, Gaer(100000)}, // max freeByteSize + {2, Gaer(1), 201, Gaer(100005)}, // 100000+5 + {2, Gaer(1), 2047800, Gaer(1124000)}, // 100000+5*204800 ( 2047800 + freeByteSize ) + {2, Gaer(1), 2048000, Gaer(1124000)}, // exceed payload max size + {2, Gaer(1), 20480000, Gaer(1124000)}, + + // v2 - 5 + {2, Gaer(5), 0, Gaer(500000)}, + {2, Gaer(5), 200, Gaer(500000)}, // max freeByteSize + {2, Gaer(5), 201, Gaer(500025)}, + {2, Gaer(5), 700, Gaer(512500)}, + {2, Gaer(5), 2047800, Gaer(5620000)}, + {2, Gaer(5), 2048000, Gaer(5620000)}, // exceed payload max size + + // v3 is same as v2 + {3, Gaer(5), 100, Gaer(500000)}, + } { + resultFee := TxBaseFee(test.forkVersion, test.gasPrice, test.payloadSize) + assert.EqualValues(t, test.expectFee, resultFee, "TxBaseFee(forkVersion:%d, payloadSize:%d, gasPrice:%s)", test.forkVersion, test.payloadSize, test.gasPrice) + } +} + +func TestTxExecuteFee(t *testing.T) { + DisableZeroFee() + defer EnableZeroFee() + + for _, test := range []struct { + forkVersion int32 + dbUpdateTotalSize int64 + gasPrice *big.Int + usedGas uint64 + expectFee *big.Int + }{ + // v1 - fee by dbUpdateTotalSize + {1, 0, nil, 0, Gaer(0)}, + {1, 200, nil, 0, Gaer(0)}, + {1, 201, nil, 0, Gaer(5000)}, + {1, 300, nil, 0, Gaer(500000)}, + {1, 1200, nil, 0, Gaer(5000000)}, + {1, 10200, nil, 0, Gaer(50000000)}, + + // after v2 - fee by gas * gasPrice + {2, 0, Gaer(1), 0, Gaer(0)}, + {2, 0, Gaer(1), 200, Gaer(200)}, + {3, 0, Gaer(5), 200, Gaer(1000)}, + {3, 0, Gaer(5), 100000, Gaer(500000)}, + } { + resultFee := TxExecuteFee(test.forkVersion, test.gasPrice, test.usedGas, test.dbUpdateTotalSize) + assert.EqualValues(t, test.expectFee, resultFee, "TxExecuteFee(forkVersion:%d, gasPrice:%s, usedGas:%d, dbUpdateTotalSize:%d)", test.forkVersion, test.gasPrice, test.usedGas, test.dbUpdateTotalSize) + } +} + +func TestTxMaxFee(t *testing.T) { + DisableZeroFee() + defer EnableZeroFee() + + for _, test := range []struct { + forkVersion int32 + lenPayload int + gasLimit uint64 + gasPrice *big.Int + balance *big.Int + expectErr bool + expectFee *big.Int + }{ + // v1 - max fee by payload + {1, 0, 0, nil, nil, false, Gaer(2000000)}, // base 0.002 AERGO + {1, 1, 0, nil, nil, false, Gaer(1025000000)}, + {1, 200, 0, nil, nil, false, Gaer(1025000000)}, + {1, 201, 0, nil, nil, false, Gaer(1025005000)}, + {1, 300, 0, nil, nil, false, Gaer(1025500000)}, + {1, 1200, 0, nil, nil, false, Gaer(1030000000)}, + + // after v2 - max fee by gas limit + {2, 0, 1000, Gaer(5), nil, true, nil}, // smaller than base fee + {2, 0, 100000, Gaer(1), nil, false, Gaer(100000)}, + {2, 0, 100000, Gaer(5), nil, false, Gaer(500000)}, + + {2, 0, 0, Gaer(5), Gaer(500000), false, Gaer(500000)}, // no gas limit - get from balance + {2, 0, 0, Gaer(5), Gaer(1000000), false, Gaer(1000000)}, + {2, 0, 0, Gaer(5), Gaer(-1), false, new(big.Int).Mul(new(big.Int).SetUint64(math.MaxUint64), Gaer(5))}, // no gas limit and no balance = max gas + } { + resultFee, err := TxMaxFee(test.forkVersion, test.lenPayload, test.gasLimit, test.balance, test.gasPrice) + require.Equal(t, test.expectErr, err != nil, "TxMaxFee(forkVersion:%d, lenPayload:%d, gasLimit:%d, balance:%s, gasPrice:%s)", test.forkVersion, test.lenPayload, test.gasLimit, test.balance, test.gasPrice) + require.EqualValues(t, test.expectFee, resultFee, "TxMaxFee(forkVersion:%d, lenPayload:%d, gasLimit:%d, balance:%s, gasPrice:%s)", test.forkVersion, test.lenPayload, test.gasLimit, test.balance, test.gasPrice) + } +} + +func Gaer(n int) *big.Int { + return big.NewInt(0).Mul(big.NewInt(int64(n)), big.NewInt(int64(1e9))) +} diff --git a/fee/gas.go b/fee/gas.go index 2fbead419..6d023d39a 100644 --- a/fee/gas.go +++ b/fee/gas.go @@ -1,6 +1,7 @@ package fee import ( + "errors" "math" "math/big" ) @@ -10,6 +11,25 @@ const ( payloadGasSize = uint64(5) ) +func GasEnabled(version int32) bool { + return !IsZeroFee() && version >= 2 +} + +//---------------------------------------------------------------// +// calc gas + +// gas = fee / gas price +func CalcGas(fee, gasPrice *big.Int) *big.Int { + return new(big.Int).Div(fee, gasPrice) +} + +func ReceiptGasUsed(version int32, isGovernance bool, txFee, gasPrice *big.Int) uint64 { + if GasEnabled(version) && !isGovernance { + return CalcGas(txFee, gasPrice).Uint64() + } + return 0 +} + func TxGas(payloadSize int) uint64 { if IsZeroFee() { return 0 @@ -23,10 +43,50 @@ func TxGas(payloadSize int) uint64 { return txGas + payloadGas } +func GasLimit(version int32, isFeeDelegation bool, txGasLimit uint64, payloadSize int, gasPrice, usedFee, senderBalance, receiverBalance *big.Int) (gasLimit uint64, err error) { + // 1. no gas limit + if GasEnabled(version) != true { + return + } + + // 2. fee delegation + if isFeeDelegation { + // check if the contract has enough balance for fee + balance := new(big.Int).Sub(receiverBalance, usedFee) + gasLimit = MaxGasLimit(balance, gasPrice) + if gasLimit == 0 { + err = errors.New("not enough gas") + } + return + } + + // read the gas limit from the tx + gasLimit = txGasLimit + // 3. no gas limit specified, the limit is the sender's balance + if gasLimit == 0 { + balance := new(big.Int).Sub(senderBalance, usedFee) + gasLimit = MaxGasLimit(balance, gasPrice) + if gasLimit == 0 { + err = errors.New("not enough gas") + } + return + } + + // 4. check if the sender has enough balance for gas + usedGas := TxGas(payloadSize) + if gasLimit <= usedGas { + err = errors.New("not enough gas") + return + } + // subtract the used gas from the gas limit + gasLimit -= usedGas + + return gasLimit, nil +} + func MaxGasLimit(balance, gasPrice *big.Int) uint64 { gasLimit := uint64(math.MaxUint64) - n := new(big.Int).Div(balance, gasPrice) - if n.IsUint64() { + if n := CalcGas(balance, gasPrice); n.IsUint64() { gasLimit = n.Uint64() } return gasLimit diff --git a/fee/gas_test.go b/fee/gas_test.go new file mode 100644 index 000000000..c0a7438a6 --- /dev/null +++ b/fee/gas_test.go @@ -0,0 +1,118 @@ +package fee + +import ( + "math" + "math/big" + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestReceiptGasUsed(t *testing.T) { + DisableZeroFee() + defer EnableZeroFee() + + for _, test := range []struct { + version int32 + isGovernance bool + txFee *big.Int + gasPrice *big.Int + expectGasUsed uint64 + }{ + // no gas used + {1, false, big.NewInt(100), big.NewInt(5), 0}, // v1 + {2, true, big.NewInt(100), big.NewInt(5), 0}, // governance + + // gas used + {2, false, big.NewInt(10), big.NewInt(1), 10}, + {2, false, big.NewInt(10), big.NewInt(5), 2}, + {2, false, big.NewInt(100), big.NewInt(1), 100}, + {2, false, big.NewInt(100), big.NewInt(5), 20}, + } { + resultGasUsed := ReceiptGasUsed(test.version, test.isGovernance, test.txFee, test.gasPrice) + assert.Equal(t, test.expectGasUsed, resultGasUsed, "GasUsed(txFee:%s, gasPrice:%s, isGovernance:%d, version:%d)", test.txFee, test.gasPrice, test.isGovernance, test.version) + } +} + +func TestTxGas(t *testing.T) { + DisableZeroFee() + defer EnableZeroFee() + + for _, test := range []struct { + payloadSize int + expectGasUsed uint64 + }{ + // less than freeByteSize + {0, 100000}, + {200, 100000}, + + {201, 100005}, + {1000, 104000}, + {204800, 1123000}, + + // more than payloadMaxSize + freeByteSize + {205000, 1124000}, + {2048000, 1124000}, + {20480000, 1124000}, + } { + resultGasUsed := TxGas(test.payloadSize) + assert.Equal(t, int(test.expectGasUsed), int(resultGasUsed), "GasUsed(payloadSize:%d)", test.payloadSize) + } +} + +func TestGasLimit(t *testing.T) { + DisableZeroFee() + defer EnableZeroFee() + + for _, test := range []struct { + version int32 + feeDelegation bool + txGasLimit uint64 + payloadSize int + gasPrice *big.Int + usedFee *big.Int + sender *big.Int + receiver *big.Int + expectErr bool + expectGasLimit uint64 + }{ + // no gas limit + {version: 1, expectErr: false, expectGasLimit: 0}, + + // fee delegation + {version: 2, feeDelegation: true, gasPrice: Gaer(1), receiver: Gaer(5), usedFee: Gaer(10), expectErr: false, expectGasLimit: math.MaxUint64}, // max + {version: 2, feeDelegation: true, gasPrice: Gaer(1), receiver: Gaer(5), usedFee: Gaer(5), expectErr: true, expectGasLimit: 0}, // not enough error + {version: 2, feeDelegation: true, gasPrice: Gaer(1), receiver: Gaer(10), usedFee: Gaer(5), expectErr: false, expectGasLimit: 5}, + + // no gas limit specified in tx, the limit is the sender's balance + {version: 2, gasPrice: Gaer(1), sender: Gaer(5), usedFee: Gaer(10), expectErr: false, expectGasLimit: math.MaxUint64}, // max + {version: 2, gasPrice: Gaer(1), sender: Gaer(5), usedFee: Gaer(5), expectErr: true, expectGasLimit: 0}, // not enough error + {version: 2, gasPrice: Gaer(1), sender: Gaer(10), usedFee: Gaer(5), expectErr: false, expectGasLimit: 5}, + + // if gas limit specified in tx, check if the sender has enough balance for gas + {version: 2, txGasLimit: 100000, payloadSize: 100, expectErr: true, expectGasLimit: 100000}, + {version: 2, txGasLimit: 150000, payloadSize: 100, expectErr: false, expectGasLimit: 50000}, + {version: 2, txGasLimit: 200000, payloadSize: 100, expectErr: false, expectGasLimit: 100000}, + } { + gasLimit, resultErr := GasLimit(test.version, test.feeDelegation, test.txGasLimit, test.payloadSize, test.gasPrice, test.usedFee, test.sender, test.receiver) + assert.Equalf(t, test.expectErr, resultErr != nil, "GasLimit(forkVersion:%d, isFeeDelegation:%t, txGasLimit:%d, payloadSize:%d, gasPrice:%s, usedFee:%s, senderBalance:%s, receiverBalance:%s)", test.version, test.feeDelegation, test.txGasLimit, test.payloadSize, test.gasPrice, test.usedFee, test.sender, test.receiver) + assert.EqualValues(t, test.expectGasLimit, gasLimit, "GasLimit(forkVersion:%d, isFeeDelegation:%t, txGasLimit:%d, payloadSize:%d, gasPrice:%s, usedFee:%s, senderBalance:%s, receiverBalance:%s)", test.version, test.feeDelegation, test.txGasLimit, test.payloadSize, test.gasPrice, test.usedFee, test.sender, test.receiver) + } +} + +func TestMaxGasLimit(t *testing.T) { + for _, test := range []struct { + balance *big.Int + gasPrice *big.Int + expectGas uint64 + }{ + {big.NewInt(100), big.NewInt(5), 20}, + {big.NewInt(100), big.NewInt(1), 100}, + {big.NewInt(0), big.NewInt(5), 0}, + {big.NewInt(-100), big.NewInt(1), math.MaxUint64}, + {big.NewInt(-100), big.NewInt(5), math.MaxUint64}, + } { + resultGas := MaxGasLimit(test.balance, test.gasPrice) + assert.Equal(t, test.expectGas, resultGas, "MaxGasLimit(balance:%s, gasPrice:%s)", test.balance, test.gasPrice) + } +} diff --git a/fee/payload.go b/fee/payload.go index 4aa879ee4..00c105ba1 100644 --- a/fee/payload.go +++ b/fee/payload.go @@ -4,71 +4,28 @@ import ( "math/big" ) -const ( - baseTxFee = "2000000000000000" // 0.002 AERGO - payloadMaxSize = 200 * 1024 - StateDbMaxUpdateSize = payloadMaxSize - freeByteSize = 200 -) - -var ( - baseTxAergo *big.Int - zeroFee bool - stateDbMaxFee *big.Int - aerPerByte *big.Int -) - -func init() { - baseTxAergo, _ = new(big.Int).SetString(baseTxFee, 10) - zeroFee = false - aerPerByte = big.NewInt(5000000000000) // 5,000 GAER, feePerBytes * PayloadMaxBytes = 1 AERGO - stateDbMaxFee = new(big.Int).Mul(aerPerByte, big.NewInt(StateDbMaxUpdateSize-freeByteSize)) -} - -func EnableZeroFee() { - zeroFee = true -} - -func DisableZeroFee() { - zeroFee = false -} - -func IsZeroFee() bool { - return zeroFee -} - -func NewZeroFee() *big.Int { - return big.NewInt(0) -} - -func PayloadTxFee(payloadSize int) *big.Int { +func PayloadFee(payloadSize int) *big.Int { if IsZeroFee() { return NewZeroFee() } - if payloadSize == 0 { - return new(big.Int).Set(baseTxAergo) - } - size := paymentDataSize(int64(payloadSize)) - if size > payloadMaxSize { - size = payloadMaxSize + + // set data fee + dataFee := paymentDataSize(int64(payloadSize)) + if dataFee > payloadMaxSize { + dataFee = payloadMaxSize } - return new(big.Int).Add( - baseTxAergo, - new(big.Int).Mul( - aerPerByte, - big.NewInt(size), - ), - ) + // return base fee + data fee + return new(big.Int).Add(baseTxAergo, CalcFee(aerPerByte, uint64(dataFee))) } -func MaxPayloadTxFee(payloadSize int) *big.Int { +func MaxPayloadFee(payloadSize int) *big.Int { if IsZeroFee() { return NewZeroFee() } if payloadSize == 0 { return new(big.Int).Set(baseTxAergo) } - return new(big.Int).Add(PayloadTxFee(payloadSize), stateDbMaxFee) + return new(big.Int).Add(PayloadFee(payloadSize), stateDbMaxFee) } func paymentDataSize(dataSize int64) int64 { @@ -79,6 +36,6 @@ func paymentDataSize(dataSize int64) int64 { return pSize } -func PaymentDataFee(dataSize int64) *big.Int { - return new(big.Int).Mul(big.NewInt(paymentDataSize(dataSize)), aerPerByte) +func StateDataFee(dataSize int64) *big.Int { + return CalcFee(aerPerByte, uint64(paymentDataSize(dataSize))) } diff --git a/fee/payload_test.go b/fee/payload_test.go index 39aef0b05..be310ff83 100644 --- a/fee/payload_test.go +++ b/fee/payload_test.go @@ -4,43 +4,47 @@ import ( "math/big" "reflect" "testing" + + "github.com/stretchr/testify/assert" ) func TestPayloadTxFee(t *testing.T) { - type args struct { + DisableZeroFee() + defer EnableZeroFee() + + for _, tt := range []struct { + name string payloadSize int - } - tests := []struct { - name string - args args - want *big.Int + want *big.Int }{ - { - "zero", - args{payloadSize: 0}, - baseTxAergo, - }, - { - "under200", - args{payloadSize: 198}, - baseTxAergo, - }, - { - "exact200", - args{payloadSize: 198}, - baseTxAergo, - }, - { - "over200", - args{payloadSize: 265}, - new(big.Int).Add(baseTxAergo, new(big.Int).Mul(new(big.Int).SetUint64(65), aerPerByte)), - }, - } - for _, tt := range tests { + {"zero", 0, baseTxAergo}, + {"under200", 198, baseTxAergo}, + {"exact200", 198, baseTxAergo}, + {"over200", 265, new(big.Int).Add(baseTxAergo, new(big.Int).Mul(new(big.Int).SetUint64(65), aerPerByte))}, + } { t.Run(tt.name, func(t *testing.T) { - if got := PayloadTxFee(tt.args.payloadSize); !reflect.DeepEqual(got, tt.want) { + if got := PayloadFee(tt.payloadSize); !reflect.DeepEqual(got, tt.want) { t.Errorf("PayloadTxFee() = %v, want %v", got, tt.want) } }) } } + +func TestMaxPayloadTxFee(t *testing.T) { + DisableZeroFee() + defer EnableZeroFee() + + for _, test := range []struct { + payloadSize int + expectFee *big.Int + }{ + {0, PayloadFee(0)}, + {1, new(big.Int).Add(PayloadFee(1), stateDbMaxFee)}, + {200, new(big.Int).Add(PayloadFee(200), stateDbMaxFee)}, + {201, new(big.Int).Add(PayloadFee(201), stateDbMaxFee)}, + {1000, new(big.Int).Add(PayloadFee(1000), stateDbMaxFee)}, + } { + resultTxFee := MaxPayloadFee(test.payloadSize) + assert.EqualValues(t, test.expectFee, resultTxFee, "MaxPayloadTxFee(payloadSize:%d)", test.payloadSize) + } +} diff --git a/go.mod b/go.mod index 55f9e9cd0..bc05c97a5 100644 --- a/go.mod +++ b/go.mod @@ -21,8 +21,8 @@ require ( github.com/golang/protobuf v1.5.3 github.com/grpc-ecosystem/grpc-opentracing v0.0.0-20180507213350-8e809c8a8645 github.com/hashicorp/golang-lru v0.5.1 - github.com/improbable-eng/grpc-web v0.9.6 - github.com/json-iterator/go v1.1.9 + github.com/improbable-eng/grpc-web v0.15.0 + github.com/json-iterator/go v1.1.10 github.com/libp2p/go-addr-util v0.0.1 github.com/libp2p/go-libp2p v0.4.0 github.com/libp2p/go-libp2p-core v0.2.3 @@ -33,7 +33,7 @@ require ( github.com/mr-tron/base58 v1.1.2 github.com/multiformats/go-multiaddr v0.1.1 github.com/multiformats/go-multiaddr-net v0.1.0 - github.com/opentracing/opentracing-go v1.0.2 + github.com/opentracing/opentracing-go v1.1.0 github.com/pkg/errors v0.9.1 github.com/rs/zerolog v1.29.1 github.com/sanity-io/litter v1.5.5 @@ -42,28 +42,30 @@ require ( github.com/spf13/viper v1.5.0 github.com/stretchr/testify v1.8.4 github.com/willf/bloom v2.0.3+incompatible - golang.org/x/crypto v0.11.0 - google.golang.org/grpc v1.56.2 + golang.org/x/crypto v0.14.0 + google.golang.org/grpc v1.59.0 google.golang.org/protobuf v1.31.0 ) require ( github.com/Workiva/go-datastructures v1.0.50 // indirect - github.com/beorn7/perks v1.0.0 // indirect + github.com/beorn7/perks v1.0.1 // indirect + github.com/cenkalti/backoff/v4 v4.1.1 // indirect github.com/cespare/xxhash v1.1.0 // indirect github.com/cespare/xxhash/v2 v2.2.0 // indirect github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e // indirect github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f // indirect + github.com/desertbit/timer v0.0.0-20180107155436-c41aec40b27f // indirect github.com/dgraph-io/badger/v3 v3.2103.2 // indirect github.com/dgraph-io/ristretto v0.1.0 // indirect github.com/dustin/go-humanize v1.0.0 // indirect github.com/funkygao/assert v0.0.0-20160929004900-4a267e33bc79 // indirect github.com/gogo/protobuf v1.3.2 // indirect - github.com/golang/glog v1.1.0 // indirect + github.com/golang/glog v1.1.2 // indirect github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6 // indirect github.com/golang/snappy v0.0.3 // indirect github.com/google/flatbuffers v1.12.1 // indirect - github.com/google/uuid v1.3.0 // indirect + github.com/google/uuid v1.3.1 // indirect github.com/gorilla/websocket v1.4.1 // indirect github.com/hashicorp/hcl v1.0.1-0.20180906183839-65a6292f0157 // indirect github.com/huin/goupnp v1.0.0 // indirect @@ -122,11 +124,11 @@ require ( github.com/pelletier/go-toml v1.2.1-0.20180930205832-81a861c69d25 // indirect github.com/pkg/term v0.0.0-20190109203006-aa71e9d9e942 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect - github.com/prometheus/client_golang v1.0.0 // indirect - github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4 // indirect - github.com/prometheus/common v0.4.1 // indirect - github.com/prometheus/procfs v0.0.2 // indirect - github.com/rs/cors v1.6.0 // indirect + github.com/prometheus/client_golang v1.7.1 // indirect + github.com/prometheus/client_model v0.2.0 // indirect + github.com/prometheus/common v0.15.0 // indirect + github.com/prometheus/procfs v0.3.0 // indirect + github.com/rs/cors v1.7.0 // indirect github.com/serialx/hashring v0.0.0-20190515033939-7706f26af194 // indirect github.com/smola/gocompat v0.2.0 // indirect github.com/spacemonkeygo/spacelog v0.0.0-20180420211403-2296661a0572 // indirect @@ -145,18 +147,18 @@ require ( github.com/willf/bitset v1.1.10 // indirect github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2 // indirect go.opencensus.io v0.22.5 // indirect - golang.org/x/mod v0.8.0 // indirect - golang.org/x/net v0.12.0 // indirect - golang.org/x/sync v0.3.0 // indirect - golang.org/x/sys v0.10.0 // indirect - golang.org/x/term v0.10.0 // indirect - golang.org/x/text v0.11.0 // indirect - golang.org/x/time v0.0.0-20190308202827-9d24e82272b4 // indirect - golang.org/x/tools v0.6.0 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20230711160842-782d3b101e98 // indirect + golang.org/x/mod v0.13.0 // indirect + golang.org/x/net v0.17.0 // indirect + golang.org/x/sys v0.13.0 // indirect + golang.org/x/term v0.13.0 // indirect + golang.org/x/text v0.13.0 // indirect + golang.org/x/time v0.3.0 // indirect + golang.org/x/tools v0.14.0 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20230822172742-b8732ec3820d // indirect google.golang.org/grpc/examples v0.0.0-20230724170852-2aa261560586 // indirect - gopkg.in/yaml.v2 v2.2.8 // indirect + gopkg.in/yaml.v2 v2.3.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect + nhooyr.io/websocket v1.8.6 // indirect ) replace github.com/Sirupsen/logrus => github.com/sirupsen/logrus v1.8.1 diff --git a/go.sum b/go.sum index 0e8dfab42..dff5eee98 100644 --- a/go.sum +++ b/go.sum @@ -1,11 +1,18 @@ cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= github.com/AndreasBriese/bbloom v0.0.0-20180913140656-343706a395b7/go.mod h1:bOvUY6CB00SOBii9/FifXqc0awNKxLFCL/+pkDPuyl8= github.com/AndreasBriese/bbloom v0.0.0-20190306092124-e2d15f34fcf9/go.mod h1:bOvUY6CB00SOBii9/FifXqc0awNKxLFCL/+pkDPuyl8= github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= +github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0= github.com/Kubuxu/go-os-helper v0.0.1/go.mod h1:N8B+I7vPCT80IcP58r50u4+gEEcsZETFUpAzWW2ep1Y= github.com/OneOfOne/xxhash v1.2.2 h1:KMrpdQIwFcEqXDklaen+P1axHaj9BSKzvpUUfnHldSE= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= +github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo= +github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI= +github.com/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/4+TcAqDqk/vUH7g= github.com/Workiva/go-datastructures v1.0.50 h1:slDmfW6KCHcC7U+LP3DDBbm4fqTwZGn1beOFPfGaLvo= github.com/Workiva/go-datastructures v1.0.50/go.mod h1:Z+F2Rca0qCsVYDS8z7bAGm8f3UkzuWYS/oBZz5a7VVA= github.com/aead/siphash v1.0.1/go.mod h1:Nywa3cDsYNNK3gaciGTWPwHt0wlpNV15vwmswBAUSII= @@ -15,14 +22,29 @@ github.com/aergoio/aergo-lib v1.1.0 h1:tPilY3bZr28DyJ0gZFXquiYv2veUIar1fGTDYljAL github.com/aergoio/aergo-lib v1.1.0/go.mod h1:+RYRhok9tHDgRR8nj+mQx9qqknKBnJYvrlEJwr+RYqY= github.com/aergoio/etcd v0.0.0-20190429013412-e8b3f96f6399 h1:dJSTOiNe0xJFreGUBSh4bY3KGDxjilUVxAKqjij1pcw= github.com/aergoio/etcd v0.0.0-20190429013412-e8b3f96f6399/go.mod h1:Blp9ztau8P3FoDynvGUeKUD6qqW/2xQ80kNwU+ywPUM= +github.com/afex/hystrix-go v0.0.0-20180502004556-fa1af6a1f4f5/go.mod h1:SkGFH1ia65gfNATL8TAiHDNxPzPdmEL5uirI2Uyuz6c= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= +github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= +github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= +github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho= github.com/anaskhan96/base58check v0.0.0-20181220122047-b05365d494c4 h1:FUDNaUiPOxrVtUmsRSdx7hrvCKXpfQafPpPU0Yh27os= github.com/anaskhan96/base58check v0.0.0-20181220122047-b05365d494c4/go.mod h1:glPG1rmt/bD3wEXWanFIuoPjC4MG+JEN+i7YhwEYA/Y= +github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= +github.com/apache/thrift v0.13.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= +github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= +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/aws/aws-lambda-go v1.13.3/go.mod h1:4UKl9IzQMoD+QF79YdCuzCwp8VbmG4VAQwij/eHl5CU= +github.com/aws/aws-sdk-go v1.27.0/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= +github.com/aws/aws-sdk-go-v2 v0.18.0/go.mod h1:JWVYvqSMppoMJC0x5wdwiImzgXTI9FuZwxzkQq9wy+g= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= -github.com/beorn7/perks v1.0.0 h1:HWo1m869IqiPhD389kmkxeTalrjNbbJTC8LXupb+sl0= github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= +github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= +github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= +github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= github.com/bluele/gcache v0.0.0-20190518031135-bc40bd653833 h1:yCfXxYaelOyqnia8F/Yng47qhmfC9nKTRIbYRrRueq4= github.com/bluele/gcache v0.0.0-20190518031135-bc40bd653833/go.mod h1:8c4/i2VlovMO2gBnHGQPN5EJw+H0lx1u/5p+cgsXtCk= github.com/btcsuite/btcd v0.0.0-20190213025234-306aecffea32/go.mod h1:DrZx5ec/dmnfpw9KyYoQyYo7d0KEvTkk/5M/vbZjAr8= @@ -39,24 +61,37 @@ github.com/btcsuite/websocket v0.0.0-20150119174127-31079b680792/go.mod h1:ghJtE github.com/btcsuite/winsvc v1.0.0/go.mod h1:jsenWakMcC0zFBFurPLEAyrnc/teJEM1O46fmI40EZs= github.com/c-bata/go-prompt v0.2.3 h1:jjCS+QhG/sULBhAaBdjb2PlMRVaKXQgn+4yzaauvs2s= github.com/c-bata/go-prompt v0.2.3/go.mod h1:VzqtzE2ksDBcdln8G7mk2RX9QyGjH+OVqOCSiVIqS34= +github.com/casbin/casbin/v2 v2.1.2/go.mod h1:YcPU1XXisHhLzuxH9coDNf2FbKpjGlbCg3n9yuLkIJQ= +github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM= +github.com/cenkalti/backoff/v4 v4.1.1 h1:G2HAfAmvm/GcKan2oOQpBXOd2tT2G57ZnZGWa1PxPBQ= +github.com/cenkalti/backoff/v4 v4.1.1/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw= +github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko= github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/clbanning/x2j v0.0.0-20191024224557-825249438eec/go.mod h1:jMjuTZXRI4dUb/I5gc9Hdhagfvm9+RyrPryS/auMzxE= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= +github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8= +github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI= github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk= github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= github.com/coreos/go-semver v0.3.0 h1:wkHLiw0WNATZnSG7epLsujiMCgPAc9xhjJ4tgnAxmfM= github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= +github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e h1:Wf6HqHfScWJN9/ZjdUKyjop4mf3Qdd+1TvvltAvM3m8= github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= +github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f h1:lBNOc5arjvs8E5mO2tbpBpLoyyu8B6e44T7hJy6potg= github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= +github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= +github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= github.com/davecgh/go-spew v0.0.0-20161028175848-04cdfd42973b/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v0.0.0-20171005155431-ecdeabc65495/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= @@ -64,6 +99,8 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/derekparker/trie v0.0.0-20190322172448-1ce4922c7ad9 h1:aSaTVlEXc2QKl4fzXU1tMYCjlrSc2mA4DZtiVfckQHo= github.com/derekparker/trie v0.0.0-20190322172448-1ce4922c7ad9/go.mod h1:D6ICZm05D9VN1n/8iOtBxLpXtoGp6HDFUJ1RNVieOSE= +github.com/desertbit/timer v0.0.0-20180107155436-c41aec40b27f h1:U5y3Y5UE0w7amNe7Z5G/twsBW0KEalRQXZzf8ufSh9I= +github.com/desertbit/timer v0.0.0-20180107155436-c41aec40b27f/go.mod h1:xH/i4TFMt8koVQZ6WFms69WAsDWr2XsYL3Hkl7jkoLE= github.com/dgraph-io/badger v1.5.5-0.20190226225317-8115aed38f8f/go.mod h1:VZxzAIRPHRVNRKRo6AXrX9BJegn6il06VMTZVJYCIjQ= github.com/dgraph-io/badger v1.6.0-rc1/go.mod h1:zwt7syl517jmP8s94KqSxTlM6IMsdhYy6psNgSztDR4= github.com/dgraph-io/badger/v3 v3.2103.2 h1:dpyM5eCJAtQCBcMCZcT4UBZchuTJgCywerHHgmxfxM8= @@ -76,10 +113,23 @@ github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2/go.mod h1:SqUrOPUn github.com/dgryski/go-farm v0.0.0-20200201041132-a6ae2369ad13 h1:fAjc9m62+UWV/WAFKLNi6ZS0675eEUC9y3AlwSbQu1Y= github.com/dgryski/go-farm v0.0.0-20200201041132-a6ae2369ad13/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw= github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no= +github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= github.com/dustin/go-humanize v1.0.0 h1:VSnTsYCnlFHaM2/igO1h6X3HA71jcobQuxemgkq4zYo= github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= +github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs= +github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU= +github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I= +github.com/edsrzf/mmap-go v1.0.0/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M= github.com/emirpasic/gods v1.12.0 h1:QAUIPSaCu4G+POclxeqb3F+WPpdKqFGlw36+yOzGlrg= github.com/emirpasic/gods v1.12.0/go.mod h1:YfzfFFoVP/catgzJb4IKIqXjX78Ha8FMSDh3ymbK86o= +github.com/envoyproxy/go-control-plane v0.6.9/go.mod h1:SBwIajubJHhxtWwsL9s8ss4safvEdbitLhGGK48rN6g= +github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= +github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= +github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= +github.com/franela/goblin v0.0.0-20200105215937-c9ffbefa60db/go.mod h1:7dvUGVsVBjqR7JHJk0brhHOZYGmfBYOrK0ZhYMEtBr4= +github.com/franela/goreq v0.0.0-20171204163338-bcd34c9993f8/go.mod h1:ZhphrRTfi2rbfLwlschooIH4+wKKDR4Pdxhh+TRoA20= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.4.8-0.20180830220226-ccc981bf8038 h1:j2xrf/etQ7t7yE6yPggWVr8GLKpISYIwxxLiHdOCHis= github.com/fsnotify/fsnotify v1.4.8-0.20180830220226-ccc981bf8038/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= @@ -88,22 +138,47 @@ github.com/funkygao/assert v0.0.0-20160929004900-4a267e33bc79/go.mod h1:f/3KPzEH github.com/funkygao/golib v0.0.0-20180314131852-90d4905c1961 h1:17GfB8KI6sVSDbk6P9JmXhYcXI83brT609GUOviGSSs= github.com/funkygao/golib v0.0.0-20180314131852-90d4905c1961/go.mod h1:o83CLAArAI7NmTbznViTftc/ELn38qwnCOGsRI/DgR4= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= +github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE= +github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= +github.com/gin-gonic/gin v1.6.3 h1:ahKqKTFpO5KTPHxWZjEdPScmYaGtLo8Y4DMHoEsnp14= +github.com/gin-gonic/gin v1.6.3/go.mod h1:75u5sXoLsGZoRN5Sgbi1eraJ4GU3++wFwWzhwvtwp4M= github.com/go-check/check v0.0.0-20180628173108-788fd7840127/go.mod h1:9ES+weclKsC9YodN5RgxqK/VD9HM9JsCSh7rNhMZE98= +github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= +github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= +github.com/go-kit/kit v0.10.0/go.mod h1:xUsJbQ/Fp4kEt7AFgCuvyX4a71u8h9jB8tj/ORgOZ7o= github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= +github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= +github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= +github.com/go-playground/locales v0.13.0 h1:HyWk6mgj5qFqCT5fjGBuRArbVDfE4hi8+e8ceBS/t7Q= +github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8= +github.com/go-playground/universal-translator v0.17.0 h1:icxd5fm+REJzpZx7ZfpaD876Lmtgy7VtROAbHHXk8no= +github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA= +github.com/go-playground/validator/v10 v10.2.0 h1:KgJ0snyC2R9VXYN2rneOtQcw5aHQB1Vv0sFl1UcHBOY= +github.com/go-playground/validator/v10 v10.2.0/go.mod h1:uOYAAleCW8F/7oMFd6aG0GOhaH6EGOAJShg8Id5JGkI= +github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= +github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee h1:s+21KNqlpePfkah2I+gwHF8xmJWRjooY+5248k6m4A0= +github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee/go.mod h1:L0fX3K22YWvt/FAX9NnzrNzcI4wNYi9Yku4O0LKYflo= +github.com/gobwas/pool v0.2.0 h1:QEmUOlnSjWtnpRGHF3SauEiOsy82Cup83Vf2LcMlnc8= +github.com/gobwas/pool v0.2.0/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw= +github.com/gobwas/ws v1.0.2 h1:CoAavW/wd/kulfZmSIBt6p24n4j7tHgNVCjsfHVNUbo= +github.com/gobwas/ws v1.0.2/go.mod h1:szmBTxLgaFppYjEmNtny/v3w89xOydFnnZMcgRRu/EM= github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/gofrs/uuid v3.2.0+incompatible h1:y12jRkkFxsd7GpqdSZ+/KCs/fJbqpEXSGd4+jfEaewE= github.com/gofrs/uuid v3.2.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= +github.com/gogo/googleapis v1.1.0/go.mod h1:gf4bu3Q80BeJ6H1S1vYPm8/ELATdvryBaNFGgqEef3s= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= +github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= github.com/gogo/protobuf v1.3.0/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= -github.com/golang/glog v1.1.0 h1:/d3pCKDPWNnvIWe0vVUpNP32qc8U3PDVxySP/y360qE= -github.com/golang/glog v1.1.0/go.mod h1:pfYeQZ3JWZoXTV5sFc986z3HTpwQs9At6P4ImfuP3NQ= +github.com/golang/glog v1.1.2 h1:DVjP2PbBOzHyzA+dn3WhHIq4NdVu3Q+pvivFICf/7fo= +github.com/golang/glog v1.1.2/go.mod h1:zR+okUeTbrL6EL3xHUDxZuEtGv04p5shwip1+mL/rLQ= +github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6 h1:ZgQEtGgCBiWRM39fZuwSd1LwSqqSW0hOdXCYYDX0R3I= github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= @@ -113,52 +188,96 @@ github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFU github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.0/go.mod h1:Qd/q+1AKNOZr9uGQzbzCmRO6sUih6GTPZv6a1/R87v0= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= +github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk= +github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= +github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= +github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= +github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= +github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= +github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= +github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.3 h1:fHPg5GQYlCeLIPB9BZqMVR5nR9A+IM5zcgeTdjMYmLA= github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/flatbuffers v1.12.1 h1:MVlul7pQNoDzWRLTw5imwYsl+usrS1TXG2H4jg6ImGw= github.com/google/flatbuffers v1.12.1/go.mod h1:1AeVuKshWv4vARoZatz6mlQ0JxURH0Kv5+zNeJKJCa8= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= +github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= -github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.3.1 h1:KjJaJ9iWZ3jOFZIf1Lqf4laDRCasjl0BCmnEGxkdLb4= +github.com/google/uuid v1.3.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +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/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= +github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= github.com/gorilla/websocket v1.4.1 h1:q7AeDBpnBk8AogcD4DSag/Ukw/KV+YhzLj2bP5HvKCM= github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= +github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de4/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= +github.com/grpc-ecosystem/go-grpc-middleware v1.2.2/go.mod h1:EaizFBKfUKtMIF5iaDEhniwNedqGo9FuLFzppDr3uwI= github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= +github.com/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= github.com/grpc-ecosystem/grpc-opentracing v0.0.0-20180507213350-8e809c8a8645 h1:MJG/KsmcqMwFAkh8mTnAwhyKoB+sTAnY4CACC110tbU= github.com/grpc-ecosystem/grpc-opentracing v0.0.0-20180507213350-8e809c8a8645/go.mod h1:6iZfnjpejD4L/4DwD7NryNaJyCQdzwWwH2MWhCA90Kw= github.com/guptarohit/asciigraph v0.4.1 h1:YHmCMN8VH81BIUIgTg2Fs3B52QDxNZw2RQ6j5pGoSxo= github.com/guptarohit/asciigraph v0.4.1/go.mod h1:9fYEfE5IGJGxlP1B+w8wHFy7sNZMhPtn59f0RLtpRFM= github.com/gxed/hashland/keccakpg v0.0.1/go.mod h1:kRzw3HkwxFU1mpmPP8v1WyQzwdGfmKFJ6tItnhQ67kU= github.com/gxed/hashland/murmur3 v0.0.1/go.mod h1:KjXop02n4/ckmZSnY2+HKcLud/tcmvhST0bie/0lS48= +github.com/hashicorp/consul/api v1.3.0/go.mod h1:MmDNSzIMUjNpY/mQ398R4bk2FnqQLoPndWW5VkKPlCE= +github.com/hashicorp/consul/sdk v0.3.0/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8= +github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= +github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= +github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= +github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= +github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= +github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU= +github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU= +github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4= +github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= +github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.1 h1:0hERBMJE1eitiLkihrMvRVBYAkpHzc/J3QdDN+dAcgU= github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= github.com/hashicorp/hcl v1.0.1-0.20180906183839-65a6292f0157 h1:uyodBE3xDz0ynKs1tLBU26wOQoEkAqqiY18DbZ+FZrA= github.com/hashicorp/hcl v1.0.1-0.20180906183839-65a6292f0157/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= +github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64= +github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ= +github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I= +github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc= github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= +github.com/hudl/fargo v1.3.0/go.mod h1:y3CKSmjA+wD2gak7sUSXTAoopbhU08POFhmITJgmKTg= github.com/huin/goupnp v1.0.0 h1:wg75sLpL6DZqwHQN6E1Cfk6mtfzS45z8OV+ic+DtHRo= github.com/huin/goupnp v1.0.0/go.mod h1:n9v9KO1tAxYH82qOn+UTIFQDmx5n1Zxd/ClZDMX7Bnc= github.com/huin/goutil v0.0.0-20170803182201-1ca381bf3150/go.mod h1:PpLOETDnJ0o3iZrZfqZzyLl6l7F3c6L1oWn7OICBi6o= -github.com/improbable-eng/grpc-web v0.9.6 h1:B8FH/k5xv/vHovSt70GJHIB2/1+4plmvtfrz33ambuE= -github.com/improbable-eng/grpc-web v0.9.6/go.mod h1:6hRR09jOEG81ADP5wCQju1z71g6OL4eEvELdran/3cs= +github.com/improbable-eng/grpc-web v0.15.0 h1:BN+7z6uNXZ1tQGcNAuaU1YjsLTApzkjt2tzCixLaUPQ= +github.com/improbable-eng/grpc-web v0.15.0/go.mod h1:1sy9HKV4Jt9aEs9JSnkWlRJPuPtwNr0l57L4f878wP8= github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= +github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo= github.com/ipfs/go-cid v0.0.1/go.mod h1:GHWU/WuQdMPmIosc4Yn1bcCT7dSeX4lBafM7iqUPQvM= github.com/ipfs/go-cid v0.0.2/go.mod h1:GHWU/WuQdMPmIosc4Yn1bcCT7dSeX4lBafM7iqUPQvM= github.com/ipfs/go-cid v0.0.3 h1:UIAh32wymBpStoe83YCzwVQQ5Oy/H0FdxvUS6DJDzms= @@ -188,21 +307,31 @@ github.com/jbenet/goprocess v0.1.3 h1:YKyIEECS/XvcfHtBzxtjBBbWK+MbvA6dG8ASiqwvr1 github.com/jbenet/goprocess v0.1.3/go.mod h1:5yspPrukOVuOLORacaBi858NqyClJPQxYZlqdZVfqY4= github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= +github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= +github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= github.com/jrick/logrotate v1.0.0/go.mod h1:LNinyqDIJnpAur+b8yyulnQw/wDuN1+BYKlTRt3OuAQ= github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= -github.com/json-iterator/go v1.1.9 h1:9yzud/Ht36ygwatGx56VwCZtlI/2AD15T1X2sjSuGns= +github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/json-iterator/go v1.1.8/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/json-iterator/go v1.1.10 h1:Kz6Cvnvv2wGdaG/V8yMvfkmNiXq9Ya2KUv4rouJJr68= +github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= +github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM= github.com/kami-zh/go-capturer v0.0.0-20171211120116-e492ea43421d/go.mod h1:P2viExyCEfeWGU259JnaQ34Inuec4R38JCyBx2edgD0= github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/kkdai/bstream v0.0.0-20161212061736-f391b8402d23/go.mod h1:J+Gs4SYgM6CZQHDETBtE9HaSEkGmuNXF86RwHhHUvq4= +github.com/klauspost/compress v1.10.3/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= +github.com/klauspost/compress v1.11.7/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= github.com/klauspost/compress v1.12.3 h1:G5AfA94pHPysR56qqrkO2pxEexdDzrpFJ6yt/VqWxVU= github.com/klauspost/compress v1.12.3/go.mod h1:8dP1Hq4DHOhN9w426knH3Rhby4rFm6D8eO+e+Dq5Gzg= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/koron/go-ssdp v0.0.0-20180514024734-4a0ed625a78b h1:wxtKgYHEncAU00muMD06dzLiahtGM1eouRNOzVV7tdQ= github.com/koron/go-ssdp v0.0.0-20180514024734-4a0ed625a78b/go.mod h1:5Ky9EC2xfoUKUor0Hjgi2BJhCSXJfMOFlmyYrVKGQMk= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= @@ -211,6 +340,8 @@ github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORN github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/leodido/go-urn v1.2.0 h1:hpXL4XnriNwQ/ABnpepYM/1vCLWNDfUNts8dX3xTG6Y= +github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII= github.com/libp2p/go-addr-util v0.0.1 h1:TpTQm9cXVRVSKsYbgQ7GKc3KbbHVTnbostgGaDEP+88= github.com/libp2p/go-addr-util v0.0.1/go.mod h1:4ac6O7n9rIAKB1dnd+s8IbbMXkt+oBpzX4/+RACcnlQ= github.com/libp2p/go-buffer-pool v0.0.1/go.mod h1:xtyIz9PMobb13WaxR6Zo1Pd1zXJKYg0a8KiIvDp3TzQ= @@ -296,6 +427,9 @@ github.com/libp2p/go-ws-transport v0.1.2/go.mod h1:dsh2Ld8F+XNmzpkaAijmg5Is+e9l6 github.com/libp2p/go-yamux v1.2.2/go.mod h1:FGTiPvoV/3DVdgWpX+tM0OW3tsM+W5bSE3gZwqQTcow= github.com/libp2p/go-yamux v1.2.3 h1:xX8A36vpXb59frIzWFdEgptLMsOANMFq2K7fPRlunYI= github.com/libp2p/go-yamux v1.2.3/go.mod h1:FGTiPvoV/3DVdgWpX+tM0OW3tsM+W5bSE3gZwqQTcow= +github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20190605223551-bc2310a04743/go.mod h1:qklhhLq1aX+mtWk9cPHPzaBjWImj5ULL6C7HFJtXQMM= +github.com/lightstep/lightstep-tracer-go v0.18.1/go.mod h1:jlF1pusYV4pidLvZ+XD0UBX0ZE6WURAspgAczcDHrL4= +github.com/lyft/protoc-gen-validate v0.0.13/go.mod h1:XbGvPuh87YZc5TdIa2/I4pLk0QoUACkjt2znoq26NVQ= github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= github.com/magiconair/properties v1.8.1 h1:ZC2Vc7/ZFkGmsVC9KvOjumD+G5lXy2RtTKyzRKO2BQ4= github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= @@ -306,12 +440,15 @@ github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcncea github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= github.com/mattn/go-colorable v0.1.12 h1:jF+Du6AlPIjs2BiUiQlKOX0rt3SujHxPnksPKZbaA40= github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= +github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= github.com/mattn/go-isatty v0.0.5/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= github.com/mattn/go-isatty v0.0.10/go.mod h1:qgIWMr58cqv1PHHyhnkY9lrL7etaEgOFcMEpPG5Rm84= +github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y= github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= +github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= github.com/mattn/go-runewidth v0.0.4 h1:2BvfKmzob6Bmd4YsL0zygOqfdFnK7GR4QL06Do4/p7Y= github.com/mattn/go-runewidth v0.0.4/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= github.com/mattn/go-tty v0.0.0-20190424173100-523744f04859 h1:smQbSzmT3EHl4EUwtFwFGmGIpiYgIiiPeVv1uguIQEE= @@ -319,6 +456,7 @@ github.com/mattn/go-tty v0.0.0-20190424173100-523744f04859/go.mod h1:XPvLUNfbS4f github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b/go.mod h1:01TrycV0kFyexm33Z7vhZRXopbI8J3TDReVlkTgMUxE= +github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= github.com/miekg/dns v1.1.12/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1 h1:lYpkrQH5ajf0OXOcUbGjvZxxijuBwbbmlSxLiuofa+g= github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1/go.mod h1:pD8RvIylQ358TN4wwqatJ8rNavkEINozVn9DtGI3dfQ= @@ -330,7 +468,13 @@ github.com/minio/sha256-simd v0.1.0/go.mod h1:2FMWW+8GMoPweT6+pI63m9YE3Lmw4J71hV github.com/minio/sha256-simd v0.1.1-0.20190913151208-6de447530771/go.mod h1:B5e1o+1/KgNmWrSQK08Y6Z1Vb5pwIktudl0J58iy0KM= github.com/minio/sha256-simd v0.1.1 h1:5QHSlgo3nt5yKOJrC7W8w7X+NFl8cMPZm96iu8kKUJU= github.com/minio/sha256-simd v0.1.1/go.mod h1:B5e1o+1/KgNmWrSQK08Y6Z1Vb5pwIktudl0J58iy0KM= +github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc= +github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= +github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI= +github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS42BGNg= +github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY= +github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= github.com/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQzvN1EDeE= github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= @@ -370,9 +514,21 @@ github.com/multiformats/go-multihash v0.0.8 h1:wrYcW5yxSi3dU07n5jnuS5PrNwyHy0zRH github.com/multiformats/go-multihash v0.0.8/go.mod h1:YSLudS+Pi8NHE7o6tb3D8vrpKa63epEDmG8nTduyAew= github.com/multiformats/go-multistream v0.1.0 h1:UpO6jrsjqs46mqAK3n6wKRYFhugss9ArzbyUzU+4wkQ= github.com/multiformats/go-multistream v0.1.0/go.mod h1:fJTiDfXJVmItycydCnNx4+wSzZ5NwG2FEVAI30fiovg= -github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223 h1:F9x/1yl3T2AeKLr2AMdilSD8+f9bvMnNN8VS5iDtovc= github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= +github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f h1:KUppIJq7/+SVif2QVs3tOP0zanoHgBEVAwHxUSIzRqU= +github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= +github.com/mwitkow/grpc-proxy v0.0.0-20181017164139-0f1106ef9c76/go.mod h1:x5OoJHDHqxHS801UIuhqGl6QdSAEJvtausosHSdazIo= +github.com/nats-io/jwt v0.3.0/go.mod h1:fRYCDE99xlTsqUzISS1Bi75UBJ6ljOJQOAAu5VglpSg= +github.com/nats-io/jwt v0.3.2/go.mod h1:/euKqTS1ZD+zzjYrY7pseZrTtWQSjujC7xjPc8wL6eU= +github.com/nats-io/nats-server/v2 v2.1.2/go.mod h1:Afk+wRZqkMQs/p45uXdrVLuab3gwv3Z8C4HTBu8GD/k= +github.com/nats-io/nats.go v1.9.1/go.mod h1:ZjDU1L/7fJ09jvUSRVBR2e7+RnLiiIQyqyzEE/Zbp4w= +github.com/nats-io/nkeys v0.1.0/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w= +github.com/nats-io/nkeys v0.1.3/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w= +github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c= +github.com/oklog/oklog v0.3.2/go.mod h1:FCV+B7mhrz4o+ueLpx+KqkyXRGMWOYEvfiXtdGtbWGs= +github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA= github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= +github.com/olekukonko/tablewriter v0.0.0-20170122224234-a0225b3f23b5/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.8.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= @@ -382,57 +538,100 @@ github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1Cpa github.com/onsi/gomega v1.5.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.7.1 h1:K0jcRCwNQM3vFGh1ppMtDh/+7ApJrjldlX8fA0jDTLQ= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= -github.com/opentracing/opentracing-go v1.0.2 h1:3jA2P6O1F9UOrWVpwrIo17pu01KWvNWg4X946/Y5Zwg= +github.com/op/go-logging v0.0.0-20160315200505-970db520ece7/go.mod h1:HzydrMdWErDVzsI23lYNej1Htcns9BCg93Dk0bBINWk= +github.com/opentracing-contrib/go-observer v0.0.0-20170622124052-a52f23424492/go.mod h1:Ngi6UdF0k5OKD5t5wlmGhe/EDKPoUM3BXZSSfIuJbis= +github.com/opentracing/basictracer-go v1.0.0/go.mod h1:QfBfYuafItcjQuMwinw9GhYKwFXS9KnPs5lxoYwgW74= github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= +github.com/opentracing/opentracing-go v1.1.0 h1:pWlfV3Bxv7k65HYwkikxat0+s3pV4bsqf19k25Ur8rU= +github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= +github.com/openzipkin-contrib/zipkin-go-opentracing v0.4.5/go.mod h1:/wsWhb9smxSfWAKL3wpBW7V8scJMt8N8gnaMCS9E/cA= +github.com/openzipkin/zipkin-go v0.1.6/go.mod h1:QgAqvLzwWbR/WpD4A3cGpPtJrZXNIiJc5AZX7/PBEpw= +github.com/openzipkin/zipkin-go v0.2.1/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4= +github.com/openzipkin/zipkin-go v0.2.2/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4= github.com/orcaman/concurrent-map v0.0.0-20190314100340-2693aad1ed75 h1:IV56VwUb9Ludyr7s53CMuEh4DdTnnQtEPLEgLyJ0kHI= github.com/orcaman/concurrent-map v0.0.0-20190314100340-2693aad1ed75/go.mod h1:Lu3tH6HLW3feq74c2GC+jIMS/K2CFcDWnWD9XkenwhI= +github.com/pact-foundation/pact-go v1.0.4/go.mod h1:uExwJY4kCzNPcHRj+hCR/HBbOOIwwtUjcrb0b5/5kLM= +github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= +github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k= github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= github.com/pelletier/go-toml v1.2.1-0.20180930205832-81a861c69d25 h1:a49/z+9Z5t53bD9NMajAJMe5tN0Kcz5Y6bvFxD/TPwo= github.com/pelletier/go-toml v1.2.1-0.20180930205832-81a861c69d25/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= +github.com/performancecopilot/speed v3.0.0+incompatible/go.mod h1:/CLtqpZ5gBg1M9iaPbIdPPGyKcA8hKdoy6hAWba7Yac= +github.com/pierrec/lz4 v1.0.2-0.20190131084431-473cd7ce01a1/go.mod h1:3/3N9NVKO0jef7pBehbT1qWhCMrIgbYNnFAZCqQ5LRc= +github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/profile v1.2.1/go.mod h1:hJw3o1OdXxsrSjjVksARp5W95eeEaEfptyVZyv6JUPA= github.com/pkg/term v0.0.0-20190109203006-aa71e9d9e942 h1:A7GG7zcGjl3jqAqGPmcNjd/D9hzL95SuoOQAaFNdLU0= github.com/pkg/term v0.0.0-20190109203006-aa71e9d9e942/go.mod h1:eCbImbZ95eXtAUIbLAuAVnBnwf83mjf6QIVH8SHYwqQ= github.com/pmezard/go-difflib v0.0.0-20151028094244-d8ed2627bdf0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= +github.com/prometheus/client_golang v0.9.3-0.20190127221311-3c4408c8b829/go.mod h1:p2iRAGwDERtqlqzRXnrOVns+ignqQo//hLXqYxZYVNs= github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso= -github.com/prometheus/client_golang v1.0.0 h1:vrDKnkGzuGvhNAL56c7DBz29ZL+KxnoR0x7enabFceM= github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= +github.com/prometheus/client_golang v1.3.0/go.mod h1:hJaj2vgQTGQmVCsAACORcieXFeDPbaTKGT+JTgUa3og= +github.com/prometheus/client_golang v1.7.1 h1:NTGy1Ja9pByO+xAeH/qiWnLrKtr3hJPNjaVUwnjpdpA= +github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= +github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4 h1:gQz4mCbXsO+nc9n1hCxHcGA3Zx3Eo+UHZoInFGUIXNM= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/client_model v0.1.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/client_model v0.2.0 h1:uq5h0d+GuxiXLJLNABMgp2qUWDPiLvgCzz2dUR+/W/M= +github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= +github.com/prometheus/common v0.2.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= -github.com/prometheus/common v0.4.1 h1:K0MGApIoQvMw27RTdJkPbr3JZ7DNbtxQNyi5STVM6Kw= github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= +github.com/prometheus/common v0.7.0/go.mod h1:DjGbpBbp5NYNiECxcL/VnbXCCaQpKd3tt26CguLLsqA= +github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo= +github.com/prometheus/common v0.15.0 h1:4fgOnadei3EZvgRwxJ7RMpG1k1pOZth5Pc13tyspaKM= +github.com/prometheus/common v0.15.0/go.mod h1:U+gB1OBLb1lF3O42bTCL+FK18tX9Oar16Clt/msog/s= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= +github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= -github.com/prometheus/procfs v0.0.2 h1:6LJUbpNm42llc4HRCuvApCSWB/WfhuNo9K98Q9sNGfs= github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= +github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A= +github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= +github.com/prometheus/procfs v0.3.0 h1:Uehi/mxLK0eiUc0H0++5tpMGTexB8wZ598MIgU8VpDM= +github.com/prometheus/procfs v0.3.0/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= +github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= -github.com/rs/cors v1.6.0 h1:G9tHG9lebljV9mfp9SNPDL36nCDxmo3zTlAf1YgvzmI= -github.com/rs/cors v1.6.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU= +github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= +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/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ= github.com/rs/xid v1.4.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= github.com/rs/zerolog v1.16.1-0.20191111091419-e709c5d91e35/go.mod h1:9nvC1axdVrAHcu/s9taAVfBuIdTZLVQmKQyvrUjF5+I= github.com/rs/zerolog v1.29.1 h1:cO+d60CHkknCbvzEWxP0S9K6KqyTjrCNUy1LdQLCGPc= github.com/rs/zerolog v1.29.1/go.mod h1:Le6ESbR7hc+DP6Lt1THiV8CQSdkkNrd3R0XbEgp3ZBU= github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= +github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= +github.com/samuel/go-zookeeper v0.0.0-20190923202752-2cc03de413da/go.mod h1:gi+0XIa01GRL2eRQVjQkKGqKF3SF9vZR/HnPullcV2E= github.com/sanity-io/litter v1.5.5 h1:iE+sBxPBzoK6uaEP5Lt3fHNgpKcHXc/A2HGETy0uJQo= github.com/sanity-io/litter v1.5.5/go.mod h1:9gzJgR2i4ZpjZHsKvUXIRQVk7P+yM3e+jAF7bU2UI5U= +github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= github.com/serialx/hashring v0.0.0-20190515033939-7706f26af194 h1:YWnuNx9HpWDl2VXcLw2O+va5a8Ii9AVcsqrOkTjWPas= github.com/serialx/hashring v0.0.0-20190515033939-7706f26af194/go.mod h1:/yeG0My1xr/u+HZrFQ1tOQQQQrOawfyMUH13ai5brBc= +github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= +github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= +github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= +github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= +github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= +github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= github.com/smola/gocompat v0.2.0 h1:6b1oIMlUXIpz//VKEDzPVBK8KG7beVwmHIUEBIs/Pns= github.com/smola/gocompat v0.2.0/go.mod h1:1B0MlxbmoZNo3h8guHp8HztB3BSYR5itql9qtVc0ypY= github.com/soheilhy/cmux v0.1.4 h1:0HKaf1o97UwFjHH9o5XsHUOF+tqmdA7KEzXLpiyaw0E= github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= +github.com/sony/gobreaker v0.4.1/go.mod h1:ZKptC7FHNvhBz7dN2LGjPVBz2sZJmc0/PkyDJOjmxWY= github.com/spacemonkeygo/openssl v0.0.0-20181017203307-c2dcc5cca94a/go.mod h1:7AyxJNCJ7SBZ1MfVQCWD6Uqo2oubI2Eq2y2eqf+A5r0= github.com/spacemonkeygo/spacelog v0.0.0-20180420211403-2296661a0572 h1:RC6RW7j+1+HkWaX/Yh71Ee5ZHaHYt7ZP4sQgUrm6cDU= github.com/spacemonkeygo/spacelog v0.0.0-20180420211403-2296661a0572/go.mod h1:w0SWMsp6j9O/dk4/ZpIhL+3CkG8ofA2vuv7k+ltqUMc= @@ -443,11 +642,13 @@ github.com/spf13/afero v1.1.2 h1:m8/z1t7/fwjysjQRYbP0RD+bUIF/8tJwPdEZsI83ACI= github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= github.com/spf13/cast v1.3.0 h1:oget//CVOEoFewqQxwr0Ej5yjygnqGkvggSE/gB35Q8= github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= +github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= github.com/spf13/cobra v0.0.5 h1:f0B+LkLX6DtmRH1isoNA9VTtNUK9K8xYd28JNNfOv/s= github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU= github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= github.com/spf13/jwalterweatherman v1.1.0 h1:ue6voC5bR5F8YxI5S67j9i582FU4Qvo2bmqnqMYADFk= github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo= +github.com/spf13/pflag v1.0.1/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= @@ -455,6 +656,9 @@ github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DM github.com/spf13/viper v1.5.0 h1:GpsTwfsQ27oS/Aha/6d1oD7tpKIqWnOA6tgOX9HHkt4= github.com/spf13/viper v1.5.0/go.mod h1:AkYRkVJF8TkSG/xet6PzXX+l39KhhXa2pdqVSxnTcn4= github.com/src-d/envconfig v1.0.0/go.mod h1:Q9YQZ7BKITldTBnoxsE5gOeB5y66RyPXeue/R4aaNBc= +github.com/streadway/amqp v0.0.0-20190404075320-75d898a42a94/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw= +github.com/streadway/amqp v0.0.0-20190827072141-edfb9018d271/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw= +github.com/streadway/handy v0.0.0-20190108123426-d5acb3125c2a/go.mod h1:qNTQ5P5JnDBl6z3cMAg/SywNDC5ABu5ApDIw6lUbRmI= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= @@ -464,6 +668,7 @@ github.com/stretchr/testify v0.0.0-20161117074351-18a02ba4a312/go.mod h1:a8OnRci github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= @@ -472,9 +677,16 @@ github.com/subosito/gotenv v1.2.0 h1:Slr1R9HxAlEKefgq5jn9U+DnETlIUa6HfgEzj0g5d7s github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= github.com/syndtr/goleveldb v1.0.0 h1:fBdIW9lB4Iz0n9khmH8w27SJ3QEJ7+IgjPEwGSZiFdE= github.com/syndtr/goleveldb v1.0.0/go.mod h1:ZVVdQEZoIme9iO1Ch2Jdy24qqXrMMOU6lpPAyBWyWuQ= +github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc= +github.com/ugorji/go v1.1.7 h1:/68gy2h+1mWMrwZFeD1kQialdSzAb432dtpeJ42ovdo= +github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw= github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= +github.com/ugorji/go/codec v1.1.7 h1:2SvQaVZ1ouYrrKKwoSk2pzd4A9evlKJb9oTL+OaLUSs= +github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY= +github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= +github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= github.com/whyrusleeping/go-keyspace v0.0.0-20160322163242-5b898ac5add1/go.mod h1:8UvriyWtv5Q5EOgjHaSseUEdkQfvwFv1I/In/O2M9gc= github.com/whyrusleeping/go-logging v0.0.0-20170515211332-0457bb6b88fc h1:9lDbC6Rz4bwmou+oE6Dt4Cb2BGMur5eR/GYptkKUVHo= github.com/whyrusleeping/go-logging v0.0.0-20170515211332-0457bb6b88fc/go.mod h1:bopw91TMyo8J3tvftk8xmU2kPmlrt4nScJQZU2hE5EM= @@ -497,53 +709,87 @@ github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9de github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/zenazn/goji v0.9.0/go.mod h1:7S9M489iMyHBNxwZnk9/EHS098H4/F6TATF2mIxtB1Q= go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= +go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= +go.etcd.io/etcd v0.0.0-20191023171146-3cf2f69b5738/go.mod h1:dnLIgRNXwCJa5e+c6mIZCrds/GIG4ncV9HhK5PX7jPg= +go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= +go.opencensus.io v0.20.2/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= go.opencensus.io v0.22.1/go.mod h1:Ap50jQcDJrx6rB6VgeeFPtuPIf3wMRvRfrfYDO6+BmA= +go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.5 h1:dntmOdLpSpHlVqbW5Eay97DelsZHe+55D+xC6i0dDS0= go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= +go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= +go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= +go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4= +go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA= go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= +go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM= golang.org/x/crypto v0.0.0-20170930174604-9419663f5a44/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190225124518-7f87c0fbb88b/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190426145343-a29dc8fdc734/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190513172903-22d7a77e9e5f/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190618222545-ea8f1a30c443/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190923035154-9ee001bba392/go.mod h1:/lpIB1dKB+9EgE3H3cr1v9wB50oz8l4C4h62xy7jSTY= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.11.0 h1:6Ewdq3tDic1mg5xRO4milcWCfMVQhI4NkqWWvqejpuA= -golang.org/x/crypto v0.11.0/go.mod h1:xgJhtzW8F9jGdVFWZESrid1U1bjeNy4zgy5cRr/CIio= +golang.org/x/crypto v0.14.0 h1:wBqGXzWJW6m1XrIKlAH0Hs1JJ7+9KBwnIO8v66Q9cHc= +golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20200331195152-e8c3332aa8e5/go.mod h1:4M0jN8W1tt0AVLNr8HDosyJCDCDuyL9N9+3m7wDWgKw= +golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= +golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= +golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= +golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= +golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= +golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.8.0 h1:LUYupSeNrTNCGzR/hVBk2NHZO4hXcVaW1k4Qx7rjPx8= -golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/mod v0.13.0 h1:I/DsJXRlw/8l/0c24sM9yb0T4z9liZTduXvdAWYiysY= +golang.org/x/mod v0.13.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181011144130-49bb7cea24b1/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190125091013-d26f9f9a57f3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190227160552-c95aed5357e7/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= +golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= +golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200421231249-e086a090c8fd/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.12.0 h1:cfawfvKITfUsFCeJIHJrbSxpeu/E81khclypR0GVT50= -golang.org/x/net v0.12.0/go.mod h1:zEVYFnQC7m/vmpQFELhcD1EWkZlX69l4oqgmer6hfKA= +golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM= +golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= +golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -551,72 +797,131 @@ golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.3.0 h1:ftCYgMx6zT/asHUrPw8BLLscYtGznsLAnjq5RH9P66E= -golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= +golang.org/x/sync v0.4.0 h1:zxkM55ReGkDlKSM+Fu41A+zmbZuaPVbGMzvvdUPznYQ= +golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181122145206-62eef0e2fa9b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190130150945-aca44879d564/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190219092855-153ac476189d/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190228124157-a34e9553db1e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190626221950-04f50cda93cb/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190922100055-0a153f010e69/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191008105621-543471e840be/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191220142924-d4481acd189f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200420163511-1957bb5e6d1f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.10.0 h1:SqMFp9UcQJZa+pmYuAKjd9xq1f0j5rLcDIk0mj4qAsA= -golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/term v0.10.0 h1:3R7pNqamzBraeqj/Tj8qt1aQ2HpmlC+Cx/qL/7hn4/c= -golang.org/x/term v0.10.0/go.mod h1:lpqdcUyK/oCiQxvxVrppt5ggO2KCZ5QblwqPnfZ6d5o= +golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE= +golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/term v0.13.0 h1:bb+I9cTfFazGW51MZqBVmZy7+JEJMouUHTUSKVQLBek= +golang.org/x/term v0.13.0/go.mod h1:LTmsnFJwVN6bCy1rVCoS+qHT1HhALEFxKncY3WNNh4U= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.11.0 h1:LAntKIrcmeSKERyiOh0XMV39LXS8IE9UL2yP7+f5ij4= -golang.org/x/text v0.11.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= -golang.org/x/time v0.0.0-20190308202827-9d24e82272b4 h1:SvFZT6jyqRaOeXpc5h/JSfZenJ2O330aBsf7JfSUXmQ= +golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k= +golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= +golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4= +golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20181130052023-1c3d964395ce/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190828213141-aed303cbaa74/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20200103221440-774c71fcf114/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.6.0 h1:BOw41kyTf3PuCW1pVQf8+Cyg8pMlkYB1oo9iJ6D/lKM= -golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= +golang.org/x/tools v0.14.0 h1:jvNa2pY0M4r62jkRQ6RwEZZyPcymeL9XZMLBbV7U2nc= +golang.org/x/tools v0.14.0/go.mod h1:uYBEerGOWcJyEORxN+Ek8+TT266gXkNlHdJBwexUsBg= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/api v0.3.1/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMtkk= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= +google.golang.org/appengine v1.2.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20180831171423-11092d34479b/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto/googleapis/rpc v0.0.0-20230711160842-782d3b101e98 h1:bVf09lpb+OJbByTj913DRJioFFAjf/ZGxEz7MajTp2U= -google.golang.org/genproto/googleapis/rpc v0.0.0-20230711160842-782d3b101e98/go.mod h1:TUfxEVdsvPg18p6AslUXFoLdpED4oBnGwyqk3dV1XzM= +google.golang.org/genproto v0.0.0-20190530194941-fb225487d101/go.mod h1:z3L6/3dTEVtUr6QSP8miRzeRqwQOioJ9I66odjN4I7s= +google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/genproto v0.0.0-20200423170343-7949de9c1215/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= +google.golang.org/genproto v0.0.0-20210126160654-44e461bb6506/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto/googleapis/rpc v0.0.0-20230822172742-b8732ec3820d h1:uvYuEyMHKNt+lT4K3bN6fGswmK8qSvcreM3BwjDh+y4= +google.golang.org/genproto/googleapis/rpc v0.0.0-20230822172742-b8732ec3820d/go.mod h1:+Bk1OCOj40wS2hwAMA+aCW9ypzm63QTBBHp6lQ3p+9M= +google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= +google.golang.org/grpc v1.20.0/go.mod h1:chYK+tFQF0nDUGJgXMSgLCQk3phJEuONr2DCgLDdAQM= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= -google.golang.org/grpc v1.56.2 h1:fVRFRnXvU+x6C4IlHZewvJOVHoOv1TUuQyoRsYnB4bI= -google.golang.org/grpc v1.56.2/go.mod h1:I9bI3vqKfayGqPUAwGdOSu7kt6oIJLixfffKrpXqQ9s= +google.golang.org/grpc v1.22.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= +google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= +google.golang.org/grpc v1.23.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= +google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= +google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= +google.golang.org/grpc v1.32.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= +google.golang.org/grpc v1.59.0 h1:Z5Iec2pjwb+LEOqzpB2MR12/eKFhDPhuqW91O+4bwUk= +google.golang.org/grpc v1.59.0/go.mod h1:aUPDwccQo6OTjy7Hct4AfBPD1GptF4fyUjIkQ9YtF98= google.golang.org/grpc/examples v0.0.0-20230724170852-2aa261560586 h1:3cBl7oDZlRZ9VAnaA9QglQNOY+ZP2wZJyGpiz1uuAuU= google.golang.org/grpc/examples v0.0.0-20230724170852-2aa261560586/go.mod h1:YYPcVQPFEuZQrEwqV6D//WM2s4HnWXtvFr/kII5NKbI= +google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= +google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= +google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= +google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= +google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= +google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4= +google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8= @@ -626,20 +931,34 @@ gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8 gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/cheggaaa/pb.v1 v1.0.25/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw= +gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= +gopkg.in/gcfg.v1 v1.2.3/go.mod h1:yesOnuUOFQAhST5vPY4nbZsb/huCgGGXlipJsBn0b3o= gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= gopkg.in/src-d/go-cli.v0 v0.0.0-20181105080154-d492247bbc0d/go.mod h1:z+K8VcOYVYcSwSjGebuDL6176A1XskgbtNl64NSg+n8= gopkg.in/src-d/go-log.v1 v1.0.1/go.mod h1:GN34hKP0g305ysm2/hctJ0Y8nWP3zxXXJ8GFabTyABE= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= +gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI= gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74= gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10= +gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU= +gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= +nhooyr.io/websocket v1.8.6 h1:s+C3xAMLwGmlI31Nyn/eAehUlZPwfYZu2JXM621Q5/k= +nhooyr.io/websocket v1.8.6/go.mod h1:B70DZP8IakI65RVQ51MsWP/8jndNma26DVA/nFSCgW0= +sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o= +sourcegraph.com/sourcegraph/appdash v0.0.0-20190731080439-ebfcffb1b5c0/go.mod h1:hI742Nqp5OhwiqlzhgfbWU4mW4yO10fP+LoT9WOswdU= diff --git a/internal/common/bytes.go b/internal/common/bytes.go index 93db56386..02cd2a0f9 100644 --- a/internal/common/bytes.go +++ b/internal/common/bytes.go @@ -1,10 +1,5 @@ package common -import ( - "bytes" - "encoding/gob" -) - // IsZero returns true if argument is empty or zero func IsZero(argv []byte) bool { if len(argv) == 0 { @@ -25,17 +20,3 @@ func Compactz(argv []byte) []byte { } return argv } - -// GobEncode encodes e by using gob and returns. -func GobEncode(e interface{}) ([]byte, error) { - var buf bytes.Buffer - err := gob.NewEncoder(&buf).Encode(e) - - return buf.Bytes(), err -} - -// GobDecode decodes a gob-encoded value v. -func GobDecode(v []byte, e interface{}) error { - dec := gob.NewDecoder(bytes.NewBuffer(v)) - return dec.Decode(e) -} diff --git a/internal/common/bytes_test.go b/internal/common/bytes_test.go index 0a669c416..805d0c79a 100644 --- a/internal/common/bytes_test.go +++ b/internal/common/bytes_test.go @@ -1,23 +1 @@ package common - -import ( - "testing" - - "github.com/stretchr/testify/assert" -) - -func TestGobCodec(t *testing.T) { - a := assert.New(t) - - x := []int{1, 2, 3} - b, err := GobEncode(x) - a.Nil(err) - - y := []int{0, 0, 0} - err = GobDecode(b, &y) - a.Nil(err) - - for i, v := range x { - a.Equal(v, y[i]) - } -} diff --git a/internal/enc/base58/base58.go b/internal/enc/base58/base58.go new file mode 100644 index 000000000..118016562 --- /dev/null +++ b/internal/enc/base58/base58.go @@ -0,0 +1,20 @@ +package base58 + +import ( + "github.com/mr-tron/base58/base58" +) + +// Encode returns human-readable (base58) string from b. Calling with empty or nil slice returns empty string. +func Encode(b []byte) string { + return base58.Encode(b) +} + +// Decode returns byte slice from human-readable (base58) string. Calling with empty string returns zero length string error. +func Decode(s string) ([]byte, error) { + return base58.Decode(s) +} + +func DecodeOrNil(s string) []byte { + buf, _ := Decode(s) + return buf +} diff --git a/internal/enc/bstr_test.go b/internal/enc/base58/base58_test.go similarity index 86% rename from internal/enc/bstr_test.go rename to internal/enc/base58/base58_test.go index 8ebf31c7c..dfe96e6af 100644 --- a/internal/enc/bstr_test.go +++ b/internal/enc/base58/base58_test.go @@ -1,11 +1,11 @@ -package enc +package base58 import ( "bytes" "testing" ) -func TestToString(t *testing.T) { +func TestB58Encode(t *testing.T) { type args struct { b []byte } @@ -22,13 +22,13 @@ func TestToString(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - got := ToString(tt.args.b) + got := Encode(tt.args.b) if got != tt.want { t.Errorf("ToString() = %v, want %v", got, tt.want) } if tt.wantInverse { - got2, err := ToBytes(got) + got2, err := Decode(got) if err != nil { t.Errorf("ToBytes() = %s, want no err", err.Error()) } diff --git a/internal/enc/base58check/base58check.go b/internal/enc/base58check/base58check.go new file mode 100644 index 000000000..9233721c6 --- /dev/null +++ b/internal/enc/base58check/base58check.go @@ -0,0 +1,23 @@ +package base58check + +import ( + "github.com/anaskhan96/base58check" +) + +func Encode(version string, data string) (string, error) { + return base58check.Encode(version, data) +} + +func EncodeOrNil(version string, data string) string { + buf, _ := Encode(version, data) + return buf +} + +func Decode(encoded string) (string, error) { + return base58check.Decode(encoded) +} + +func DecodeOrNil(encoded string) string { + buf, _ := Decode(encoded) + return buf +} diff --git a/internal/enc/base58check/base58check_test.go b/internal/enc/base58check/base58check_test.go new file mode 100644 index 000000000..dc8e9ac10 --- /dev/null +++ b/internal/enc/base58check/base58check_test.go @@ -0,0 +1,31 @@ +package base58check + +import ( + "testing" + + "github.com/aergoio/aergo/v2/internal/enc/hex" + "github.com/stretchr/testify/require" +) + +func TestB58CheckEncode(t *testing.T) { + for _, test := range []struct { + name string + version string + data string + expect string + }{ + {"T1", hex.Encode([]byte{0}), hex.Encode([]byte("Hello")), "1vSxRbq6DSYXc"}, + {"T2", hex.Encode([]byte{1}), hex.Encode([]byte("Hello")), "5BShidwAu2ieX"}, + {"T3", hex.Encode([]byte{5}), hex.Encode([]byte("abcdefghijklmnopqrstuvwxyz1234567890")), "2BSSzM1LQHgVeyiCPn5bEfgWY3HmiC3cbjGYFhTs1bVv5GTT7nJ8ajSE"}, + } { + t.Run(test.name, func(t *testing.T) { + got, err := Encode(test.version, test.data) + require.NoErrorf(t, err, "B58CheckEncode() error = %v", err) + require.Equalf(t, test.expect, got, "B58CheckEncode() = %v, want %v", got, test.expect) + + recover, err := Decode(got) + require.NoErrorf(t, err, "B58CheckDecode() error = %v", err) + require.Equalf(t, test.version+test.data, recover, "B58CheckDecode() = %v, want %v", recover, test.version+test.data) + }) + } +} diff --git a/internal/enc/base64/base64.go b/internal/enc/base64/base64.go new file mode 100644 index 000000000..999484323 --- /dev/null +++ b/internal/enc/base64/base64.go @@ -0,0 +1,17 @@ +package base64 + +import "encoding/base64" + +func Encode(s []byte) string { + return base64.StdEncoding.EncodeToString(s) +} + +func Decode(s string) ([]byte, error) { + return base64.StdEncoding.DecodeString(s) +} + +// Do not use processing real data, Only use for Logging or Testing. +func DecodeOrNil(s string) []byte { + buf, _ := Decode(s) + return buf +} diff --git a/internal/enc/bstr.go b/internal/enc/bstr.go deleted file mode 100644 index f5230cc56..000000000 --- a/internal/enc/bstr.go +++ /dev/null @@ -1,13 +0,0 @@ -package enc - -import "github.com/mr-tron/base58/base58" - -// ToString returns human-readable (base58) string from b. Calling with empty or nil slice returns empty string. -func ToString(b []byte) string { - return base58.Encode(b) -} - -// ToBytes returns byte slice from human-readable (base58) string. Calling with empty string returns zero length string error. -func ToBytes(s string) ([]byte, error) { - return base58.Decode(s) -} diff --git a/internal/enc/gob/gob.go b/internal/enc/gob/gob.go new file mode 100644 index 000000000..be2baa1c5 --- /dev/null +++ b/internal/enc/gob/gob.go @@ -0,0 +1,22 @@ +package gob + +import ( + "bytes" + "encoding/gob" +) + +// Encode encodes e by using gob and returns. +func Encode(e interface{}) ([]byte, error) { + var buf bytes.Buffer + err := gob.NewEncoder(&buf).Encode(e) + if err != nil { + return nil, err + } + return buf.Bytes(), nil +} + +// Decode decodes a gob-encoded value v. +func Decode(v []byte, e interface{}) error { + dec := gob.NewDecoder(bytes.NewBuffer(v)) + return dec.Decode(e) +} diff --git a/internal/enc/gob/gob_test.go b/internal/enc/gob/gob_test.go new file mode 100644 index 000000000..b4300cabc --- /dev/null +++ b/internal/enc/gob/gob_test.go @@ -0,0 +1,23 @@ +package gob + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestGobCodec(t *testing.T) { + a := assert.New(t) + + x := []int{1, 2, 3} + b, err := Encode(x) + a.Nil(err) + + y := []int{0, 0, 0} + err = Decode(b, &y) + a.Nil(err) + + for i, v := range x { + a.Equal(v, y[i]) + } +} diff --git a/internal/enc/hex/hex.go b/internal/enc/hex/hex.go new file mode 100644 index 000000000..6c484ee4d --- /dev/null +++ b/internal/enc/hex/hex.go @@ -0,0 +1,11 @@ +package hex + +import "encoding/hex" + +func Encode(b []byte) string { + return hex.EncodeToString(b) +} + +func Decode(s string) ([]byte, error) { + return hex.DecodeString(s) +} diff --git a/internal/enc/proto/proto.go b/internal/enc/proto/proto.go new file mode 100644 index 000000000..c8d41984f --- /dev/null +++ b/internal/enc/proto/proto.go @@ -0,0 +1,29 @@ +package proto + +import ( + "github.com/golang/protobuf/proto" +) + +type Message = proto.Message + +// Encode encodes e by using gob and returns. +func Encode(m proto.Message) ([]byte, error) { + return proto.Marshal(m) +} + +// Decode decodes a gob-encoded value v. +func Decode(v []byte, m proto.Message) error { + return proto.Unmarshal(v, m) +} + +func Size(m proto.Message) int { + return proto.Size(m) +} + +func Equal(m1, m2 proto.Message) bool { + return proto.Equal(m1, m2) +} + +func Clone(m proto.Message) proto.Message { + return proto.Clone(m) +} diff --git a/internal/merkle/merkle_test.go b/internal/merkle/merkle_test.go index 56d1c477f..7a8d0a68c 100644 --- a/internal/merkle/merkle_test.go +++ b/internal/merkle/merkle_test.go @@ -2,13 +2,12 @@ package merkle import ( "bytes" - "encoding/base64" "encoding/binary" "hash" "testing" + "github.com/aergoio/aergo/v2/internal/enc/base64" "github.com/minio/sha256-simd" - "github.com/mr-tron/base58/base58" "github.com/stretchr/testify/assert" ) @@ -16,14 +15,6 @@ var ( tms []MerkleEntry ) -func EncodeB64(bs []byte) string { - return base64.StdEncoding.EncodeToString(bs) -} - -func EncodeB58(bs []byte) string { - return base58.Encode(bs) -} - func beforeTest(count int) error { tms = make([]MerkleEntry, count) @@ -100,7 +91,7 @@ func TestMerkle2Tx(t *testing.T) { for i, merkle := range merkles { assert.Equal(t, len(merkle), 32) - t.Logf("%d:%v", i, EncodeB64(merkle)) + t.Logf("%d:%v", i, base64.Encode(merkle)) } } @@ -123,7 +114,7 @@ func TestMerkle3Tx(t *testing.T) { for i, merkle := range merkles { assert.NotNil(t, merkle, "nil=%d", i) assert.Equal(t, len(merkle), 32) - t.Logf("%d:%v", i, EncodeB64(merkle)) + t.Logf("%d:%v", i, base64.Encode(merkle)) } } diff --git a/mempool/mempool.go b/mempool/mempool.go index 64bc9219f..f99c05dcf 100644 --- a/mempool/mempool.go +++ b/mempool/mempool.go @@ -28,12 +28,12 @@ import ( "github.com/aergoio/aergo/v2/contract/system" "github.com/aergoio/aergo/v2/fee" "github.com/aergoio/aergo/v2/internal/common" - "github.com/aergoio/aergo/v2/internal/enc" + "github.com/aergoio/aergo/v2/internal/enc/base58" + "github.com/aergoio/aergo/v2/internal/enc/proto" "github.com/aergoio/aergo/v2/message" "github.com/aergoio/aergo/v2/pkg/component" "github.com/aergoio/aergo/v2/state" "github.com/aergoio/aergo/v2/types" - "github.com/golang/protobuf/proto" ) const ( @@ -252,7 +252,7 @@ func (mp *MemPool) Receive(context actor.Context) { Err: errs, }) case *message.MemPoolDelTx: - mp.Info().Str("txhash", enc.ToString(msg.Tx.GetHash())).Msg("remove tx in mempool") + mp.Info().Str("txhash", base58.Encode(msg.Tx.GetHash())).Msg("remove tx in mempool") err := mp.removeTx(msg.Tx) context.Respond(&message.MemPoolDelTxRsp{ Err: err, @@ -451,8 +451,8 @@ func (mp *MemPool) setStateDB(block *types.Block) (bool, bool) { } mp.Debug().Str("Hash", newBlockID.String()). Str("StateRoot", types.ToHashID(stateRoot).String()). - Str("chainidhash", enc.ToString(mp.bestChainIdHash)). - Str("next chainidhash", enc.ToString(mp.acceptChainIdHash)). + Str("chainidhash", base58.Encode(mp.bestChainIdHash)). + Str("next chainidhash", base58.Encode(mp.acceptChainIdHash)). Msg("new StateDB opened") } else if !bytes.Equal(mp.stateDB.GetRoot(), stateRoot) { if err := mp.stateDB.SetRoot(stateRoot); err != nil { @@ -676,15 +676,11 @@ func (mp *MemPool) validateTx(tx types.Transaction, account types.Address) error return err } case types.AergoName: - systemcs, err := mp.stateDB.GetSystemAccountState() - if err != nil { - return err - } sender, err := mp.stateDB.GetAccountStateV(account) if err != nil { return err } - if _, err := name.ValidateNameTx(tx.GetBody(), sender, scs, systemcs); err != nil { + if _, err := name.ValidateNameTx(tx.GetBody(), sender, scs); err != nil { return err } case types.AergoEnterprise: @@ -717,14 +713,10 @@ func (mp *MemPool) validateTx(tx types.Transaction, account types.Address) error if err != nil { return err } - bal := aergoState.GetBalanceBigInt() - fee, err := tx.GetMaxFee(bal, system.GetGasPrice(), mp.nextBlockVersion()) + err = tx.ValidateMaxFee(aergoState.GetBalanceBigInt(), system.GetGasPrice(), mp.nextBlockVersion()) if err != nil { return err } - if fee.Cmp(bal) > 0 { - return types.ErrInsufficientBalance - } txBody := tx.GetBody() rsp, err := mp.RequestToFuture(message.ChainSvc, &message.CheckFeeDelegation{Payload: txBody.GetPayload(), Contract: recipient, @@ -805,7 +797,7 @@ func (mp *MemPool) getAccountState(acc []byte) (*types.State, error) { state, err := mp.stateDB.GetAccountState(types.ToAccountID(acc)) if err != nil { - mp.Fatal().Err(err).Str("sroot", enc.ToString(mp.stateDB.GetRoot())).Msg("failed to get state") + mp.Fatal().Err(err).Str("sroot", base58.Encode(mp.stateDB.GetRoot())).Msg("failed to get state") //FIXME PANIC? //mp.Fatal().Err(err).Msg("failed to get state") @@ -877,7 +869,7 @@ func (mp *MemPool) loadTxs() { break } - err = proto.Unmarshal(buffer, &buf) + err = proto.Decode(buffer, &buf) if err != nil { mp.Error().Err(err).Msg("errr on unmarshalling tx during loading") continue @@ -920,7 +912,7 @@ Dump: var total_data []byte start := time.Now() - data, err := proto.Marshal(v.GetTx()) + data, err := proto.Encode(v.GetTx()) if err != nil { mp.Error().Err(err).Msg("Marshal failed") continue @@ -963,7 +955,7 @@ func (mp *MemPool) removeTx(tx *types.Tx) error { defer mp.Unlock() if mp.exist(tx.GetHash()) == nil { - mp.Warn().Str("txhash", enc.ToString(tx.GetHash())).Msg("could not find tx to remove") + mp.Warn().Str("txhash", base58.Encode(tx.GetHash())).Msg("could not find tx to remove") return types.ErrTxNotFound } acc := tx.GetBody().GetAccount() @@ -973,7 +965,7 @@ func (mp *MemPool) removeTx(tx *types.Tx) error { } newOrphan, removed := list.RemoveTx(tx) if removed == nil { - mp.Error().Str("txhash", enc.ToString(tx.GetHash())).Msg("already removed tx") + mp.Error().Str("txhash", base58.Encode(tx.GetHash())).Msg("already removed tx") } mp.orphan += newOrphan mp.releaseMemPoolList(list) diff --git a/mempool/txverifier.go b/mempool/txverifier.go index 76f3e9745..4380692ad 100644 --- a/mempool/txverifier.go +++ b/mempool/txverifier.go @@ -2,7 +2,7 @@ package mempool import ( "github.com/aergoio/aergo-actor/actor" - "github.com/aergoio/aergo/v2/internal/enc" + "github.com/aergoio/aergo/v2/internal/enc/base58" "github.com/aergoio/aergo/v2/message" "github.com/aergoio/aergo/v2/types" ) @@ -31,7 +31,7 @@ func (s *TxVerifier) Receive(context actor.Context) { err = s.mp.put(tx) } if err != nil { - s.mp.Logger.Info().Err(err).Str("txID", enc.ToString(msg.GetHash())).Msg("tx verification failed") + s.mp.Logger.Info().Err(err).Str("txID", base58.Encode(msg.GetHash())).Msg("tx verification failed") } } context.Respond(&message.MemPoolPutRsp{Err: err}) diff --git a/p2p/actorwork.go b/p2p/actorwork.go index 84343c4bc..d7075b696 100644 --- a/p2p/actorwork.go +++ b/p2p/actorwork.go @@ -11,7 +11,7 @@ import ( "time" "github.com/aergoio/aergo-actor/actor" - "github.com/aergoio/aergo/v2/internal/enc" + "github.com/aergoio/aergo/v2/internal/enc/base58" "github.com/aergoio/aergo/v2/message" "github.com/aergoio/aergo/v2/p2p/p2pcommon" "github.com/aergoio/aergo/v2/p2p/p2putil" @@ -141,7 +141,7 @@ func (p2ps *P2P) NotifyNewBlock(blockNotice message.NotifyNewBlock) bool { } } - p2ps.Debug().Int("skipped_cnt", skipped).Int("sent_cnt", sent).Str("hash", enc.ToString(blockNotice.Block.BlockHash())).Msg("Notifying new block") + p2ps.Debug().Int("skipped_cnt", skipped).Int("sent_cnt", sent).Str("hash", base58.Encode(blockNotice.Block.BlockHash())).Msg("Notifying new block") return true } @@ -162,7 +162,7 @@ func (p2ps *P2P) NotifyBlockProduced(blockNotice message.NotifyNewBlock) bool { } } - p2ps.Debug().Int("skipped_cnt", skipped).Int("sent_cnt", sent).Str("hash", enc.ToString(blockNotice.Block.BlockHash())).Uint64("block_no", req.BlockNo).Msg("Notifying block produced") + p2ps.Debug().Int("skipped_cnt", skipped).Int("sent_cnt", sent).Str("hash", base58.Encode(blockNotice.Block.BlockHash())).Uint64("block_no", req.BlockNo).Msg("Notifying block produced") return true } diff --git a/p2p/const_test.go b/p2p/const_test.go index b126be5c8..0d53fdbcf 100644 --- a/p2p/const_test.go +++ b/p2p/const_test.go @@ -7,13 +7,13 @@ package p2p import ( "bytes" - "encoding/base64" - "encoding/hex" "fmt" "testing" "github.com/aergoio/aergo-lib/log" - "github.com/aergoio/aergo/v2/internal/enc" + "github.com/aergoio/aergo/v2/internal/enc/base58" + "github.com/aergoio/aergo/v2/internal/enc/base64" + "github.com/aergoio/aergo/v2/internal/enc/hex" "github.com/aergoio/aergo/v2/p2p/p2pcommon" "github.com/aergoio/aergo/v2/p2p/p2pmock" "github.com/aergoio/aergo/v2/types" @@ -23,9 +23,9 @@ import ( // this file collect sample global constants used in unit test. I'm tired of creating less meaningful variables in each tests. -var dummyBlockHash, _ = hex.DecodeString("4f461d85e869ade8a0544f8313987c33a9c06534e50c4ad941498299579bd7ac") +var dummyBlockHash, _ = hex.Decode("4f461d85e869ade8a0544f8313987c33a9c06534e50c4ad941498299579bd7ac") var dummyBlockHeight uint64 = 100215 -var dummyTxHash, _ = enc.ToBytes("4H4zAkAyRV253K5SNBJtBxqUgHEbZcXbWFFc6cmQHY45") +var dummyTxHash, _ = base58.Decode("4H4zAkAyRV253K5SNBJtBxqUgHEbZcXbWFFc6cmQHY45") var samplePeerID types.PeerID var sampleMeta p2pcommon.PeerMeta @@ -67,9 +67,9 @@ var dummyBestBlock *types.Block var dummyMeta p2pcommon.PeerMeta func init() { - bytes, _ := base64.StdEncoding.DecodeString(sampleKey1PrivBase64) + bytes, _ := base64.Decode(sampleKey1PrivBase64) sampleKey1Priv, _ = crypto.UnmarshalPrivateKey(bytes) - bytes, _ = base64.StdEncoding.DecodeString(sampelKey1PubBase64) + bytes, _ = base64.Decode(sampelKey1PubBase64) sampleKey1Pub, _ = crypto.UnmarshalPublicKey(bytes) if !sampleKey1Priv.GetPublic().Equals(sampleKey1Pub) { panic("problem in pk generation ") @@ -79,7 +79,7 @@ func init() { panic("problem in id generation") } - bytes, _ = base64.StdEncoding.DecodeString(sampleKey2PrivBase64) + bytes, _ = base64.Decode(sampleKey2PrivBase64) sampleKey2Priv, _ = crypto.UnmarshalPrivateKey(bytes) sampleKey2Pub = sampleKey2Priv.GetPublic() sampleKey2ID, _ = types.IDFromPublicKey(sampleKey2Pub) @@ -121,7 +121,7 @@ func init() { sampleTxs = make([][]byte, len(sampleTxsB58)) sampleTxIDs = make([]types.TxID, len(sampleTxsB58)) for i, hashb58 := range sampleTxsB58 { - hash, _ := enc.ToBytes(hashb58) + hash, _ := base58.Decode(hashb58) sampleTxs[i] = hash copy(sampleTxIDs[i][:], hash) } @@ -129,7 +129,7 @@ func init() { sampleBlks = make([][]byte, len(sampleBlksB58)) sampleBlksIDs = make([]types.BlockID, len(sampleBlksB58)) for i, hashb58 := range sampleTxsB58 { - hash, _ := enc.ToBytes(hashb58) + hash, _ := base58.Decode(hashb58) sampleBlks[i] = hash copy(sampleBlksIDs[i][:], hash) } @@ -149,7 +149,7 @@ func createDummyMo(ctrl *gomock.Controller) *p2pmock.MockMsgOrder { func TestTXIDs(t *testing.T) { for i := 0; i < len(sampleTxIDs); i++ { if !bytes.Equal(sampleTxs[i], sampleTxIDs[i][:]) { - t.Errorf("TX hash %v and converted ID %v are differ.", enc.ToString(sampleTxs[i]), sampleTxIDs[i]) + t.Errorf("TX hash %v and converted ID %v are differ.", base58.Encode(sampleTxs[i]), sampleTxIDs[i]) } } } @@ -157,7 +157,7 @@ func TestTXIDs(t *testing.T) { func TestBlockIDs(t *testing.T) { for i := 0; i < len(sampleBlksIDs); i++ { if !bytes.Equal(sampleBlks[i], sampleBlksIDs[i][:]) { - t.Errorf("TX hash %v and converted ID %v are differ.", enc.ToString(sampleBlks[i]), sampleBlksIDs[i]) + t.Errorf("TX hash %v and converted ID %v are differ.", base58.Encode(sampleBlks[i]), sampleBlksIDs[i]) } } } @@ -267,12 +267,12 @@ var testIn = []string{ func TestMoreTXIDs(t *testing.T) { for _, in := range testIn { - hash, _ := enc.ToBytes(in) + hash, _ := base58.Decode(in) id, err := types.ParseToTxID(hash) if err != nil { - t.Errorf("Failed to parse TX hash %v : %v", enc.ToString(hash), err) + t.Errorf("Failed to parse TX hash %v : %v", base58.Encode(hash), err) } else if !bytes.Equal(hash, id[:]) { - t.Errorf("TX hash %v and converted ID %v are differ.", enc.ToString(hash), id) + t.Errorf("TX hash %v and converted ID %v are differ.", base58.Encode(hash), id) } } } diff --git a/p2p/hashreceiver_test.go b/p2p/hashreceiver_test.go index ecda5f4e4..bd69d0a84 100644 --- a/p2p/hashreceiver_test.go +++ b/p2p/hashreceiver_test.go @@ -10,7 +10,7 @@ import ( "time" "github.com/aergoio/aergo/v2/chain" - "github.com/aergoio/aergo/v2/internal/enc" + "github.com/aergoio/aergo/v2/internal/enc/base58" "github.com/aergoio/aergo/v2/message" "github.com/aergoio/aergo/v2/p2p/p2pcommon" "github.com/aergoio/aergo/v2/p2p/p2pmock" @@ -120,7 +120,7 @@ func TestBlockHashesReceiver_ReceiveResp(t *testing.T) { for _, h := range arg.Hashes { _, err := types.ParseToBlockID(h) if err != nil { - t.Fatalf("Wrong block hash %s, err %v)", enc.ToString(h), err.Error()) + t.Fatalf("Wrong block hash %s, err %v)", base58.Encode(h), err.Error()) } } } diff --git a/p2p/msgorder.go b/p2p/msgorder.go index 5a62a9b84..6c3f255be 100644 --- a/p2p/msgorder.go +++ b/p2p/msgorder.go @@ -9,7 +9,7 @@ import ( "time" "github.com/aergoio/aergo/v2/consensus" - "github.com/aergoio/aergo/v2/internal/enc" + "github.com/aergoio/aergo/v2/internal/enc/base58" "github.com/aergoio/aergo/v2/p2p/p2pcommon" "github.com/aergoio/aergo/v2/p2p/p2putil" "github.com/aergoio/aergo/v2/p2p/raftsupport" @@ -169,7 +169,7 @@ func (pr *pbBpNoticeOrder) SendTo(pi p2pcommon.RemotePeer) error { } if pr.trace { p.logger.Debug().Str(p2putil.LogPeerName, p.Name()).Stringer(p2putil.LogProtoID, pr.GetProtocolID()). - Str(p2putil.LogMsgID, pr.GetMsgID().String()).Str(p2putil.LogBlkHash, enc.ToString(pr.block.Hash)).Msg("Notify block produced") + Str(p2putil.LogMsgID, pr.GetMsgID().String()).Str(p2putil.LogBlkHash, base58.Encode(pr.block.Hash)).Msg("Notify block produced") } return nil } diff --git a/p2p/p2pcommon/message.go b/p2p/p2pcommon/message.go index 5fb0c6e42..9904ee383 100644 --- a/p2p/p2pcommon/message.go +++ b/p2p/p2pcommon/message.go @@ -9,8 +9,8 @@ package p2pcommon import ( "time" + "github.com/aergoio/aergo/v2/internal/enc/proto" "github.com/aergoio/aergo/v2/types" - "github.com/golang/protobuf/proto" ) // Message is unit structure transferred from a peer to another peer. diff --git a/p2p/p2pkey/nodekey.go b/p2p/p2pkey/nodekey.go index 90dd90d16..9190c0faa 100644 --- a/p2p/p2pkey/nodekey.go +++ b/p2p/p2pkey/nodekey.go @@ -12,7 +12,7 @@ import ( "github.com/aergoio/aergo-lib/log" "github.com/aergoio/aergo/v2/config" - "github.com/aergoio/aergo/v2/internal/enc" + "github.com/aergoio/aergo/v2/internal/enc/base58" "github.com/aergoio/aergo/v2/p2p/p2pcommon" "github.com/aergoio/aergo/v2/p2p/p2putil" "github.com/aergoio/aergo/v2/types" @@ -72,7 +72,7 @@ func InitNodeInfo(baseCfg *config.BaseConfig, p2pCfg *config.P2PConfig, version ni = &nodeInfo{ id: id, - sid: enc.ToString([]byte(id)), + sid: base58.Encode([]byte(id)), pubKey: pub, privKey: priv, version: version, diff --git a/p2p/p2putil/PKTest_test.go b/p2p/p2putil/PKTest_test.go index 8a7a17477..6cb233c70 100644 --- a/p2p/p2putil/PKTest_test.go +++ b/p2p/p2putil/PKTest_test.go @@ -1,9 +1,9 @@ package p2putil import ( - "encoding/hex" "testing" + "github.com/aergoio/aergo/v2/internal/enc/hex" "github.com/btcsuite/btcd/btcec" "github.com/libp2p/go-libp2p-core/crypto" ) @@ -26,15 +26,15 @@ func PrintLibP2PKey(priv crypto.Key, marshaled []byte, t *testing.T) { if err != nil { t.Errorf("Failed to get bytes: %v", err.Error()) } else { - t.Logf("BT/MAR %v", hex.EncodeToString(oldBytes)) - t.Logf("RAW %v", hex.EncodeToString(newBytes)) + t.Logf("BT/MAR %v", hex.Encode(oldBytes)) + t.Logf("RAW %v", hex.Encode(newBytes)) } } func PrintBTCPKey(priv *btcec.PrivateKey, t *testing.T) { oldBytes := priv.Serialize() - t.Logf("PRIV %v", hex.EncodeToString(oldBytes)) - t.Logf("PUBLIC %v", hex.EncodeToString(priv.PubKey().SerializeCompressed())) + t.Logf("PRIV %v", hex.Encode(oldBytes)) + t.Logf("PUBLIC %v", hex.Encode(priv.PubKey().SerializeCompressed())) } func TestLibs(t *testing.T) { diff --git a/p2p/p2putil/certificate_test.go b/p2p/p2putil/certificate_test.go index 11d58d261..edfb2701c 100644 --- a/p2p/p2putil/certificate_test.go +++ b/p2p/p2putil/certificate_test.go @@ -6,11 +6,11 @@ import ( "testing" "time" - "github.com/aergoio/aergo/v2/internal/enc" + "github.com/aergoio/aergo/v2/internal/enc/base58" + "github.com/aergoio/aergo/v2/internal/enc/proto" "github.com/aergoio/aergo/v2/p2p/p2pcommon" "github.com/aergoio/aergo/v2/types" "github.com/btcsuite/btcd/btcec" - "github.com/golang/protobuf/proto" ) func TestNewAgentCertV1(t *testing.T) { @@ -51,7 +51,7 @@ func TestNewAgentCertV1(t *testing.T) { t.Errorf("NewAgentCertV1() bpID = %v, want %v", got.AgentID, tt.args.agentID) } if !got.BPPubKey.IsEqual(tt.args.bpKey.PubKey()) { - t.Errorf("NewAgentCertV1() pubKey = %v, want %v", enc.ToString(got.BPPubKey.SerializeCompressed()), enc.ToString(tt.args.bpKey.PubKey().SerializeCompressed())) + t.Errorf("NewAgentCertV1() pubKey = %v, want %v", base58.Encode(got.BPPubKey.SerializeCompressed()), base58.Encode(tt.args.bpKey.PubKey().SerializeCompressed())) } if !types.IsSamePeerID(got.BPID, tt.args.bpID) { t.Errorf("NewAgentCertV1() bpID = %v, want %v", got.BPID, tt.args.bpID) @@ -258,7 +258,7 @@ func Test_calculateCertificateHash(t *testing.T) { } if !bytes.Equal(h1, h11) { - t.Fatalf("calculated hash is differ! %v , want %v ", enc.ToString(h11), enc.ToString(h1)) + t.Fatalf("calculated hash is differ! %v , want %v ", base58.Encode(h11), base58.Encode(h1)) } h2, err := calculateCertificateHash(w2) if err != nil { @@ -266,7 +266,7 @@ func Test_calculateCertificateHash(t *testing.T) { } if bytes.Equal(h1, h2) { - t.Fatalf("calculated hash is same! %v , want different ", enc.ToString(h2)) + t.Fatalf("calculated hash is same! %v , want different ", base58.Encode(h2)) } } diff --git a/p2p/p2putil/cryptoutil_test.go b/p2p/p2putil/cryptoutil_test.go index c09b3cc7d..07e192f99 100644 --- a/p2p/p2putil/cryptoutil_test.go +++ b/p2p/p2putil/cryptoutil_test.go @@ -2,9 +2,9 @@ package p2putil import ( "bytes" - "encoding/hex" "testing" + "github.com/aergoio/aergo/v2/internal/enc/hex" "github.com/btcsuite/btcd/btcec" "github.com/libp2p/go-libp2p-core/crypto" ) @@ -27,11 +27,11 @@ func TestConvertPKToLibP2P(t *testing.T) { } raw, err := got.Raw() if !bytes.Equal(raw, btcPK.Serialize()) { - t.Errorf("ConvertPKToLibP2P() pk = %v, want %v", hex.EncodeToString(raw), hex.EncodeToString(btcPK.Serialize())) + t.Errorf("ConvertPKToLibP2P() pk = %v, want %v", hex.Encode(raw), hex.Encode(btcPK.Serialize())) } rev := ConvertPKToBTCEC(got) if !bytes.Equal(rev.Serialize(), btcPK.Serialize()) { - t.Errorf("ConvertPKToBTCEC() pk = %v, want %v", hex.EncodeToString(rev.Serialize()), hex.EncodeToString(btcPK.Serialize())) + t.Errorf("ConvertPKToBTCEC() pk = %v, want %v", hex.Encode(rev.Serialize()), hex.Encode(btcPK.Serialize())) } marshaled, err := crypto.MarshalPrivateKey(got) @@ -68,11 +68,11 @@ func TestConvertPubKeyToLibP2P(t *testing.T) { } raw, err := got.Raw() if !bytes.Equal(raw, pubKey.SerializeCompressed()) { - t.Errorf("ConvertPubToLibP2P() pk = %v, want %v", hex.EncodeToString(raw), hex.EncodeToString(pubKey.SerializeCompressed())) + t.Errorf("ConvertPubToLibP2P() pk = %v, want %v", hex.Encode(raw), hex.Encode(pubKey.SerializeCompressed())) } rev := ConvertPubKeyToBTCEC(got) if !bytes.Equal(rev.SerializeCompressed(), pubKey.SerializeCompressed()) { - t.Errorf("ConvertPubKeyToBTCEC() pk = %v, want %v", hex.EncodeToString(rev.SerializeCompressed()), hex.EncodeToString(pubKey.SerializeCompressed())) + t.Errorf("ConvertPubKeyToBTCEC() pk = %v, want %v", hex.Encode(rev.SerializeCompressed()), hex.Encode(pubKey.SerializeCompressed())) } }) } diff --git a/p2p/p2putil/protobuf.go b/p2p/p2putil/protobuf.go index 8faf2953a..9a11334bd 100644 --- a/p2p/p2putil/protobuf.go +++ b/p2p/p2putil/protobuf.go @@ -6,8 +6,8 @@ package p2putil import ( + "github.com/aergoio/aergo/v2/internal/enc/proto" "github.com/aergoio/aergo/v2/p2p/p2pcommon" - "github.com/golang/protobuf/proto" ) func CalculateFieldDescSize(varSize int) int { @@ -30,13 +30,13 @@ func CalculateFieldDescSize(varSize int) int { } func MarshalMessageBody(message p2pcommon.MessageBody) ([]byte, error) { - return proto.Marshal(message) + return proto.Encode(message) } func UnmarshalMessageBody(data []byte, msgData p2pcommon.MessageBody) error { - return proto.Unmarshal(data, msgData) + return proto.Decode(data, msgData) } func UnmarshalAndReturn(data []byte, msgData p2pcommon.MessageBody) (p2pcommon.MessageBody, error) { - return msgData, proto.Unmarshal(data, msgData) + return msgData, proto.Decode(data, msgData) } diff --git a/p2p/p2putil/protobuf_test.go b/p2p/p2putil/protobuf_test.go index cc3e10d04..2e918e44a 100644 --- a/p2p/p2putil/protobuf_test.go +++ b/p2p/p2putil/protobuf_test.go @@ -9,22 +9,22 @@ import ( "fmt" "testing" - "github.com/aergoio/aergo/v2/internal/enc" + "github.com/aergoio/aergo/v2/internal/enc/base58" + "github.com/aergoio/aergo/v2/internal/enc/proto" "github.com/aergoio/aergo/v2/types" - "github.com/golang/protobuf/proto" "github.com/stretchr/testify/assert" ) -var dummyTxHash, _ = enc.ToBytes("4H4zAkAyRV253K5SNBJtBxqUgHEbZcXbWFFc6cmQHY45") +var dummyTxHash, _ = base58.Decode("4H4zAkAyRV253K5SNBJtBxqUgHEbZcXbWFFc6cmQHY45") func Test_MarshalTxResp(t *testing.T) { dummyTx := &types.Tx{Hash: dummyTxHash, Body: &types.TxBody{Payload: []byte("It's a good day to die.")}} - txMarshaled, _ := proto.Marshal(dummyTx) + txMarshaled, _ := proto.Encode(dummyTx) txSize := len(dummyTxHash) + 2 + len(txMarshaled) + 2 // hash+ field desc of hash + tx+field desc of tx - //fmt.Println("TX : ",hex.EncodeToString(txMarshaled)) - emptyMarshaled, _ := proto.Marshal(&types.GetTransactionsResponse{}) + //fmt.Println("TX : ",hex.HexEncode(txMarshaled)) + emptyMarshaled, _ := proto.Encode(&types.GetTransactionsResponse{}) emptySize := len(emptyMarshaled) - //fmt.Println("EMPTY: ",hex.EncodeToString(emptyMarshaled)) + //fmt.Println("EMPTY: ",hex.HexEncode(emptyMarshaled)) //fmt.Printf("Size of All nil: %d , tx size: %d ",emptySize, txSize) tests := []struct { name string @@ -50,7 +50,7 @@ func Test_MarshalTxResp(t *testing.T) { txSlice = append(txSlice, dummyTx) } sampleRsp := &types.GetTransactionsResponse{Hashes: hashSlice, Txs: txSlice} - actual, err := proto.Marshal(sampleRsp) + actual, err := proto.Encode(sampleRsp) if err != nil { t.Errorf("Invalid proto error %s", err.Error()) } @@ -59,7 +59,7 @@ func Test_MarshalTxResp(t *testing.T) { if actualSize < cut { cut = actualSize } - //fmt.Println("ACTUAL: ",hex.EncodeToString(actual[:cut])) + //fmt.Println("ACTUAL: ",hex.HexEncode(actual[:cut])) assert.Equal(t, test.expectedSize, actualSize) diff --git a/p2p/p2putil/util.go b/p2p/p2putil/util.go index 539378821..8eed9bf9a 100644 --- a/p2p/p2putil/util.go +++ b/p2p/p2putil/util.go @@ -13,7 +13,7 @@ import ( "strconv" "strings" - "github.com/aergoio/aergo/v2/internal/enc" + "github.com/aergoio/aergo/v2/internal/enc/base58" "github.com/aergoio/aergo/v2/message" "github.com/aergoio/aergo/v2/types" "github.com/gofrs/uuid" @@ -186,9 +186,9 @@ func PrintHashList(blocks []*types.Block) string { case 0: return "blk_cnt=0" case 1: - return fmt.Sprintf("blk_cnt=1,hash=%s(num %d)", enc.ToString(blocks[0].Hash), blocks[0].Header.BlockNo) + return fmt.Sprintf("blk_cnt=1,hash=%s(num %d)", base58.Encode(blocks[0].Hash), blocks[0].Header.BlockNo) default: - return fmt.Sprintf("blk_cnt=%d,firstHash=%s(num %d),lastHash=%s(num %d)", l, enc.ToString(blocks[0].Hash), blocks[0].Header.BlockNo, enc.ToString(blocks[l-1].Hash), blocks[l-1].Header.BlockNo) + return fmt.Sprintf("blk_cnt=%d,firstHash=%s(num %d),lastHash=%s(num %d)", l, base58.Encode(blocks[0].Hash), blocks[0].Header.BlockNo, base58.Encode(blocks[l-1].Hash), blocks[l-1].Header.BlockNo) } } diff --git a/p2p/p2putil/util_test.go b/p2p/p2putil/util_test.go index b077f1efe..e52b46fce 100644 --- a/p2p/p2putil/util_test.go +++ b/p2p/p2putil/util_test.go @@ -16,7 +16,7 @@ import ( "testing" "time" - "github.com/aergoio/aergo/v2/internal/enc" + "github.com/aergoio/aergo/v2/internal/enc/base58" "github.com/aergoio/aergo/v2/types" "github.com/gofrs/uuid" lru "github.com/hashicorp/golang-lru" @@ -111,10 +111,10 @@ func Test_Encode(t *testing.T) { } for _, test := range tests { t.Run(test.name, func(t *testing.T) { - got := enc.ToString(test.in) + got := base58.Encode(test.in) assert.Equal(t, test.out, got) if len(test.out) > 0 { - gotBytes, err := enc.ToBytes(test.out) + gotBytes, err := base58.Decode(test.out) assert.Nil(t, err) assert.Equal(t, test.in, gotBytes) } diff --git a/p2p/raftsupport/clusterreceiver.go b/p2p/raftsupport/clusterreceiver.go index a4872a7cd..12af9e1cc 100644 --- a/p2p/raftsupport/clusterreceiver.go +++ b/p2p/raftsupport/clusterreceiver.go @@ -10,10 +10,10 @@ import ( "sync" "time" + "github.com/aergoio/aergo/v2/internal/enc/proto" "github.com/aergoio/aergo/v2/message" "github.com/aergoio/aergo/v2/p2p/p2pcommon" "github.com/aergoio/aergo/v2/types" - "github.com/golang/protobuf/proto" "github.com/pkg/errors" ) diff --git a/p2p/raftsupport/concclusterreceiver.go b/p2p/raftsupport/concclusterreceiver.go index aaee3b0c1..0ff67c134 100644 --- a/p2p/raftsupport/concclusterreceiver.go +++ b/p2p/raftsupport/concclusterreceiver.go @@ -11,11 +11,11 @@ import ( "time" "github.com/aergoio/aergo-lib/log" + "github.com/aergoio/aergo/v2/internal/enc/proto" "github.com/aergoio/aergo/v2/message" "github.com/aergoio/aergo/v2/p2p/p2pcommon" "github.com/aergoio/aergo/v2/p2p/p2putil" "github.com/aergoio/aergo/v2/types" - "github.com/golang/protobuf/proto" "github.com/pkg/errors" ) diff --git a/p2p/raftsupport/snapshotreceiver.go b/p2p/raftsupport/snapshotreceiver.go index 8d2cd4df4..2a46ff7d2 100644 --- a/p2p/raftsupport/snapshotreceiver.go +++ b/p2p/raftsupport/snapshotreceiver.go @@ -12,12 +12,12 @@ import ( "github.com/aergoio/aergo-lib/log" "github.com/aergoio/aergo/v2/consensus" + "github.com/aergoio/aergo/v2/internal/enc/proto" "github.com/aergoio/aergo/v2/p2p/p2pcommon" "github.com/aergoio/aergo/v2/p2p/p2putil" "github.com/aergoio/aergo/v2/types" rtypes "github.com/aergoio/etcd/pkg/types" "github.com/aergoio/etcd/raft/raftpb" - "github.com/golang/protobuf/proto" ) const ( @@ -106,7 +106,7 @@ func (s *snapshotReceiver) Receive() { } func (s *snapshotReceiver) sendResp(w io.Writer, resp *types.SnapshotResponse) { - b, err := proto.Marshal(resp) + b, err := proto.Encode(resp) if err == nil { bytebuf := make([]byte, SnapRespHeaderLength) binary.BigEndian.PutUint32(bytebuf, uint32(len(b))) diff --git a/p2p/raftsupport/snapshotsender.go b/p2p/raftsupport/snapshotsender.go index 125a1d14f..327df5b36 100644 --- a/p2p/raftsupport/snapshotsender.go +++ b/p2p/raftsupport/snapshotsender.go @@ -15,6 +15,7 @@ import ( "github.com/aergoio/aergo-lib/log" "github.com/aergoio/aergo/v2/consensus" + "github.com/aergoio/aergo/v2/internal/enc/proto" "github.com/aergoio/aergo/v2/p2p/p2pcommon" "github.com/aergoio/aergo/v2/p2p/p2putil" "github.com/aergoio/aergo/v2/types" @@ -22,7 +23,6 @@ import ( "github.com/aergoio/etcd/raft" "github.com/aergoio/etcd/raft/raftpb" "github.com/aergoio/etcd/snap" - "github.com/golang/protobuf/proto" core "github.com/libp2p/go-libp2p-core" ) @@ -171,7 +171,7 @@ func readWireHSResp(rd io.Reader) (resp types.SnapshotResponse, err error) { return } - err = proto.Unmarshal(bodyBuf, &resp) + err = proto.Decode(bodyBuf, &resp) return } func (s *snapshotSender) createSnapBody(merged snap.Message) io.ReadCloser { diff --git a/p2p/remotepeer_test.go b/p2p/remotepeer_test.go index ade9dc57e..fb27467d1 100644 --- a/p2p/remotepeer_test.go +++ b/p2p/remotepeer_test.go @@ -232,7 +232,7 @@ func TestRemotePeer_handleMsg(t *testing.T) { msg.On("Subprotocol").Return(PingRequest) } bodyStub := &types.Ping{} - bytes, _ := proto.Marshal(bodyStub) + bytes, _ := proto.Encode(bodyStub) msg.On("ID").Return(sampleMsgID) msg.On("Payload").Return(bytes) mockMsgHandler.On("parsePayload", mock.AnythingOfType("[]uint8")).Return(bodyStub, tt.args.parerr) diff --git a/p2p/signature.go b/p2p/signature.go index e596828b6..722aa97ee 100644 --- a/p2p/signature.go +++ b/p2p/signature.go @@ -8,9 +8,9 @@ package p2p import ( "fmt" + "github.com/aergoio/aergo/v2/internal/enc/proto" "github.com/aergoio/aergo/v2/p2p/p2pcommon" "github.com/aergoio/aergo/v2/types" - "github.com/golang/protobuf/proto" "github.com/libp2p/go-libp2p-core/crypto" ) @@ -33,7 +33,7 @@ func newDefaultMsgSigner(privKey crypto.PrivKey, pubKey crypto.PubKey, peerID ty func (pm *defaultMsgSigner) SignMsg(message *types.P2PMessage) error { message.Header.PeerID = pm.pidBytes message.Header.NodePubKey = pm.pubKeyBytes - data, err := proto.Marshal(&types.P2PMessage{Header: canonicalizeHeader(message.Header), Data: message.Data}) + data, err := proto.Encode(&types.P2PMessage{Header: canonicalizeHeader(message.Header), Data: message.Data}) if err != nil { return err } @@ -82,7 +82,7 @@ func (pm *defaultMsgSigner) VerifyMsg(msg *types.P2PMessage, senderID types.Peer } } - data, _ := proto.Marshal(&types.P2PMessage{Header: canonicalizeHeader(msg.Header), Data: msg.Data}) + data, _ := proto.Encode(&types.P2PMessage{Header: canonicalizeHeader(msg.Header), Data: msg.Data}) return verifyBytes(data, signature, pubKey) } diff --git a/p2p/subproto/addrs_test.go b/p2p/subproto/addrs_test.go index 1d789caf6..c94622892 100644 --- a/p2p/subproto/addrs_test.go +++ b/p2p/subproto/addrs_test.go @@ -10,11 +10,11 @@ import ( "testing" "github.com/aergoio/aergo-lib/log" + "github.com/aergoio/aergo/v2/internal/enc/proto" "github.com/aergoio/aergo/v2/p2p/p2pcommon" "github.com/aergoio/aergo/v2/p2p/p2pmock" "github.com/aergoio/aergo/v2/types" "github.com/golang/mock/gomock" - "github.com/golang/protobuf/proto" ) var samplePeers []p2pcommon.RemotePeer diff --git a/p2p/subproto/block.go b/p2p/subproto/block.go index 79c602ea2..00da901f6 100644 --- a/p2p/subproto/block.go +++ b/p2p/subproto/block.go @@ -7,7 +7,7 @@ package subproto import ( "github.com/aergoio/aergo-lib/log" - "github.com/aergoio/aergo/v2/internal/enc" + "github.com/aergoio/aergo/v2/internal/enc/base58" "github.com/aergoio/aergo/v2/message" "github.com/aergoio/aergo/v2/p2p/p2pcommon" "github.com/aergoio/aergo/v2/p2p/p2putil" @@ -162,7 +162,7 @@ func (bh *newBlockNoticeHandler) Handle(msg p2pcommon.Message, msgBody p2pcommon if blockID, err := types.ParseToBlockID(data.BlockHash); err != nil { // TODO Add penalty score and break - bh.logger.Info().Str(p2putil.LogPeerName, remotePeer.Name()).Str("hash", enc.ToString(data.BlockHash)).Msg("malformed blockHash") + bh.logger.Info().Str(p2putil.LogPeerName, remotePeer.Name()).Str("hash", base58.Encode(data.BlockHash)).Msg("malformed blockHash") return } else { // lru cache can't accept byte slice key @@ -242,7 +242,7 @@ func (bh *getAncestorRequestHandler) handleGetAncestorReq(msg p2pcommon.Message, AncestorNo: ancestor.No, } - bh.logger.Debug().Uint64("ancestorno", ancestor.No).Str("ancestorhash", enc.ToString(ancestor.Hash)).Msg("Sending get ancestor response") + bh.logger.Debug().Uint64("ancestorno", ancestor.No).Str("ancestorhash", base58.Encode(ancestor.Hash)).Msg("Sending get ancestor response") remotePeer.SendMessage(remotePeer.MF().NewMsgResponseOrder(msg.ID(), p2pcommon.GetAncestorResponse, resp)) } diff --git a/p2p/subproto/blockhash_test.go b/p2p/subproto/blockhash_test.go index 4dba77a74..551290b69 100644 --- a/p2p/subproto/blockhash_test.go +++ b/p2p/subproto/blockhash_test.go @@ -13,7 +13,7 @@ import ( "github.com/aergoio/aergo-lib/log" "github.com/aergoio/aergo/v2/chain" - "github.com/aergoio/aergo/v2/internal/enc" + "github.com/aergoio/aergo/v2/internal/enc/base58" "github.com/aergoio/aergo/v2/p2p/p2pcommon" "github.com/aergoio/aergo/v2/p2p/p2pmock" "github.com/aergoio/aergo/v2/types" @@ -46,7 +46,7 @@ func TestGetHashRequestHandler_handle(t *testing.T) { sampleBlks = make([][]byte, len(sampleBlksB58)) sampleBlksHashes = make([]types.BlockID, len(sampleBlksB58)) for i, hashb58 := range sampleBlksB58 { - hash, _ := enc.ToBytes(hashb58) + hash, _ := base58.Decode(hashb58) sampleBlks[i] = hash copy(sampleBlksHashes[i][:], hash) } @@ -154,7 +154,7 @@ func TestGetHashByNoRequestHandler_handle(t *testing.T) { sampleBlks = make([][]byte, len(sampleBlksB58)) sampleBlksHashes = make([]types.BlockID, len(sampleBlksB58)) for i, hashb58 := range sampleBlksB58 { - hash, _ := enc.ToBytes(hashb58) + hash, _ := base58.Decode(hashb58) sampleBlks[i] = hash copy(sampleBlksHashes[i][:], hash) } diff --git a/p2p/subproto/bp.go b/p2p/subproto/bp.go index 5cf90f2f1..3937949e9 100644 --- a/p2p/subproto/bp.go +++ b/p2p/subproto/bp.go @@ -7,7 +7,7 @@ package subproto import ( "github.com/aergoio/aergo-lib/log" - "github.com/aergoio/aergo/v2/internal/enc" + "github.com/aergoio/aergo/v2/internal/enc/base58" "github.com/aergoio/aergo/v2/message" "github.com/aergoio/aergo/v2/p2p/p2pcommon" "github.com/aergoio/aergo/v2/p2p/p2putil" @@ -48,7 +48,7 @@ func (h *blockProducedNoticeHandler) Handle(msg p2pcommon.Message, msgBody p2pco block := data.Block if blockID, err := types.ParseToBlockID(data.GetBlock().GetHash()); err != nil { // TODO add penalty score - h.logger.Info().Str(p2putil.LogPeerName, remotePeer.Name()).Str("hash", enc.ToString(data.GetBlock().GetHash())).Msg("malformed blockHash") + h.logger.Info().Str(p2putil.LogPeerName, remotePeer.Name()).Str("hash", base58.Encode(data.GetBlock().GetHash())).Msg("malformed blockHash") return } else { bpID, err := block.BPID() @@ -107,7 +107,7 @@ func (h *toAgentBPNoticeHandler) Handle(msg p2pcommon.Message, msgBody p2pcommon block := data.Block if blockID, err := types.ParseToBlockID(data.GetBlock().GetHash()); err != nil { // TODO add penalty score - h.logger.Info().Str(p2putil.LogPeerName, remotePeer.Name()).Str("hash", enc.ToString(data.GetBlock().GetHash())).Msg("malformed blockHash") + h.logger.Info().Str(p2putil.LogPeerName, remotePeer.Name()).Str("hash", base58.Encode(data.GetBlock().GetHash())).Msg("malformed blockHash") return } else { bpID, err := block.BPID() diff --git a/p2p/subproto/bp_test.go b/p2p/subproto/bp_test.go index d0e07a7d9..a6411f0de 100644 --- a/p2p/subproto/bp_test.go +++ b/p2p/subproto/bp_test.go @@ -10,13 +10,13 @@ import ( "time" "github.com/aergoio/aergo-lib/log" - "github.com/aergoio/aergo/v2/internal/enc" + "github.com/aergoio/aergo/v2/internal/enc/base58" + "github.com/aergoio/aergo/v2/internal/enc/proto" "github.com/aergoio/aergo/v2/p2p/p2pcommon" "github.com/aergoio/aergo/v2/p2p/p2pmock" "github.com/aergoio/aergo/v2/p2p/p2putil" "github.com/aergoio/aergo/v2/types" "github.com/golang/mock/gomock" - "github.com/golang/protobuf/proto" "github.com/libp2p/go-libp2p-core/crypto" ) @@ -65,7 +65,7 @@ func TestNewBlockProducedNoticeHandlerOfBP(t *testing.T) { func Test_blockProducedNoticeHandler_handle_FromBP(t *testing.T) { logger := log.NewLogger("test.subproto") - dummyBlockHash, _ := enc.ToBytes("v6zbuQ4aVSdbTwQhaiZGp5pcL5uL55X3kt2wfxor5W6") + dummyBlockHash, _ := base58.Decode("v6zbuQ4aVSdbTwQhaiZGp5pcL5uL55X3kt2wfxor5W6") dummyBlockID := types.MustParseBlockID(dummyBlockHash) bpKey, bpPub, _ := crypto.GenerateKeyPair(crypto.Secp256k1, 256) bpID, _ := types.IDFromPrivateKey(bpKey) diff --git a/p2p/subproto/getblock.go b/p2p/subproto/getblock.go index 4d96e1aee..be3042131 100644 --- a/p2p/subproto/getblock.go +++ b/p2p/subproto/getblock.go @@ -9,11 +9,11 @@ import ( "time" "github.com/aergoio/aergo-lib/log" - "github.com/aergoio/aergo/v2/internal/enc" + "github.com/aergoio/aergo/v2/internal/enc/base58" + "github.com/aergoio/aergo/v2/internal/enc/proto" "github.com/aergoio/aergo/v2/p2p/p2pcommon" "github.com/aergoio/aergo/v2/p2p/p2putil" "github.com/aergoio/aergo/v2/types" - "github.com/golang/protobuf/proto" ) type blockRequestHandler struct { @@ -82,13 +82,13 @@ func (bh *blockRequestHandler) handleBlkReq(msg p2pcommon.Message, data *types.G foundBlock, err := bh.actor.GetChainAccessor().GetBlock(hash) if err != nil { // the block hash from request must exists. this error is fatal. - bh.logger.Warn().Err(err).Str(p2putil.LogBlkHash, enc.ToString(hash)).Str(p2putil.LogOrgReqID, requestID.String()).Msg("failed to get block while processing getBlock") + bh.logger.Warn().Err(err).Str(p2putil.LogBlkHash, base58.Encode(hash)).Str(p2putil.LogOrgReqID, requestID.String()).Msg("failed to get block while processing getBlock") status = types.ResultStatus_INTERNAL break } if foundBlock == nil { // the remote peer request not existing block - bh.logger.Debug().Str(p2putil.LogBlkHash, enc.ToString(hash)).Str(p2putil.LogOrgReqID, requestID.String()).Msg("requested block hash is missing") + bh.logger.Debug().Str(p2putil.LogBlkHash, base58.Encode(hash)).Str(p2putil.LogOrgReqID, requestID.String()).Msg("requested block hash is missing") status = types.ResultStatus_NOT_FOUND break diff --git a/p2p/subproto/getblock_test.go b/p2p/subproto/getblock_test.go index 2204087f9..c4e2a13df 100644 --- a/p2p/subproto/getblock_test.go +++ b/p2p/subproto/getblock_test.go @@ -10,7 +10,7 @@ import ( "time" "github.com/aergoio/aergo-lib/log" - "github.com/aergoio/aergo/v2/internal/enc" + "github.com/aergoio/aergo/v2/internal/enc/base58" "github.com/aergoio/aergo/v2/message" "github.com/aergoio/aergo/v2/p2p/p2pcommon" "github.com/aergoio/aergo/v2/p2p/p2pmock" @@ -95,7 +95,7 @@ func TestBlockResponseHandler_handle(t *testing.T) { logger := log.NewLogger("test.subproto") var dummyPeerID, _ = types.IDB58Decode("16Uiu2HAmN5YU8V2LnTy9neuuJCLNsxLnd5xVSRZqkjvZUHS3mLoD") - dummyBlockHash, _ := enc.ToBytes("v6zbuQ4aVSdbTwQhaiZGp5pcL5uL55X3kt2wfxor5W6") + dummyBlockHash, _ := base58.Decode("v6zbuQ4aVSdbTwQhaiZGp5pcL5uL55X3kt2wfxor5W6") var sampleBlksB58 = []string{ "v6zbuQ4aVSdbTwQhaiZGp5pcL5uL55X3kt2wfxor5W6", "2VEPg4MqJUoaS3EhZ6WWSAUuFSuD4oSJ645kSQsGV7H9", @@ -110,7 +110,7 @@ func TestBlockResponseHandler_handle(t *testing.T) { sampleBlks = make([][]byte, len(sampleBlksB58)) sampleBlksHashes = make([]types.BlockID, len(sampleBlksB58)) for i, hashb58 := range sampleBlksB58 { - hash, _ := enc.ToBytes(hashb58) + hash, _ := base58.Decode(hashb58) sampleBlks[i] = hash copy(sampleBlksHashes[i][:], hash) } diff --git a/p2p/subproto/ping_test.go b/p2p/subproto/ping_test.go index b6526aa4f..6c0efeff8 100644 --- a/p2p/subproto/ping_test.go +++ b/p2p/subproto/ping_test.go @@ -3,7 +3,7 @@ package subproto import ( "testing" - "github.com/aergoio/aergo/v2/internal/enc" + "github.com/aergoio/aergo/v2/internal/enc/base58" "github.com/aergoio/aergo/v2/types" "github.com/libp2p/go-libp2p-core/network" @@ -78,7 +78,7 @@ func Test_pingRequestHandler_handle(t *testing.T) { defer ctrl.Finish() logger := log.NewLogger("test.subproto") - dummyBlockHash, _ := enc.ToBytes("v6zbuQ4aVSdbTwQhaiZGp5pcL5uL55X3kt2wfxor5W6") + dummyBlockHash, _ := base58.Decode("v6zbuQ4aVSdbTwQhaiZGp5pcL5uL55X3kt2wfxor5W6") var dummyPeerID, _ = types.IDB58Decode("16Uiu2HAmN5YU8V2LnTy9neuuJCLNsxLnd5xVSRZqkjvZUHS3mLoD") type args struct { diff --git a/p2p/subproto/raftstub.go b/p2p/subproto/raftstub.go index 23c3fb9c5..baad777db 100644 --- a/p2p/subproto/raftstub.go +++ b/p2p/subproto/raftstub.go @@ -7,7 +7,7 @@ package subproto import ( "github.com/aergoio/aergo-lib/log" - "github.com/aergoio/aergo/v2/internal/enc" + "github.com/aergoio/aergo/v2/internal/enc/base58" "github.com/aergoio/aergo/v2/p2p/p2pcommon" "github.com/aergoio/aergo/v2/p2p/p2putil" "github.com/aergoio/aergo/v2/types" @@ -69,7 +69,7 @@ func (bh *raftNewBlkNoticeDiscardHandler) Handle(msg p2pcommon.Message, msgBody if blockID, err := types.ParseToBlockID(data.BlockHash); err != nil { // TODO Add penalty score and break - bh.logger.Info().Str(p2putil.LogPeerName, remotePeer.Name()).Str("hash", enc.ToString(data.BlockHash)).Msg("malformed blockHash") + bh.logger.Info().Str(p2putil.LogPeerName, remotePeer.Name()).Str("hash", base58.Encode(data.BlockHash)).Msg("malformed blockHash") return } else { // just update last status diff --git a/p2p/subproto/tx.go b/p2p/subproto/tx.go index d928f8e77..f3ef230cd 100644 --- a/p2p/subproto/tx.go +++ b/p2p/subproto/tx.go @@ -7,7 +7,7 @@ package subproto import ( "github.com/aergoio/aergo-lib/log" - "github.com/aergoio/aergo/v2/internal/enc" + "github.com/aergoio/aergo/v2/internal/enc/base58" "github.com/aergoio/aergo/v2/message" "github.com/aergoio/aergo/v2/p2p/p2pcommon" "github.com/aergoio/aergo/v2/p2p/p2putil" @@ -107,7 +107,7 @@ func (th *newTxNoticeHandler) Handle(msg p2pcommon.Message, msgBody p2pcommon.Me hashes := make([]types.TxID, len(data.TxHashes)) for i, hash := range data.TxHashes { if tid, err := types.ParseToTxID(hash); err != nil { - th.logger.Info().Str(p2putil.LogPeerName, remotePeer.Name()).Str("hash", enc.ToString(hash)).Msg("malformed txhash found") + th.logger.Info().Str(p2putil.LogPeerName, remotePeer.Name()).Str("hash", base58.Encode(hash)).Msg("malformed txhash found") // TODO Add penalty score and break break } else { diff --git a/p2p/subproto/tx_test.go b/p2p/subproto/tx_test.go index be9668aec..8b3e09aba 100644 --- a/p2p/subproto/tx_test.go +++ b/p2p/subproto/tx_test.go @@ -10,7 +10,7 @@ import ( "time" "github.com/aergoio/aergo-lib/log" - "github.com/aergoio/aergo/v2/internal/enc" + "github.com/aergoio/aergo/v2/internal/enc/base58" "github.com/aergoio/aergo/v2/message" "github.com/aergoio/aergo/v2/p2p/p2pmock" "github.com/aergoio/aergo/v2/types" @@ -45,7 +45,7 @@ func BenchmarkArrayKey(b *testing.B) { fmt.Printf("P2 in base64\n") target2 := make(map[string]int) for i := 0; i < size; i++ { - target2[enc.ToString(samples[i][:])] = i + target2[base58.Encode(samples[i][:])] = i } endTime := time.Now() fmt.Printf("Takes %f sec\n", endTime.Sub(startTime).Seconds()) diff --git a/p2p/synctx.go b/p2p/synctx.go index a16878d86..6eeda2708 100644 --- a/p2p/synctx.go +++ b/p2p/synctx.go @@ -8,12 +8,12 @@ import ( "time" "github.com/aergoio/aergo-lib/log" + "github.com/aergoio/aergo/v2/internal/enc/proto" "github.com/aergoio/aergo/v2/message" "github.com/aergoio/aergo/v2/p2p/p2pcommon" "github.com/aergoio/aergo/v2/p2p/p2putil" "github.com/aergoio/aergo/v2/p2p/subproto" "github.com/aergoio/aergo/v2/types" - "github.com/golang/protobuf/proto" lru "github.com/hashicorp/golang-lru" ) diff --git a/p2p/synctx_test.go b/p2p/synctx_test.go index fed5988d7..5e79a27f6 100644 --- a/p2p/synctx_test.go +++ b/p2p/synctx_test.go @@ -8,7 +8,7 @@ import ( "time" "github.com/aergoio/aergo-lib/log" - "github.com/aergoio/aergo/v2/internal/enc" + "github.com/aergoio/aergo/v2/internal/enc/base58" "github.com/aergoio/aergo/v2/message" "github.com/aergoio/aergo/v2/message/messagemock" "github.com/aergoio/aergo/v2/p2p/p2pcommon" @@ -285,7 +285,7 @@ func Test_txSyncManager_refineFrontCacheConsumption(t *testing.T) { } } if w == nil { - t.Fatalf("unexpected sent request %v", enc.ToString(hashes[i])) + t.Fatalf("unexpected sent request %v", base58.Encode(hashes[i])) } wTids := w.txIDs if len(hashes) != len(wTids) { @@ -422,7 +422,7 @@ func Test_txSyncManager_refineFrontCache(t *testing.T) { } } if !found { - t.Errorf("req hash %v, is not in wanted hash %v", enc.ToString(hash), tt.wantSend) + t.Errorf("req hash %v, is not in wanted hash %v", base58.Encode(hash), tt.wantSend) } sentMap[types.ToTxID(hash)] = 1 } @@ -583,7 +583,7 @@ func Test_syncTxManager_handleTxReq(t *testing.T) { var sampleTxs = make([][]byte, len(sampleTxsB58)) var sampleTxHashes = make([]types.TxID, len(sampleTxsB58)) for i, hashb58 := range sampleTxsB58 { - hash, _ := enc.ToBytes(hashb58) + hash, _ := base58.Decode(hashb58) sampleTxs[i] = hash copy(sampleTxHashes[i][:], hash) } diff --git a/p2p/test/golang_test.go b/p2p/test/golang_test.go index c4a83a6f0..4261648b6 100644 --- a/p2p/test/golang_test.go +++ b/p2p/test/golang_test.go @@ -5,29 +5,30 @@ import ( ) func TestSliceCompaction1(t *testing.T) { - sli := make([]int,10) - for i:=0; i<10; i++ { + sli := make([]int, 10) + for i := 0; i < 10; i++ { sli[i] = i } - s2 := append(sli[:3],sli[5:]...) + s2 := append(sli[:3], sli[5:]...) - t.Logf("Sli : %v",sli) - t.Logf("S2 : %v",s2) + t.Logf("Sli : %v", sli) + t.Logf("S2 : %v", s2) } func TestSliceCompaction2(t *testing.T) { - sli := make([]int,10) - for i:=0; i<10; i++ { + sli := make([]int, 10) + for i := 0; i < 10; i++ { sli[i] = i } - i:=9 // last element - sli = append(sli[:i],sli[i+1:]...) - t.Logf("Sli : (len %v) %v ",len(sli),sli) + i := 9 // last element + sli = append(sli[:i], sli[i+1:]...) + t.Logf("Sli : (len %v) %v ", len(sli), sli) } type data struct { str string } + func TestDefer(t *testing.T) { val := data{"first val"} vp := &val @@ -47,6 +48,5 @@ func printValue(t *testing.T, name string, str interface{}) { if ok { v = *v2 } - t.Logf("%v is %v ",name,v) + t.Logf("%v is %v ", name, v) } - diff --git a/p2p/transport/networktransport_test.go b/p2p/transport/networktransport_test.go index be2b8e1f1..0209773c8 100644 --- a/p2p/transport/networktransport_test.go +++ b/p2p/transport/networktransport_test.go @@ -6,13 +6,13 @@ package transport import ( - "encoding/hex" "testing" "time" "github.com/aergoio/aergo-lib/log" "github.com/aergoio/aergo/v2/config" cfg "github.com/aergoio/aergo/v2/config" + "github.com/aergoio/aergo/v2/internal/enc/hex" "github.com/aergoio/aergo/v2/message" "github.com/aergoio/aergo/v2/p2p/p2pcommon" "github.com/aergoio/aergo/v2/p2p/p2pkey" @@ -35,7 +35,7 @@ func init() { // TODO split this test into two... one is to attempt make connection and the other is test peermanager if same peerid is given // Ignoring test for now, for lack of abstraction on AergoPeer struct func IgnoredTestP2PServiceRunAddPeer(t *testing.T) { - var sampleBlockHash, _ = hex.DecodeString("4f461d85e869ade8a0544f8313987c33a9c06534e50c4ad941498299579bd7ac") + var sampleBlockHash, _ = hex.Decode("4f461d85e869ade8a0544f8313987c33a9c06534e50c4ad941498299579bd7ac") var sampleBlockHeight uint64 = 100215 ctrl := gomock.NewController(t) diff --git a/p2p/txreceiver.go b/p2p/txreceiver.go index 94c956410..47f77f498 100644 --- a/p2p/txreceiver.go +++ b/p2p/txreceiver.go @@ -10,7 +10,7 @@ import ( "time" "github.com/aergoio/aergo-lib/log" - "github.com/aergoio/aergo/v2/internal/enc" + "github.com/aergoio/aergo/v2/internal/enc/base58" "github.com/aergoio/aergo/v2/message" "github.com/aergoio/aergo/v2/p2p/p2pcommon" "github.com/aergoio/aergo/v2/p2p/p2putil" @@ -116,7 +116,7 @@ func (br *GetTxsReceiver) handleInWaiting(msg p2pcommon.Message, msgBody p2pcomm } // missing tx for !bytes.Equal(br.hashes[br.offset], tx.Hash) { - br.logger.Trace().Str("expect", enc.ToString(br.hashes[br.offset])).Str("received", enc.ToString(tx.Hash)).Int("offset", br.offset).Msg("expected hash was missing") + br.logger.Trace().Str("expect", base58.Encode(br.hashes[br.offset])).Str("received", base58.Encode(tx.Hash)).Int("offset", br.offset).Msg("expected hash was missing") br.missed = append(br.missed, tx.Hash) br.offset++ if br.offset >= len(br.hashes) { diff --git a/p2p/v030/v030handshake_test.go b/p2p/v030/v030handshake_test.go index fa1d02fae..109d52c48 100644 --- a/p2p/v030/v030handshake_test.go +++ b/p2p/v030/v030handshake_test.go @@ -7,13 +7,13 @@ package v030 import ( "context" - "encoding/hex" "fmt" "reflect" "testing" "github.com/aergoio/aergo-lib/log" "github.com/aergoio/aergo/v2/config" + "github.com/aergoio/aergo/v2/internal/enc/hex" "github.com/aergoio/aergo/v2/p2p/p2pcommon" "github.com/aergoio/aergo/v2/p2p/p2pkey" "github.com/aergoio/aergo/v2/p2p/p2pmock" @@ -30,7 +30,7 @@ var ( myChainID, newVerChainID, theirChainID *types.ChainID myChainBytes, newVerChainBytes, theirChainBytes []byte samplePeerID, _ = types.IDB58Decode("16Uiu2HAmFqptXPfcdaCdwipB2fhHATgKGVFVPehDAPZsDKSU7jRm") - dummyBlockHash, _ = hex.DecodeString("4f461d85e869ade8a0544f8313987c33a9c06534e50c4ad941498299579bd7ac") + dummyBlockHash, _ = hex.Decode("4f461d85e869ade8a0544f8313987c33a9c06534e50c4ad941498299579bd7ac") dummyBlockHeight uint64 = 100215 ) diff --git a/p2p/v030/v030io_test.go b/p2p/v030/v030io_test.go index e114d0034..ca0f930c8 100644 --- a/p2p/v030/v030io_test.go +++ b/p2p/v030/v030io_test.go @@ -13,11 +13,11 @@ import ( "testing" "time" - "github.com/aergoio/aergo/v2/internal/enc" + "github.com/aergoio/aergo/v2/internal/enc/base58" + "github.com/aergoio/aergo/v2/internal/enc/proto" "github.com/aergoio/aergo/v2/p2p/p2pcommon" "github.com/aergoio/aergo/v2/types" "github.com/gofrs/uuid" - "github.com/golang/protobuf/proto" "github.com/stretchr/testify/assert" ) @@ -48,7 +48,7 @@ func init() { sampleTxs = make([][]byte, len(sampleTxsB58)) sampleTxHashes = make([]types.TxID, len(sampleTxsB58)) for i, hashb58 := range sampleTxsB58 { - hash, _ := enc.ToBytes(hashb58) + hash, _ := base58.Decode(hashb58) sampleTxs[i] = hash copy(sampleTxHashes[i][:], hash) } @@ -56,7 +56,7 @@ func init() { sampleBlks = make([][]byte, len(sampleBlksB58)) sampleBlksHashes = make([]types.BlockID, len(sampleBlksB58)) for i, hashb58 := range sampleTxsB58 { - hash, _ := enc.ToBytes(hashb58) + hash, _ := base58.Decode(hashb58) sampleBlks[i] = hash copy(sampleBlksHashes[i][:], hash) } @@ -86,7 +86,7 @@ func Test_ReadWrite(t *testing.T) { t.Run(test.name, func(t *testing.T) { sizeChecker, sizeChecker2 := ioSum{}, ioSum{} samplePData := &types.NewTransactionsNotice{TxHashes: test.ids} - payload, _ := proto.Marshal(samplePData) + payload, _ := proto.Encode(samplePData) sample := p2pcommon.NewMessageValue(p2pcommon.NewTxNotice, sampleID, p2pcommon.EmptyID, time.Now().UnixNano(), payload) buf := bytes.NewBuffer(nil) @@ -138,7 +138,7 @@ func TestV030Writer_WriteError(t *testing.T) { //sampleUUID, _ := uuid.NewRandom() //copy(sampleID[:], sampleUUID[:]) //samplePData := &types.NewTransactionsNotice{TxHashes:sampleTxs} - //payload, _ := proto.Marshal(samplePData) + //payload, _ := proto.Encode(samplePData) //sample := &MessageValue{subProtocol: subproto.NewTxNotice, id: sampleID, timestamp: time.Now().UnixNano(), length: uint32(len(payload)), payload: payload} //mockWriter := make(MockWriter) //mockWriter.On("Write", mock.Anything).Return(fmt.Errorf("writer error")) @@ -154,14 +154,14 @@ func BenchmarkV030Writer_WriteMsg(b *testing.B) { timestamp := time.Now().UnixNano() smallPData := &types.NewTransactionsNotice{} - payload, _ := proto.Marshal(smallPData) + payload, _ := proto.Encode(smallPData) smallMsg := p2pcommon.NewMessageValue(p2pcommon.NewTxNotice, sampleID, p2pcommon.EmptyID, timestamp, payload) bigHashes := make([][]byte, 0, len(sampleTxs)*10000) for i := 0; i < 10000; i++ { bigHashes = append(bigHashes, sampleTxs...) } bigPData := &types.NewTransactionsNotice{TxHashes: bigHashes} - payload, _ = proto.Marshal(bigPData) + payload, _ = proto.Encode(bigPData) bigMsg := p2pcommon.NewMessageValue(p2pcommon.NewTxNotice, sampleID, p2pcommon.EmptyID, timestamp, payload) benchmarks := []struct { @@ -198,7 +198,7 @@ func BenchmarkV030Reader_ReadMsg(b *testing.B) { timestamp := time.Now().UnixNano() smallPData := &types.NewTransactionsNotice{} - payload, _ := proto.Marshal(smallPData) + payload, _ := proto.Encode(smallPData) smallMsg := p2pcommon.NewMessageValue(p2pcommon.NewTxNotice, sampleID, p2pcommon.EmptyID, timestamp, payload) smallBytes := getMarshaledV030(smallMsg, 1) bigHashes := make([][]byte, 0, len(sampleTxs)*10000) @@ -206,7 +206,7 @@ func BenchmarkV030Reader_ReadMsg(b *testing.B) { bigHashes = append(bigHashes, sampleTxs...) } bigPData := &types.NewTransactionsNotice{TxHashes: bigHashes} - payload, _ = proto.Marshal(bigPData) + payload, _ = proto.Encode(bigPData) bigMsg := p2pcommon.NewMessageValue(p2pcommon.NewTxNotice, sampleID, p2pcommon.EmptyID, timestamp, payload) bigBytes := getMarshaledV030(bigMsg, 1) diff --git a/p2p/v030/v032handshake.go b/p2p/v030/v032handshake.go index 803bffc7f..a612a22f0 100644 --- a/p2p/v030/v032handshake.go +++ b/p2p/v030/v032handshake.go @@ -12,7 +12,7 @@ import ( "io" "github.com/aergoio/aergo-lib/log" - "github.com/aergoio/aergo/v2/internal/enc" + "github.com/aergoio/aergo/v2/internal/enc/base58" "github.com/aergoio/aergo/v2/p2p/p2pcommon" "github.com/aergoio/aergo/v2/p2p/p2putil" "github.com/aergoio/aergo/v2/types" @@ -47,7 +47,7 @@ func (h *V032Handshaker) checkRemoteStatus(remotePeerStatus *types.Status) error genHash := h.localGenesisHash if !bytes.Equal(genHash, remotePeerStatus.Genesis) { h.sendGoAway("different genesis block") - return fmt.Errorf("different genesis block local: %v , remote %v", enc.ToString(genHash), enc.ToString(remotePeerStatus.Genesis)) + return fmt.Errorf("different genesis block local: %v , remote %v", base58.Encode(genHash), base58.Encode(remotePeerStatus.Genesis)) } return nil diff --git a/p2p/v030/v033handshake.go b/p2p/v030/v033handshake.go index ab5399fdf..4106e258d 100644 --- a/p2p/v030/v033handshake.go +++ b/p2p/v030/v033handshake.go @@ -12,7 +12,7 @@ import ( "io" "github.com/aergoio/aergo-lib/log" - "github.com/aergoio/aergo/v2/internal/enc" + "github.com/aergoio/aergo/v2/internal/enc/base58" "github.com/aergoio/aergo/v2/internal/network" "github.com/aergoio/aergo/v2/p2p/p2pcommon" "github.com/aergoio/aergo/v2/p2p/p2putil" @@ -76,7 +76,7 @@ func (h *V033Handshaker) checkRemoteStatus(remotePeerStatus *types.Status) error genHash := h.localGenesisHash if !bytes.Equal(genHash, remotePeerStatus.Genesis) { h.sendGoAway("different genesis block") - return fmt.Errorf("different genesis block local: %v , remote %v", enc.ToString(genHash), enc.ToString(remotePeerStatus.Genesis)) + return fmt.Errorf("different genesis block local: %v , remote %v", base58.Encode(genHash), base58.Encode(remotePeerStatus.Genesis)) } return nil diff --git a/p2p/v200/v200handshake.go b/p2p/v200/v200handshake.go index 9f35813ef..422ed2961 100644 --- a/p2p/v200/v200handshake.go +++ b/p2p/v200/v200handshake.go @@ -14,7 +14,7 @@ import ( "time" "github.com/aergoio/aergo-lib/log" - "github.com/aergoio/aergo/v2/internal/enc" + "github.com/aergoio/aergo/v2/internal/enc/base58" "github.com/aergoio/aergo/v2/internal/network" "github.com/aergoio/aergo/v2/p2p/p2pcommon" "github.com/aergoio/aergo/v2/p2p/p2pkey" @@ -192,7 +192,7 @@ func (h *V200Handshaker) checkRemoteStatus(remotePeerStatus *types.Status) error genHash := h.localGenesisHash if !bytes.Equal(genHash, remotePeerStatus.Genesis) { h.sendGoAway("different genesis block") - return fmt.Errorf("different genesis block local: %v , remote %v", enc.ToString(genHash), enc.ToString(remotePeerStatus.Genesis)) + return fmt.Errorf("different genesis block local: %v , remote %v", base58.Encode(genHash), base58.Encode(remotePeerStatus.Genesis)) } h.remoteMeta = rMeta diff --git a/p2p/v200/v200handshake_test.go b/p2p/v200/v200handshake_test.go index 072195921..283ec7846 100644 --- a/p2p/v200/v200handshake_test.go +++ b/p2p/v200/v200handshake_test.go @@ -7,7 +7,6 @@ package v200 import ( "context" - "encoding/hex" "fmt" "net" "reflect" @@ -17,6 +16,7 @@ import ( "github.com/aergoio/aergo-lib/log" "github.com/aergoio/aergo/v2/config" + "github.com/aergoio/aergo/v2/internal/enc/hex" "github.com/aergoio/aergo/v2/p2p/p2pcommon" "github.com/aergoio/aergo/v2/p2p/p2pkey" "github.com/aergoio/aergo/v2/p2p/p2pmock" @@ -35,7 +35,7 @@ var ( theirChainBytes []byte samplePeerID, _ = types.IDB58Decode("16Uiu2HAmFqptXPfcdaCdwipB2fhHATgKGVFVPehDAPZsDKSU7jRm") - dummyBlockHash, _ = hex.DecodeString("4f461d85e869ade8a0544f8313987c33a9c06534e50c4ad941498299579bd7ac") + dummyBlockHash, _ = hex.Decode("4f461d85e869ade8a0544f8313987c33a9c06534e50c4ad941498299579bd7ac") dummyBlockID = types.MustParseBlockID(dummyBlockHash) dummyBlockHeight uint64 = 100215 diff --git a/polaris/server/mapservice_test.go b/polaris/server/mapservice_test.go index 73e7151fd..a810e8670 100644 --- a/polaris/server/mapservice_test.go +++ b/polaris/server/mapservice_test.go @@ -14,6 +14,7 @@ import ( "time" "github.com/aergoio/aergo/v2/config" + "github.com/aergoio/aergo/v2/internal/enc/proto" "github.com/aergoio/aergo/v2/p2p/p2pcommon" "github.com/aergoio/aergo/v2/p2p/p2pmock" "github.com/aergoio/aergo/v2/p2p/p2putil" @@ -21,7 +22,6 @@ import ( "github.com/aergoio/aergo/v2/polaris/common" "github.com/aergoio/aergo/v2/types" "github.com/golang/mock/gomock" - "github.com/golang/protobuf/proto" "github.com/libp2p/go-libp2p-core/network" "github.com/stretchr/testify/assert" ) diff --git a/rpc/grpcserver_test.go b/rpc/grpcserver_test.go index 928d88802..f0aad80b9 100644 --- a/rpc/grpcserver_test.go +++ b/rpc/grpcserver_test.go @@ -6,14 +6,15 @@ package rpc import ( "context" - "encoding/hex" "fmt" "math/big" "reflect" "testing" "github.com/aergoio/aergo-actor/actor" - "github.com/aergoio/aergo/v2/internal/enc" + "github.com/aergoio/aergo/v2/internal/enc/base58" + "github.com/aergoio/aergo/v2/internal/enc/base64" + "github.com/aergoio/aergo/v2/internal/enc/hex" "github.com/aergoio/aergo/v2/message" "github.com/aergoio/aergo/v2/message/messagemock" "github.com/aergoio/aergo/v2/p2p/p2pcommon" @@ -21,38 +22,37 @@ import ( "github.com/aergoio/aergo/v2/pkg/component" "github.com/aergoio/aergo/v2/types" "github.com/golang/mock/gomock" - "github.com/mr-tron/base58/base58" ) func TestAergoRPCService_dummys(t *testing.T) { fmt.Println("dummyBlockHash") - fmt.Printf("HEX : %s \n", hex.EncodeToString(dummyBlockHash)) - fmt.Printf("B64 : %s \n", enc.ToString(dummyBlockHash)) + fmt.Printf("HEX : %s \n", hex.Encode(dummyBlockHash)) + fmt.Printf("B64 : %s \n", base64.Encode(dummyBlockHash)) fmt.Printf("B58 : %s \n", base58.Encode(dummyBlockHash)) fmt.Println() fmt.Println("dummyTx") - fmt.Printf("HEX : %s \n", hex.EncodeToString(dummyTxHash)) - fmt.Printf("B64 : %s \n", enc.ToString(dummyTxHash)) + fmt.Printf("HEX : %s \n", hex.Encode(dummyTxHash)) + fmt.Printf("B64 : %s \n", base64.Encode(dummyTxHash)) fmt.Printf("B58 : %s \n", base58.Encode(dummyTxHash)) fmt.Println() fmt.Println("Address1") - fmt.Printf("HEX : %s \n", hex.EncodeToString(dummyWalletAddress)) - fmt.Printf("B64 : %s \n", enc.ToString(dummyWalletAddress)) + fmt.Printf("HEX : %s \n", hex.Encode(dummyWalletAddress)) + fmt.Printf("B64 : %s \n", base64.Encode(dummyWalletAddress)) fmt.Printf("B58 : %s \n", base58.Encode(dummyWalletAddress)) fmt.Println() fmt.Println("Address2") - fmt.Printf("HEX : %s \n", hex.EncodeToString(dummyWalletAddress2)) - fmt.Printf("B64 : %s \n", enc.ToString(dummyWalletAddress2)) + fmt.Printf("HEX : %s \n", hex.Encode(dummyWalletAddress2)) + fmt.Printf("B64 : %s \n", base64.Encode(dummyWalletAddress2)) fmt.Printf("B58 : %s \n", base58.Encode(dummyWalletAddress2)) fmt.Println() } -var dummyBlockHash, _ = hex.DecodeString("4f461d85e869ade8a0544f8313987c33a9c06534e50c4ad941498299579bd7ac") +var dummyBlockHash, _ = hex.Decode("4f461d85e869ade8a0544f8313987c33a9c06534e50c4ad941498299579bd7ac") var dummyBlockHeight uint32 = 100215 -var dummyTxHash, _ = hex.DecodeString("218bdab4e87fb332b55eb89854ef553f9e3d440c81fff4161b672adede1261ee") +var dummyTxHash, _ = hex.Decode("218bdab4e87fb332b55eb89854ef553f9e3d440c81fff4161b672adede1261ee") // base64 encoding of dummyTxHash is "" var dummyWalletAddress, _ = base58.Decode("1Ee8uhLFXzkSRRU1orBpgXFAPpVi64aSYo") diff --git a/state/chainstatedb.go b/state/chainstatedb.go index dd5a00eba..4dbf83c7d 100644 --- a/state/chainstatedb.go +++ b/state/chainstatedb.go @@ -7,7 +7,7 @@ import ( "github.com/aergoio/aergo-lib/db" "github.com/aergoio/aergo/v2/internal/common" - "github.com/aergoio/aergo/v2/internal/enc" + "github.com/aergoio/aergo/v2/internal/enc/base58" "github.com/aergoio/aergo/v2/types" ) @@ -168,8 +168,8 @@ func (sdb *ChainStateDB) UpdateRoot(bstate *BlockState) error { // bstate.BlockInfo.StateRoot = types.ToHashID(sdb.GetRoot()) // } - logger.Debug().Str("before", enc.ToString(sdb.states.GetRoot())). - Str("stateRoot", enc.ToString(bstate.GetRoot())).Msg("apply block state") + logger.Debug().Str("before", base58.Encode(sdb.states.GetRoot())). + Str("stateRoot", base58.Encode(bstate.GetRoot())).Msg("apply block state") if err := sdb.states.SetRoot(bstate.GetRoot()); err != nil { return err @@ -182,8 +182,8 @@ func (sdb *ChainStateDB) SetRoot(targetBlockRoot []byte) error { sdb.Lock() defer sdb.Unlock() - logger.Debug().Str("before", enc.ToString(sdb.states.GetRoot())). - Str("target", enc.ToString(targetBlockRoot)).Msg("rollback state") + logger.Debug().Str("before", base58.Encode(sdb.states.GetRoot())). + Str("target", base58.Encode(targetBlockRoot)).Msg("rollback state") sdb.states.SetRoot(targetBlockRoot) return nil diff --git a/state/contract.go b/state/contract.go index a0b9a9998..df7511ea0 100644 --- a/state/contract.go +++ b/state/contract.go @@ -6,8 +6,8 @@ import ( "github.com/aergoio/aergo-lib/db" "github.com/aergoio/aergo/v2/internal/common" + "github.com/aergoio/aergo/v2/internal/enc/proto" "github.com/aergoio/aergo/v2/types" - "github.com/golang/protobuf/proto" ) func (states *StateDB) OpenContractStateAccount(aid types.AccountID) (*ContractState, error) { @@ -192,7 +192,7 @@ func (st *ContractState) Hash() []byte { // Marshal implements types.ImplMarshal func (st *ContractState) Marshal() ([]byte, error) { - return proto.Marshal(st.State) + return proto.Encode(st.State) } func (st *ContractState) cache() *stateBuffer { diff --git a/state/statebuffer.go b/state/statebuffer.go index 0ea32c8e5..b2a369e3a 100644 --- a/state/statebuffer.go +++ b/state/statebuffer.go @@ -4,9 +4,9 @@ import ( "sort" "github.com/aergoio/aergo/v2/internal/common" + "github.com/aergoio/aergo/v2/internal/enc/proto" "github.com/aergoio/aergo/v2/pkg/trie" "github.com/aergoio/aergo/v2/types" - "github.com/golang/protobuf/proto" ) type entry interface { @@ -205,7 +205,7 @@ func marshal(data interface{}) ([]byte, error) { case (types.ImplMarshal): return data.(types.ImplMarshal).Marshal() case (proto.Message): - return proto.Marshal(data.(proto.Message)) + return proto.Encode(data.(proto.Message)) } return nil, nil } diff --git a/state/statebuffer_test.go b/state/statebuffer_test.go index 4f881eb60..56d65c1ae 100644 --- a/state/statebuffer_test.go +++ b/state/statebuffer_test.go @@ -1,9 +1,9 @@ package state import ( - "encoding/hex" "testing" + "github.com/aergoio/aergo/v2/internal/enc/hex" "github.com/aergoio/aergo/v2/types" "github.com/stretchr/testify/assert" ) @@ -26,7 +26,7 @@ func TestBufferIndexStack(t *testing.T) { idxs.push(k0, 4) idxs.push(k1, 5) for i, v := range kset { - t.Logf("(%d)[%v]%v", i, hex.EncodeToString(v[:]), idxs[v]) + t.Logf("(%d)[%v]%v", i, hex.Encode(v[:]), idxs[v]) } assert.Equal(t, 4, idxs.pop(k0)) @@ -39,13 +39,13 @@ func TestBufferIndexStack(t *testing.T) { assert.Equal(t, 2, idxs.peek(k1)) assert.Equal(t, 2, idxs.pop(k1)) for i, v := range kset { - t.Logf("(%d)[%v]%v", i, hex.EncodeToString(v[:]), idxs[v]) + t.Logf("(%d)[%v]%v", i, hex.Encode(v[:]), idxs[v]) } idxs.push(k0, 6, 8, 12) idxs.push(k1, 7, 9, 10, 11) for i, v := range kset { - t.Logf("(%d)[%v]%v", i, hex.EncodeToString(v[:]), idxs[v]) + t.Logf("(%d)[%v]%v", i, hex.Encode(v[:]), idxs[v]) } assert.Equal(t, 12, idxs[k0].peek()) @@ -57,7 +57,7 @@ func TestBufferIndexRollback(t *testing.T) { idxs.push(k0, 0, 1, 3, 4, 6, 7, 8) idxs.push(k1, 2, 5, 9) for i, v := range kset { - t.Logf("(%d)[%v]%v", i, hex.EncodeToString(v[:]), idxs[v]) + t.Logf("(%d)[%v]%v", i, hex.Encode(v[:]), idxs[v]) } assert.Equal(t, 8, idxs[k0].peek()) @@ -65,7 +65,7 @@ func TestBufferIndexRollback(t *testing.T) { idxs.rollback(5) for i, v := range kset { - t.Logf("(%d)[%v]%v", i, hex.EncodeToString(v[:]), idxs[v]) + t.Logf("(%d)[%v]%v", i, hex.Encode(v[:]), idxs[v]) } assert.Equal(t, 4, idxs[k0].peek()) @@ -73,7 +73,7 @@ func TestBufferIndexRollback(t *testing.T) { idxs.rollback(0) for i, v := range kset { - t.Logf("(%d)[%v]%v", i, hex.EncodeToString(v[:]), idxs[v]) + t.Logf("(%d)[%v]%v", i, hex.Encode(v[:]), idxs[v]) } assert.Equal(t, -1, idxs[k0].peek()) diff --git a/state/statedata.go b/state/statedata.go index d4756c603..2c4f47478 100644 --- a/state/statedata.go +++ b/state/statedata.go @@ -1,12 +1,10 @@ package state import ( - "bytes" - "encoding/gob" - "github.com/aergoio/aergo-lib/db" + "github.com/aergoio/aergo/v2/internal/enc/gob" + "github.com/aergoio/aergo/v2/internal/enc/proto" "github.com/aergoio/aergo/v2/types" - "github.com/golang/protobuf/proto" ) func saveData(store db.DB, key []byte, data interface{}) error { @@ -19,18 +17,12 @@ func saveData(store db.DB, key []byte, data interface{}) error { case ([]byte): raw = data.([]byte) case proto.Message: - raw, err = proto.Marshal(data.(proto.Message)) + raw, err = proto.Encode(data.(proto.Message)) if err != nil { return err } default: - buffer := &bytes.Buffer{} - enc := gob.NewEncoder(buffer) - err = enc.Encode(data) - if err != nil { - return err - } - raw = buffer.Bytes() + raw, err = gob.Encode(data) if err != nil { return err } @@ -53,11 +45,9 @@ func loadData(store db.DB, key []byte, data interface{}) error { case *[]byte: *(data).(*[]byte) = raw case proto.Message: - err = proto.Unmarshal(raw, data.(proto.Message)) + err = proto.Decode(raw, data.(proto.Message)) default: - reader := bytes.NewReader(raw) - dec := gob.NewDecoder(reader) - err = dec.Decode(data) + err = gob.Decode(raw, data) } return err } diff --git a/state/statedb.go b/state/statedb.go index 4bd37dbef..eefd82874 100644 --- a/state/statedb.go +++ b/state/statedb.go @@ -15,7 +15,7 @@ import ( "github.com/aergoio/aergo-lib/db" "github.com/aergoio/aergo-lib/log" "github.com/aergoio/aergo/v2/internal/common" - "github.com/aergoio/aergo/v2/internal/enc" + "github.com/aergoio/aergo/v2/internal/enc/base58" "github.com/aergoio/aergo/v2/pkg/trie" "github.com/aergoio/aergo/v2/types" ) @@ -224,6 +224,10 @@ func (v *V) IsNew() bool { return v.newOne } +func (v *V) IsContract() bool { + return len(v.State().CodeHash) > 0 +} + func (v *V) IsDeploy() bool { return v.deploy&deployFlag != 0 } @@ -397,7 +401,7 @@ func (states *StateDB) GetVarAndProof(id []byte, root []byte, compressed bool) ( Height: uint32(height), AuditPath: ap, } - logger.Debug().Str("contract root : ", enc.ToString(root)).Msg("Get contract variable and Proof") + logger.Debug().Str("contract root : ", base58.Encode(root)).Msg("Get contract variable and Proof") return contractVarProof, nil } @@ -427,7 +431,7 @@ func (states *StateDB) GetAccountAndProof(id []byte, root []byte, compressed boo Height: uint32(height), AuditPath: ap, } - logger.Debug().Str("state root : ", enc.ToString(root)).Msg("Get Account and Proof") + logger.Debug().Str("state root : ", base58.Encode(root)).Msg("Get Account and Proof") return accountProof, nil } @@ -549,7 +553,7 @@ func (states *StateDB) HasMarker(root []byte) bool { } marker := states.store.Get(common.Hasher(root)) if marker != nil && bytes.Equal(marker, stateMarker) { - // logger.Debug().Str("stateRoot", enc.ToString(root)).Str("marker", hex.EncodeToString(marker)).Msg("IsMarked") + // logger.Debug().Str("stateRoot", enc.ToString(root)).Str("marker", hex.HexEncode(marker)).Msg("IsMarked") return true } return false diff --git a/state/storage.go b/state/storage.go index 2eea7404d..03d8dd433 100644 --- a/state/storage.go +++ b/state/storage.go @@ -6,7 +6,7 @@ import ( "github.com/aergoio/aergo-lib/db" "github.com/aergoio/aergo/v2/internal/common" - "github.com/aergoio/aergo/v2/internal/enc" + "github.com/aergoio/aergo/v2/internal/enc/base58" "github.com/aergoio/aergo/v2/pkg/trie" "github.com/aergoio/aergo/v2/types" ) @@ -134,8 +134,8 @@ func (storage *bufferedStorage) update() error { return err } if !bytes.Equal(before, storage.trie.Root) { - logger.Debug().Str("before", enc.ToString(before)). - Str("after", enc.ToString(storage.trie.Root)).Msg("Changed storage trie root") + logger.Debug().Str("before", base58.Encode(before)). + Str("after", base58.Encode(storage.trie.Root)).Msg("Changed storage trie root") storage.dirty = true } return nil diff --git a/syncer/blockfetcher.go b/syncer/blockfetcher.go index fbe64018c..9e6c1d541 100644 --- a/syncer/blockfetcher.go +++ b/syncer/blockfetcher.go @@ -9,7 +9,7 @@ import ( "sync/atomic" "time" - "github.com/aergoio/aergo/v2/internal/enc" + "github.com/aergoio/aergo/v2/internal/enc/base58" "github.com/aergoio/aergo/v2/message" "github.com/aergoio/aergo/v2/pkg/component" "github.com/aergoio/aergo/v2/types" @@ -342,7 +342,7 @@ func (bf *BlockFetcher) checkTaskTimeout() error { return err } - logger.Error().Uint64("StartNo", task.startNo).Str("start", enc.ToString(task.hashes[0])).Int("cout", task.count).Int("runqueue", bf.runningQueue.Len()).Int("pendingqueue", bf.pendingQueue.Len()). + logger.Error().Uint64("StartNo", task.startNo).Str("start", base58.Encode(task.hashes[0])).Int("cout", task.count).Int("runqueue", bf.runningQueue.Len()).Int("pendingqueue", bf.pendingQueue.Len()). Msg("timeouted task pushed to pending queue") //time.Sleep(10000*time.Second) @@ -358,7 +358,7 @@ func (bf *BlockFetcher) processFailedTask(task *FetchTask, isErr bool) error { } } - logger.Error().Int("peerno", task.syncPeer.No).Uint64("StartNo", task.startNo).Str("start", enc.ToString(task.hashes[0])).Msg("task fail, move to retry queue") + logger.Error().Int("peerno", task.syncPeer.No).Uint64("StartNo", task.startNo).Str("start", base58.Encode(task.hashes[0])).Msg("task fail, move to retry queue") failPeer := task.syncPeer @@ -380,7 +380,7 @@ func (bf *BlockFetcher) processFailedTask(task *FetchTask, isErr bool) error { } func (bf *BlockFetcher) popNextTask(task *FetchTask) { - logger.Debug().Int("retry", task.retry).Uint64("StartNo", task.startNo).Str("start", enc.ToString(task.hashes[0])).Str("end", enc.ToString(task.hashes[task.count-1])). + logger.Debug().Int("retry", task.retry).Uint64("StartNo", task.startNo).Str("start", base58.Encode(task.hashes[0])).Str("end", base58.Encode(task.hashes[task.count-1])). Int("tasks retry", bf.retryQueue.Len()).Int("tasks pending", bf.pendingQueue.Len()).Msg("next fetchtask") var poppedTask *FetchTask @@ -427,7 +427,7 @@ func (bf *BlockFetcher) searchCandidateTask() (*FetchTask, error) { start, end := 0, 0 count := hashSet.Count - logger.Debug().Uint64("startno", hashSet.StartNo).Str("start", enc.ToString(hashSet.Hashes[0])).Int("count", hashSet.Count).Msg("add new fetchtasks from HashSet") + logger.Debug().Uint64("startno", hashSet.StartNo).Str("start", base58.Encode(hashSet.Hashes[0])).Int("count", hashSet.Count).Msg("add new fetchtasks from HashSet") for start < count { end = start + bf.maxFetchSize @@ -464,7 +464,7 @@ func (bf *BlockFetcher) searchCandidateTask() (*FetchTask, error) { return nil, nil } - logger.Debug().Uint64("startno", hashSet.StartNo).Array("hashes", &LogBlockHashesMarshaller{hashSet.Hashes, 10}).Str("start", enc.ToString(hashSet.Hashes[0])).Int("count", hashSet.Count).Msg("BlockFetcher got hashset") + logger.Debug().Uint64("startno", hashSet.StartNo).Array("hashes", &LogBlockHashesMarshaller{hashSet.Hashes, 10}).Str("start", base58.Encode(hashSet.Hashes[0])).Int("count", hashSet.Count).Msg("BlockFetcher got hashset") bf.curHashSet = hashSet addNewFetchTasks(hashSet) @@ -488,12 +488,12 @@ func (m LogBlockHashesMarshaller) MarshalZerologArray(a *zerolog.Array) { size := len(m.arr) if size > m.limit { for i := 0; i < m.limit-1; i++ { - a.Str(enc.ToString(m.arr[i])) + a.Str(base58.Encode(m.arr[i])) } a.Str(fmt.Sprintf("(and %d more)", size-m.limit+1)) } else { for _, element := range m.arr { - a.Str(enc.ToString(element)) + a.Str(base58.Encode(element)) } } } @@ -533,7 +533,7 @@ func (bf *BlockFetcher) runTask(task *FetchTask, peer *SyncPeer) { task.syncPeer = peer bf.runningQueue.PushBack(task) - logger.Debug().Int("peerno", task.syncPeer.No).Int("count", task.count).Uint64("StartNo", task.startNo).Str("start", enc.ToString(task.hashes[0])).Int("runqueue", bf.runningQueue.Len()).Msg("send block fetch request") + logger.Debug().Int("peerno", task.syncPeer.No).Int("count", task.count).Uint64("StartNo", task.startNo).Str("start", base58.Encode(task.hashes[0])).Int("runqueue", bf.runningQueue.Len()).Msg("send block fetch request") bf.compRequester.TellTo(message.P2PSvc, &message.GetBlockChunks{Seq: bf.GetSeq(), GetBlockInfos: message.GetBlockInfos{ToWhom: peer.ID, Hashes: task.hashes}, TTL: DfltFetchTimeOut}) } @@ -553,7 +553,7 @@ func (bf *BlockFetcher) findFinished(msg *message.GetBlockChunksRsp, peerMatch b if task.isPeerMatched(msg.ToWhom) { bf.runningQueue.Remove(e) - logger.Debug().Stringer("peer", types.LogPeerShort(msg.ToWhom)).Err(msg.Err).Str("start", enc.ToString(task.hashes[0])).Int("count", task.count).Int("runqueue", bf.runningQueue.Len()).Msg("task finished with error") + logger.Debug().Stringer("peer", types.LogPeerShort(msg.ToWhom)).Err(msg.Err).Str("start", base58.Encode(task.hashes[0])).Int("count", task.count).Int("runqueue", bf.runningQueue.Len()).Msg("task finished with error") return task, nil } } else { @@ -561,7 +561,7 @@ func (bf *BlockFetcher) findFinished(msg *message.GetBlockChunksRsp, peerMatch b if task.isMatched(msg.ToWhom, msg.Blocks, count) { bf.runningQueue.Remove(e) - logger.Debug().Uint64("StartNo", task.startNo).Str("start", enc.ToString(task.hashes[0])).Int("count", task.count).Int("runqueue", bf.runningQueue.Len()). + logger.Debug().Uint64("StartNo", task.startNo).Str("start", base58.Encode(task.hashes[0])).Int("count", task.count).Int("runqueue", bf.runningQueue.Len()). Msg("task finished") return task, nil @@ -737,7 +737,7 @@ func (tq *TaskQueue) Peek() *FetchTask { func (task *FetchTask) isTimeOut(now time.Time, timeout time.Duration) bool { if now.Sub(task.started) > timeout { - logger.Info().Int("peerno", task.syncPeer.No).Uint64("startno", task.startNo).Str("start", enc.ToString(task.hashes[0])).Int("cout", task.count).Msg("FetchTask peer timeouted") + logger.Info().Int("peerno", task.syncPeer.No).Uint64("startno", task.startNo).Str("start", base58.Encode(task.hashes[0])).Int("cout", task.count).Msg("FetchTask peer timeouted") return true } @@ -756,7 +756,7 @@ func (task *FetchTask) isMatched(peerID types.PeerID, blocks []*types.Block, cou for i, block := range blocks { if bytes.Compare(task.hashes[i], block.GetHash()) != 0 { - logger.Info().Int("peerno", task.syncPeer.No).Str("hash", enc.ToString(task.hashes[0])).Int("idx", i).Msg("task hash mismatch") + logger.Info().Int("peerno", task.syncPeer.No).Str("hash", base58.Encode(task.hashes[0])).Int("idx", i).Msg("task hash mismatch") return false } } diff --git a/syncer/blockprocessor.go b/syncer/blockprocessor.go index b533bc49c..cac892da5 100644 --- a/syncer/blockprocessor.go +++ b/syncer/blockprocessor.go @@ -6,7 +6,7 @@ import ( "sort" "github.com/aergoio/aergo/v2/chain" - "github.com/aergoio/aergo/v2/internal/enc" + "github.com/aergoio/aergo/v2/internal/enc/base58" "github.com/aergoio/aergo/v2/message" "github.com/aergoio/aergo/v2/pkg/component" "github.com/aergoio/aergo/v2/types" @@ -136,8 +136,8 @@ func (bproc *BlockProcessor) GetBlockChunkRsp(msg *message.GetBlockChunksRsp) er //TODO invalid peer logger.Error().Stringer("peer", types.LogPeerShort(msg.ToWhom)). Int("count", len(msg.Blocks)). - Str("from", enc.ToString(msg.Blocks[0].GetHash())). - Str("to", enc.ToString(msg.Blocks[len(msg.Blocks)-1].GetHash())). + Str("from", base58.Encode(msg.Blocks[0].GetHash())). + Str("to", base58.Encode(msg.Blocks[len(msg.Blocks)-1].GetHash())). Msg("dropped unknown block response message") return nil } @@ -172,7 +172,7 @@ func (bproc *BlockProcessor) GetBlockChunkRspError(msg *message.GetBlockChunksRs func (bproc *BlockProcessor) AddBlockResponse(msg *message.AddBlockRsp) error { if err := bproc.isValidResponse(msg); err != nil { - logger.Info().Err(err).Uint64("no", msg.BlockNo).Str("hash", enc.ToString(msg.BlockHash)).Msg("block connect failed") + logger.Info().Err(err).Uint64("no", msg.BlockNo).Str("hash", base58.Encode(msg.BlockHash)).Msg("block connect failed") return err } @@ -182,12 +182,12 @@ func (bproc *BlockProcessor) AddBlockResponse(msg *message.AddBlockRsp) error { if curNo != msg.BlockNo || !bytes.Equal(curHash, msg.BlockHash) { logger.Error().Uint64("curNo", curNo).Uint64("msgNo", msg.BlockNo). - Str("curHash", enc.ToString(curHash)).Str("msgHash", enc.ToString(msg.BlockHash)). + Str("curHash", base58.Encode(curHash)).Str("msgHash", base58.Encode(msg.BlockHash)). Msg("invalid add block response") return &ErrSyncMsg{msg: msg, str: "drop unknown add response"} } - logger.Info().Uint64("no", msg.BlockNo).Str("hash", enc.ToString(msg.BlockHash)).Msg("block connect succeed") + logger.Info().Uint64("no", msg.BlockNo).Str("hash", base58.Encode(msg.BlockHash)).Msg("block connect succeed") bproc.blockFetcher.stat.setLastAddBlock(curBlock) @@ -266,7 +266,7 @@ func (bproc *BlockProcessor) connectBlock(block *types.Block) { } logger.Info().Uint64("no", block.GetHeader().BlockNo). - Str("hash", enc.ToString(block.GetHash())). + Str("hash", base58.Encode(block.GetHash())). Msg("request connecting block to chainsvc") bproc.compRequester.RequestTo(message.ChainSvc, &message.AddBlock{PeerID: "", Block: block, Bstate: nil, IsSync: true}) @@ -283,7 +283,7 @@ func (bproc *BlockProcessor) pushToConnQueue(newReq *ConnectTask) { bproc.connQueue = sortedList logger.Info().Int("len", len(bproc.connQueue)).Uint64("firstno", newReq.firstNo). - Str("firstHash", enc.ToString(newReq.Blocks[0].GetHash())). + Str("firstHash", base58.Encode(newReq.Blocks[0].GetHash())). Msg("add new task to connect queue") } @@ -307,7 +307,7 @@ func (bproc *BlockProcessor) popFromConnQueue() *ConnectTask { bproc.connQueue = sortedList logger.Info().Int("len", len(sortedList)).Uint64("firstno", newReq.firstNo). - Str("firstHash", enc.ToString(newReq.Blocks[0].GetHash())). + Str("firstHash", base58.Encode(newReq.Blocks[0].GetHash())). Msg("pop task from connect queue") return newReq diff --git a/syncer/finder.go b/syncer/finder.go index 70a179a38..a99ae1fe9 100644 --- a/syncer/finder.go +++ b/syncer/finder.go @@ -6,7 +6,7 @@ import ( "time" "github.com/aergoio/aergo/v2/chain" - "github.com/aergoio/aergo/v2/internal/enc" + "github.com/aergoio/aergo/v2/internal/enc/base58" "github.com/aergoio/aergo/v2/message" "github.com/aergoio/aergo/v2/pkg/component" "github.com/aergoio/aergo/v2/types" @@ -140,7 +140,7 @@ func (finder *Finder) lightscan() (*types.BlockInfo, error) { if ancestor == nil { logger.Debug().Msg("not found ancestor in lightscan") } else { - logger.Info().Str("hash", enc.ToString(ancestor.Hash)).Uint64("no", ancestor.No).Msg("find ancestor in lightscan") + logger.Info().Str("hash", base58.Encode(ancestor.Hash)).Uint64("no", ancestor.No).Msg("find ancestor in lightscan") if ancestor.No >= finder.ctx.TargetNo { logger.Info().Msg("already synchronized") @@ -163,7 +163,7 @@ func (finder *Finder) getAnchors() ([][]byte, error) { finder.ctx.LastAnchor = result.(message.GetAnchorsRsp).LastNo } - logger.Info().Str("start", enc.ToString(anchors[0])).Int("count", len(anchors)).Uint64("last", finder.ctx.LastAnchor).Msg("get anchors from chain") + logger.Info().Str("start", base58.Encode(anchors[0])).Int("count", len(anchors)).Uint64("last", finder.ctx.LastAnchor).Msg("get anchors from chain") return anchors, nil } @@ -204,7 +204,7 @@ func (finder *Finder) fullscan() (*types.BlockInfo, error) { if ancestor == nil { logger.Info().Msg("failed to search ancestor in fullscan") } else { - logger.Info().Uint64("no", ancestor.No).Str("hash", enc.ToString(ancestor.Hash)).Msg("find ancestor in fullscan") + logger.Info().Uint64("no", ancestor.No).Str("hash", base58.Encode(ancestor.Hash)).Msg("find ancestor in fullscan") } return ancestor, err diff --git a/syncer/hashfetcher.go b/syncer/hashfetcher.go index 3892bd130..4097b4eae 100644 --- a/syncer/hashfetcher.go +++ b/syncer/hashfetcher.go @@ -4,7 +4,7 @@ import ( "sync" "time" - "github.com/aergoio/aergo/v2/internal/enc" + "github.com/aergoio/aergo/v2/internal/enc/base58" "github.com/aergoio/aergo/v2/message" "github.com/aergoio/aergo/v2/pkg/component" "github.com/aergoio/aergo/v2/types" @@ -171,7 +171,7 @@ func (hf *HashFetcher) requestHashSet() { hf.reqTime = time.Now() hf.isRequesting = true - logger.Debug().Uint64("prev", hf.lastBlockInfo.No).Str("prevhash", enc.ToString(hf.lastBlockInfo.Hash)).Uint64("count", count).Msg("request hashset to peer") + logger.Debug().Uint64("prev", hf.lastBlockInfo.No).Str("prevhash", base58.Encode(hf.lastBlockInfo.Hash)).Uint64("count", count).Msg("request hashset to peer") hf.compRequester.TellTo(message.P2PSvc, &message.GetHashes{Seq: hf.GetSeq(), ToWhom: hf.ctx.PeerID, PrevInfo: hf.lastBlockInfo, Count: count}) } @@ -241,8 +241,8 @@ func (hf *HashFetcher) isValidResponse(msg *message.GetHashesRsp) (bool, error) } if !isValid { - logger.Error().Str("req prev", enc.ToString(hf.lastBlockInfo.Hash)). - Str("msg prev", enc.ToString(msg.PrevInfo.Hash)). + logger.Error().Str("req prev", base58.Encode(hf.lastBlockInfo.Hash)). + Str("msg prev", base58.Encode(msg.PrevInfo.Hash)). Uint64("req count", hf.reqCount). Uint64("msg count", msg.Count). Msg("invalid GetHashesRsp") @@ -267,8 +267,8 @@ func (hf *HashFetcher) GetHahsesRsp(msg *message.GetHashesRsp) { logger.Debug().Int("count", count). Uint64("prev", msg.PrevInfo.No). - Str("start", enc.ToString(msg.Hashes[0])). - Str("end", enc.ToString(msg.Hashes[count-1])).Msg("receive GetHashesRsp") + Str("start", base58.Encode(msg.Hashes[0])). + Str("end", base58.Encode(msg.Hashes[count-1])).Msg("receive GetHashesRsp") hf.responseCh <- msg return diff --git a/tests/bp01.id b/tests/bp01.id new file mode 100644 index 000000000..e6b88a555 --- /dev/null +++ b/tests/bp01.id @@ -0,0 +1 @@ +16Uiu2HAmG4PSXYUxkPbNb7qTcEExFpgAwBrm3hB32aJXuvX2f1sd \ No newline at end of file diff --git a/tests/bp01.key b/tests/bp01.key new file mode 100644 index 000000000..8ab66a8aa --- /dev/null +++ b/tests/bp01.key @@ -0,0 +1 @@ + A<žiTÎB-:»1J è\»GÒø1³„ T'ƒÇ \ No newline at end of file diff --git a/tests/bp01.pub b/tests/bp01.pub new file mode 100644 index 000000000..d42833955 Binary files /dev/null and b/tests/bp01.pub differ diff --git a/tests/bp02.id b/tests/bp02.id new file mode 100644 index 000000000..102b8a198 --- /dev/null +++ b/tests/bp02.id @@ -0,0 +1 @@ +16Uiu2HAmMzncFmnpjigZJRoraToKkABvZimMUAyXf6bdrZeN7mbJ \ No newline at end of file diff --git a/tests/bp02.key b/tests/bp02.key new file mode 100644 index 000000000..9c9f8c626 --- /dev/null +++ b/tests/bp02.key @@ -0,0 +1,2 @@ + †5 +&¶ÊÓd½fã#[k©1~‹ ÔĽÕ=Âî¥ \ No newline at end of file diff --git a/tests/bp02.pub b/tests/bp02.pub new file mode 100644 index 000000000..f9627f3fc --- /dev/null +++ b/tests/bp02.pub @@ -0,0 +1 @@ +!ŠË…–’û:^ØpàBúX̾°´ß¥2/·íý~Õ \ No newline at end of file diff --git a/tests/bp03.id b/tests/bp03.id new file mode 100644 index 000000000..ce5e264a5 --- /dev/null +++ b/tests/bp03.id @@ -0,0 +1 @@ +16Uiu2HAmKB7RYXe1uHNYMtkuuM2fEHxsv6P9PZ45ogJw6aZD3y7x \ No newline at end of file diff --git a/tests/bp03.key b/tests/bp03.key new file mode 100644 index 000000000..769f934f5 --- /dev/null +++ b/tests/bp03.key @@ -0,0 +1 @@ + ⧾o¸{Vã©IÔ–uÒQ»Ñö7¹˜6$MÏÅøpÐGº \ No newline at end of file diff --git a/tests/bp03.pub b/tests/bp03.pub new file mode 100644 index 000000000..8704fcc3d --- /dev/null +++ b/tests/bp03.pub @@ -0,0 +1 @@ +!`Ý‹/½|t¦iþ™+ãյ͚ÙýBƒ5mHK4[EC \ No newline at end of file diff --git a/tests/common.sh b/tests/common.sh index bd5abe899..07f573593 100644 --- a/tests/common.sh +++ b/tests/common.sh @@ -1,4 +1,68 @@ +start_nodes() { + + if [ "$consensus" == "sbp" ]; then + # open the aergo node in testmode + ../bin/aergosvr --testmode --home ./aergo-files > logs 2> logs & + pid=$! + else + # open the 3 nodes + ../bin/aergosvr --home ./node1 >> logs1 2>> logs1 & + pid1=$! + ../bin/aergosvr --home ./node2 >> logs2 2>> logs2 & + pid2=$! + ../bin/aergosvr --home ./node3 >> logs3 2>> logs3 & + pid3=$! + fi + +} + +stop_nodes() { + + if [ "$consensus" == "sbp" ]; then + kill $pid + else + kill $pid1 $pid2 $pid3 + fi + +} + +wait_version() { + expect_version=$1 + counter=0 + # do not stop on errors + set +e + + while true; do + # get the current hardfork version + output=$(../bin/aergocli blockchain 2>/dev/null) + # check if 'output' is non-empty and starts with '{' + if [[ -n "$output" ]] && [[ "${output:0:1}" == "{" ]]; then + cur_version=$(echo "$output" | jq .ChainInfo.Chainid.Version | sed 's/"//g') + else + cur_version=0 + fi + + #echo "current version: $cur_version" + + if [ $cur_version -eq $expect_version ]; then + version=$expect_version + break + else + sleep 0.5 + counter=$((counter+1)) + if [ $counter -gt 20 ]; then + echo "Failed to change the blockchain version on the nodes" + echo "Desired: $expect_version, Actual: $cur_version" + exit 1 + fi + fi + done + + # stop on errors + set -e +} + get_deploy_args() { contract_file=$1 @@ -24,10 +88,11 @@ deploy() { get_receipt() { txhash=$1 counter=0 + # do not stop on errors set +e while true; do - output=$(../bin/aergocli receipt get $txhash 2>&1 > receipt.json) + output=$(../bin/aergocli receipt get --port $query_port $txhash 2>&1 > receipt.json) #echo "output: $output" @@ -38,7 +103,6 @@ get_receipt() { echo "Error: tx not found: $txhash" exit 1 fi - continue elif [[ -n $output ]]; then echo "Error: $output" exit 1 @@ -47,6 +111,7 @@ get_receipt() { fi done + # stop on errors set -e } diff --git a/tests/config-node1.toml b/tests/config-node1.toml new file mode 100644 index 000000000..8ffb68f7e --- /dev/null +++ b/tests/config-node1.toml @@ -0,0 +1,48 @@ +# aergo TOML Configuration File (https://github.com/toml-lang/toml) +# base configurations +enableprofile = false + +[rpc] +netserviceaddr = "0.0.0.0" +netserviceport = 7845 +netservicetrace = false +nstls = false +nscert = "" +nskey = "" +nsallowcors = false + +[p2p] +netprotocoladdr = "127.0.0.1" +netprotocolport = 2001 +npbindaddr = "0.0.0.0" +npbindport = 2001 +nptls = false +npcert = "" +npkey = "bp01.key" +npaddpeers = [ +#"/ip4/127.0.0.1/tcp/2001/p2p/16Uiu2HAmG4PSXYUxkPbNb7qTcEExFpgAwBrm3hB32aJXuvX2f1sd", +"/ip4/127.0.0.1/tcp/2002/p2p/16Uiu2HAmMzncFmnpjigZJRoraToKkABvZimMUAyXf6bdrZeN7mbJ", +"/ip4/127.0.0.1/tcp/2003/p2p/16Uiu2HAmKB7RYXe1uHNYMtkuuM2fEHxsv6P9PZ45ogJw6aZD3y7x" +] +npexposeself = false +npdiscoverpeers = false +npusepolaris = false +peerrole = "producer" + +[blockchain] +maxblocksize = 1000000 + +[mempool] +showmetrics = false + +[consensus] +enablebp = true + +[consensus.raft] +newcluster=true +name="bp01" + +[hardfork] +v2 = "0" +v3 = "10000" +v4 = "10000" diff --git a/tests/config-node2.toml b/tests/config-node2.toml new file mode 100644 index 000000000..f68988e37 --- /dev/null +++ b/tests/config-node2.toml @@ -0,0 +1,48 @@ +# aergo TOML Configuration File (https://github.com/toml-lang/toml) +# base configurations +enableprofile = false + +[rpc] +netserviceaddr = "0.0.0.0" +netserviceport = 8845 +netservicetrace = false +nstls = false +nscert = "" +nskey = "" +nsallowcors = false + +[p2p] +netprotocoladdr = "127.0.0.1" +netprotocolport = 2002 +npbindaddr = "0.0.0.0" +npbindport = 2002 +nptls = false +npcert = "" +npkey = "bp02.key" +npaddpeers = [ +"/ip4/127.0.0.1/tcp/2001/p2p/16Uiu2HAmG4PSXYUxkPbNb7qTcEExFpgAwBrm3hB32aJXuvX2f1sd", +#"/ip4/127.0.0.1/tcp/2002/p2p/16Uiu2HAmMzncFmnpjigZJRoraToKkABvZimMUAyXf6bdrZeN7mbJ", +"/ip4/127.0.0.1/tcp/2003/p2p/16Uiu2HAmKB7RYXe1uHNYMtkuuM2fEHxsv6P9PZ45ogJw6aZD3y7x" +] +npexposeself = false +npdiscoverpeers = false +npusepolaris = false +peerrole = "producer" + +[blockchain] +maxblocksize = 1000000 + +[mempool] +showmetrics = false + +[consensus] +enablebp = true + +[consensus.raft] +newcluster=true +name="bp02" + +[hardfork] +v2 = "0" +v3 = "10000" +v4 = "10000" diff --git a/tests/config-node3.toml b/tests/config-node3.toml new file mode 100644 index 000000000..888aca265 --- /dev/null +++ b/tests/config-node3.toml @@ -0,0 +1,48 @@ +# aergo TOML Configuration File (https://github.com/toml-lang/toml) +# base configurations +enableprofile = false + +[rpc] +netserviceaddr = "0.0.0.0" +netserviceport = 9845 +netservicetrace = false +nstls = false +nscert = "" +nskey = "" +nsallowcors = false + +[p2p] +netprotocoladdr = "127.0.0.1" +netprotocolport = 2003 +npbindaddr = "0.0.0.0" +npbindport = 2003 +nptls = false +npcert = "" +npkey = "bp03.key" +npaddpeers = [ +"/ip4/127.0.0.1/tcp/2001/p2p/16Uiu2HAmG4PSXYUxkPbNb7qTcEExFpgAwBrm3hB32aJXuvX2f1sd", +"/ip4/127.0.0.1/tcp/2002/p2p/16Uiu2HAmMzncFmnpjigZJRoraToKkABvZimMUAyXf6bdrZeN7mbJ" +#"/ip4/127.0.0.1/tcp/2003/p2p/16Uiu2HAmKB7RYXe1uHNYMtkuuM2fEHxsv6P9PZ45ogJw6aZD3y7x" +] +npexposeself = false +npdiscoverpeers = false +npusepolaris = false +peerrole = "producer" + +[blockchain] +maxblocksize = 1000000 + +[mempool] +showmetrics = false + +[consensus] +enablebp = true + +[consensus.raft] +newcluster=true +name="bp03" + +[hardfork] +v2 = "0" +v3 = "10000" +v4 = "10000" diff --git a/tests/config.toml b/tests/config-sbp.toml similarity index 99% rename from tests/config.toml rename to tests/config-sbp.toml index 793fe86e8..10b3304d7 100644 --- a/tests/config.toml +++ b/tests/config-sbp.toml @@ -81,3 +81,4 @@ enablelocalconf = "false" [hardfork] v2 = "0" v3 = "10000" +v4 = "10000" diff --git a/tests/genesis-dpos.json b/tests/genesis-dpos.json new file mode 100644 index 000000000..da860252f --- /dev/null +++ b/tests/genesis-dpos.json @@ -0,0 +1,17 @@ +{ + "chain_id":{ + "magic":"test.chain", + "public":true, + "mainnet":false, + "consensus":"dpos" + }, + "timestamp": 1559883600000000000, + "balance": { + "AmPpcKvToDCUkhT1FJjdbNvR4kNDhLFJGHkSqfjWe3QmHm96qv4R": "1000000000000000000000" + }, + "bps": [ + "16Uiu2HAmG4PSXYUxkPbNb7qTcEExFpgAwBrm3hB32aJXuvX2f1sd", + "16Uiu2HAmMzncFmnpjigZJRoraToKkABvZimMUAyXf6bdrZeN7mbJ", + "16Uiu2HAmKB7RYXe1uHNYMtkuuM2fEHxsv6P9PZ45ogJw6aZD3y7x" + ] +} diff --git a/tests/genesis-raft.json b/tests/genesis-raft.json new file mode 100644 index 000000000..c996b3590 --- /dev/null +++ b/tests/genesis-raft.json @@ -0,0 +1,31 @@ +{ + "chain_id":{ + "magic":"test.chain", + "public":true, + "mainnet":false, + "consensus":"raft" + }, + "timestamp": 1559883600000000000, + "balance": { + "AmPpcKvToDCUkhT1FJjdbNvR4kNDhLFJGHkSqfjWe3QmHm96qv4R": "1000000000000000000000" + }, + "bps": [ + ], + "enterprise_bps": [ + { + "name": "bp01", + "address": "/ip4/127.0.0.1/tcp/2001", + "peerid": "16Uiu2HAmG4PSXYUxkPbNb7qTcEExFpgAwBrm3hB32aJXuvX2f1sd" + }, + { + "name": "bp02", + "address": "/ip4/127.0.0.1/tcp/2002", + "peerid": "16Uiu2HAmMzncFmnpjigZJRoraToKkABvZimMUAyXf6bdrZeN7mbJ" + }, + { + "name": "bp03", + "address": "/ip4/127.0.0.1/tcp/2003", + "peerid": "16Uiu2HAmKB7RYXe1uHNYMtkuuM2fEHxsv6P9PZ45ogJw6aZD3y7x" + } + ] +} diff --git a/tests/run_tests.sh b/tests/run_tests.sh index 0089ec715..f212dac71 100755 --- a/tests/run_tests.sh +++ b/tests/run_tests.sh @@ -1,24 +1,72 @@ # stop on errors set -e +source common.sh -# run the brick test -./test-brick.sh +arg=$1 +if [ "$arg" != "sbp" ] && [ "$arg" != "dpos" ] && [ "$arg" != "raft" ] && [ "$arg" != "brick" ]; then + echo "Usage: $0 [brick|sbp|dpos|raft]" + exit 1 +fi +echo "Running integration tests for $arg" -# delete and recreate the aergo folder -rm -rf ./aergo-files -mkdir aergo-files -# copy the config file -cp config.toml ./aergo-files/ +if [ "$arg" == "brick" ]; then + # run the brick test + ../bin/brick -V test.brick + exit 0 +fi -# open the aergo server in testmode to create the config file -echo "" -echo "starting the aergo server..." -../bin/aergosvr --testmode --home ./aergo-files > logs 2> logs & -pid=$! -# wait it to be ready -sleep 2 +consensus=$arg + +if [ "$consensus" == "sbp" ]; then + # delete and recreate the aergo folder + rm -rf ./aergo-files + mkdir aergo-files + # copy the config file + cp config-sbp.toml ./aergo-files/config.toml + # delete the old logs + rm -f logs +else + # delete and recreate the aergo folder + rm -rf node1 + rm -rf node2 + rm -rf node3 + mkdir node1 + mkdir node2 + mkdir node3 + # copy the config files + cp config-node1.toml node1/config.toml + cp config-node2.toml node2/config.toml + cp config-node3.toml node3/config.toml + # delete the old logs + rm -f logs1 logs2 logs3 + # create the genesis block + echo "creating genesis block..." + ../bin/aergosvr init --genesis ./genesis-$consensus.json --home ./node1 + ../bin/aergosvr init --genesis ./genesis-$consensus.json --home ./node2 + ../bin/aergosvr init --genesis ./genesis-$consensus.json --home ./node3 +fi -version=$(../bin/aergocli blockchain | jq .ChainInfo.Chainid.Version | sed 's/"//g') +# define the config files according to the consensus +if [ "$consensus" == "sbp" ]; then + config_files=("./aergo-files/config.toml") +elif [ "$consensus" == "dpos" ]; then + config_files=("./node1/config.toml" "./node2/config.toml" "./node3/config.toml") +elif [ "$consensus" == "raft" ]; then + config_files=("./node1/config.toml" "./node2/config.toml" "./node3/config.toml") +fi + +# define which port used for queries +if [ "$consensus" == "sbp" ]; then + query_port="7845" +else + query_port="9845" +fi + +echo "" +echo "starting nodes..." +start_nodes +# wait the node(s) to be ready, expecting hardfork version 2 +wait_version 2 function set_version() { # stop on errors @@ -31,28 +79,18 @@ function set_version() { block_no=$(../bin/aergocli blockchain | jq .Height | sed 's/"//g') # increment 2 numbers block_no=$((block_no+2)) - # terminate the server process - kill $pid - # save the hardfork config on the config file - echo "updating the config file..." - if [ $version -eq 2 ]; then - sed -i "s/^v2 = \"10000\"$/v2 = \"${block_no}\"/" ./aergo-files/config.toml - elif [ $version -eq 3 ]; then - sed -i "s/^v3 = \"10000\"$/v3 = \"${block_no}\"/" ./aergo-files/config.toml - fi - # restart the aergo server - echo "restarting the aergo server..." - ../bin/aergosvr --testmode --home ./aergo-files > logs 2> logs & - pid=$! - # wait it to be ready - sleep 3 - # check if it worked - new_version=$(../bin/aergocli blockchain | jq .ChainInfo.Chainid.Version | sed 's/"//g') - if [ $new_version -ne $version ]; then - echo "Failed to change the blockchain version on the server" - echo "Desired: $version, Actual: $new_version" - exit 1 - fi + # terminate the server process(es) + stop_nodes + # save the hardfork config on the config file(s) + echo "updating the config file(s)..." + for config_file in "${config_files[@]}"; do + sed -i "s/^v$version = \"10000\"$/v$version = \"${block_no}\"/" $config_file + done + # restart the aergo nodes + echo "restarting the aergo nodes..." + start_nodes + # wait the node(s) to be ready, expecting the new hardfork version + wait_version $version echo "---------------------------------" # do not stop on errors set +e @@ -77,6 +115,10 @@ function check() { fi } +# make these variables accessible to the called scripts +export consensus +export query_port + # create the account used on tests echo "creating user account..." ../bin/aergocli account import --keystore . --if 47zh1byk8MqWkQo5y8dvbrex99ZMdgZqfydar7w2QQgQqc7YrmFsBuMeF1uHWa5TwA1ZwQ7V6 --password bmttest @@ -103,9 +145,9 @@ check ./test-contract-deploy.sh # terminate the server process echo "" -echo "closing the aergo server" +echo "closing the aergo nodes" echo "" -kill $pid +stop_nodes # print the summary if [ $num_failed_tests -gt 0 ]; then diff --git a/tests/test-brick.sh b/tests/test-brick.sh deleted file mode 100755 index 155dd32c6..000000000 --- a/tests/test-brick.sh +++ /dev/null @@ -1 +0,0 @@ -../bin/brick -V test.brick diff --git a/tests/test-gas-per-function-v2.sh b/tests/test-gas-per-function-v2.sh index 3fd16a4a8..40091b577 100755 --- a/tests/test-gas-per-function-v2.sh +++ b/tests/test-gas-per-function-v2.sh @@ -16,9 +16,26 @@ address=$(cat receipt.json | jq .contractAddress | sed 's/"//g') assert_equals "$status" "CREATED" +echo "-- transfer funds to the contract --" + +from=AmPpcKvToDCUkhT1FJjdbNvR4kNDhLFJGHkSqfjWe3QmHm96qv4R + +txhash=$(../bin/aergocli --keystore . --password bmttest \ + sendtx --from $from --to $address --amount 5aergo \ + | jq .hash | sed 's/"//g') + +get_receipt $txhash + +status=$(cat receipt.json | jq .status | sed 's/"//g') +ret=$(cat receipt.json | jq .ret | sed 's/"//g') + +assert_equals "$status" "SUCCESS" +assert_equals "$ret" "{}" + + echo "-- get account's nonce --" -account_state=$(../bin/aergocli getstate --address AmPpcKvToDCUkhT1FJjdbNvR4kNDhLFJGHkSqfjWe3QmHm96qv4R) +account_state=$(../bin/aergocli getstate --address $from) nonce=$(echo $account_state | jq .nonce | sed 's/"//g') @@ -141,7 +158,7 @@ add_test "system.getCreator" 135156 add_test "system.getOrigin" 135656 add_test "contract.send" 135716 -add_test "contract.balance" 135797 +#add_test "contract.balance" 135797 add_test "contract.deploy" 158752 add_test "contract.call" 149642 add_test "contract.pcall" 150563 diff --git a/tests/test-gas-per-function-v3.sh b/tests/test-gas-per-function-v3.sh index abe5ad2ee..35c39caff 100755 --- a/tests/test-gas-per-function-v3.sh +++ b/tests/test-gas-per-function-v3.sh @@ -16,9 +16,26 @@ address=$(cat receipt.json | jq .contractAddress | sed 's/"//g') assert_equals "$status" "CREATED" +echo "-- transfer funds to the contract --" + +from=AmPpcKvToDCUkhT1FJjdbNvR4kNDhLFJGHkSqfjWe3QmHm96qv4R + +txhash=$(../bin/aergocli --keystore . --password bmttest \ + sendtx --from $from --to $address --amount 5aergo \ + | jq .hash | sed 's/"//g') + +get_receipt $txhash + +status=$(cat receipt.json | jq .status | sed 's/"//g') +ret=$(cat receipt.json | jq .ret | sed 's/"//g') + +assert_equals "$status" "SUCCESS" +assert_equals "$ret" "{}" + + echo "-- get account's nonce --" -account_state=$(../bin/aergocli getstate --address AmPpcKvToDCUkhT1FJjdbNvR4kNDhLFJGHkSqfjWe3QmHm96qv4R) +account_state=$(../bin/aergocli getstate --address $from) nonce=$(echo $account_state | jq .nonce | sed 's/"//g') @@ -141,7 +158,7 @@ add_test "system.getCreator" 135156 add_test "system.getOrigin" 135656 add_test "contract.send" 135716 -add_test "contract.balance" 135797 +#add_test "contract.balance" 135797 add_test "contract.deploy" 158752 add_test "contract.call" 149642 add_test "contract.pcall" 150563 diff --git a/tests/test-gas-verify-proof.sh b/tests/test-gas-verify-proof.sh index 222069db7..98bd142c6 100755 --- a/tests/test-gas-verify-proof.sh +++ b/tests/test-gas-verify-proof.sh @@ -6,7 +6,7 @@ fork_version=$1 echo "-- deploy --" -deploy ../contract/vm_dummy/test_files/feature_luacryptoverifyproof.lua +deploy ../contract/vm_dummy/test_files/feature_crypto_verify_proof.lua get_receipt $txhash diff --git a/tools/genesisdump/main.go b/tools/genesisdump/main.go index 26de7d6ee..030cebe38 100644 --- a/tools/genesisdump/main.go +++ b/tools/genesisdump/main.go @@ -1,11 +1,11 @@ package main import ( - "encoding/hex" "encoding/json" "fmt" "os" + "github.com/aergoio/aergo/v2/internal/enc/hex" "github.com/aergoio/aergo/v2/types" ) @@ -41,6 +41,6 @@ func main() { panic(err) } - str := "\"" + hex.EncodeToString(bs) + "\"" + str := "\"" + hex.Encode(bs) + "\"" fmt.Println(str) } diff --git a/tools/mpdumpdiag/main.go b/tools/mpdumpdiag/main.go index 14f98adc8..56d5608e9 100644 --- a/tools/mpdumpdiag/main.go +++ b/tools/mpdumpdiag/main.go @@ -9,8 +9,8 @@ import ( "os" "github.com/aergoio/aergo/v2/cmd/aergocli/util" + "github.com/aergoio/aergo/v2/internal/enc/proto" "github.com/aergoio/aergo/v2/types" - "github.com/golang/protobuf/proto" "github.com/spf13/cobra" ) @@ -75,7 +75,7 @@ func runPrintCmd(cmd *cobra.Command, args []string) { break } - err = proto.Unmarshal(buffer, &buf) + err = proto.Decode(buffer, &buf) if err != nil { cmd.Println("error: unmarshall tx err, continue", err.Error()) continue @@ -112,7 +112,7 @@ func runGenCmd(cmd *cobra.Command, args []string) { txlist, err := util.ParseBase58Tx(b) for _, v := range txlist { var total_data []byte - data, err := proto.Marshal(v) + data, err := proto.Encode(v) if err != nil { cmd.Println("error: marshal failed", err.Error()) continue diff --git a/types/account.go b/types/account.go index 2512ca8cd..ecd58ef70 100644 --- a/types/account.go +++ b/types/account.go @@ -1,12 +1,12 @@ package types import ( - "encoding/hex" "errors" "fmt" "strings" - "github.com/anaskhan96/base58check" + "github.com/aergoio/aergo/v2/internal/enc/base58check" + "github.com/aergoio/aergo/v2/internal/enc/hex" ) const AddressLength = 33 @@ -50,7 +50,7 @@ func EncodeAddress(addr Address) string { if len(addr) != AddressLength { return string(addr) } - encoded, _ := base58check.Encode(fmt.Sprintf("%x", AddressVersion), hex.EncodeToString(addr)) + encoded, _ := base58check.Encode(fmt.Sprintf("%x", AddressVersion), hex.Encode(addr)) return encoded } @@ -72,7 +72,7 @@ func DecodeAddress(encodedAddr string) (Address, error) { if err != nil { return nil, err } - decodedBytes, err := hex.DecodeString(decodedString) + decodedBytes, err := hex.Decode(decodedString) if err != nil { return nil, err } @@ -95,7 +95,7 @@ func DecodeAddressBytes(decodedBytes []byte) (Address, error) { } func EncodePrivKey(key []byte) string { - encoded, _ := base58check.Encode(fmt.Sprintf("%x", PrivKeyVersion), hex.EncodeToString(key)) + encoded, _ := base58check.Encode(fmt.Sprintf("%x", PrivKeyVersion), hex.Encode(key)) return encoded } @@ -104,7 +104,7 @@ func DecodePrivKey(encodedKey string) ([]byte, error) { if err != nil { return nil, err } - decodedBytes, err := hex.DecodeString(decodedString) + decodedBytes, err := hex.Decode(decodedString) if err != nil { return nil, err } diff --git a/types/blockchain.go b/types/blockchain.go index 3de9e1bf3..e4905dc54 100644 --- a/types/blockchain.go +++ b/types/blockchain.go @@ -17,9 +17,9 @@ import ( "time" "github.com/aergoio/aergo/v2/internal/common" - "github.com/aergoio/aergo/v2/internal/enc" + "github.com/aergoio/aergo/v2/internal/enc/base58" + "github.com/aergoio/aergo/v2/internal/enc/proto" "github.com/aergoio/aergo/v2/internal/merkle" - "github.com/golang/protobuf/proto" "github.com/libp2p/go-libp2p-core/crypto" "github.com/minio/sha256-simd" ) @@ -452,14 +452,14 @@ func (block *Block) BPID2Str() string { return "" } - return enc.ToString([]byte(id)) + return base58.Encode([]byte(id)) } // ID returns the base64 encoded formated ID (hash) of block. func (block *Block) ID() string { hash := block.BlockHash() if hash != nil { - return enc.ToString(hash) + return base58.Encode(hash) } return "" @@ -470,7 +470,7 @@ func (block *Block) ID() string { func (block *Block) PrevID() string { hash := block.GetHeader().GetPrevBlockHash() if hash != nil { - return enc.ToString(hash) + return base58.Encode(hash) } return "" diff --git a/types/blockchain_test.go b/types/blockchain_test.go index 88db63786..643f992fc 100644 --- a/types/blockchain_test.go +++ b/types/blockchain_test.go @@ -7,7 +7,7 @@ import ( "testing" "time" - "github.com/golang/protobuf/proto" + "github.com/aergoio/aergo/v2/internal/enc/proto" "github.com/libp2p/go-libp2p-core/crypto" "github.com/minio/sha256-simd" "github.com/stretchr/testify/assert" diff --git a/types/common.go b/types/common.go index b25aeaa6c..8304b2e48 100644 --- a/types/common.go +++ b/types/common.go @@ -1,9 +1,8 @@ package types import ( - "encoding/base64" - - "github.com/mr-tron/base58/base58" + "github.com/aergoio/aergo/v2/internal/enc/base58" + "github.com/aergoio/aergo/v2/internal/enc/base64" ) const MAXBLOCKNO BlockNo = 18446744073709551615 @@ -11,11 +10,11 @@ const maxMetaSizeLimit = uint32(256 << 10) const blockSizeHardLimit = uint32(8 << (10 * 2)) func EncodeB64(bs []byte) string { - return base64.StdEncoding.EncodeToString(bs) + return base64.Encode(bs) } func DecodeB64(sb string) []byte { - buf, _ := base64.StdEncoding.DecodeString(sb) + buf, _ := base64.Decode(sb) return buf } diff --git a/types/dbkey/key.go b/types/dbkey/key.go new file mode 100644 index 000000000..56b2331ea --- /dev/null +++ b/types/dbkey/key.go @@ -0,0 +1,134 @@ +package dbkey + +import ( + "bytes" + "fmt" + + "github.com/aergoio/aergo/v2/types" +) + +//---------------------------------------------------------------------------------// +// chain + +func Receipts(blockHash []byte, blockNo types.BlockNo) []byte { + key := make([]byte, len(receiptsPrefix)+len(blockHash)+8) + copy(key, []byte(receiptsPrefix)) + copy(key[len(receiptsPrefix):], blockHash) + copy(key[len(receiptsPrefix)+len(blockHash):], types.BlockNoToBytes(blockNo)) + return key +} + +//---------------------------------------------------------------------------------// +// metadata + +func Genesis() []byte { + return []byte(genesis) +} + +func GenesisBalance() []byte { + return []byte(genesisBalance) +} + +func LatestBlock() []byte { + return []byte(latestBlock) +} + +func HardFork() []byte { + return []byte(hardFork) +} + +func ReOrg() []byte { + return []byte(reOrg) +} + +// dpos +func DposLibStatus() []byte { + return []byte(dposLibStatus) +} + +// raft +func RaftIdentity() []byte { + return []byte(raftIdentity) +} + +func RaftState() []byte { + return []byte(raftState) +} + +func RaftSnap() []byte { + return []byte(raftSnap) +} + +func RaftEntryLastIdx() []byte { + return []byte(raftEntryLastIdx) +} + +func RaftEntry(blockNo types.BlockNo) []byte { + return append([]byte(raftEntry), types.BlockNoToBytes(blockNo)...) +} + +func RaftEntryInvert(blockHash []byte) []byte { + return append([]byte(raftEntryInvert), blockHash...) +} + +func RaftConfChangeProgress(id uint64) []byte { + return append([]byte(raftConfChangeProgress), types.Uint64ToBytes(id)...) +} + +//---------------------------------------------------------------------------------// +// governance + +// enterprise +func EnterpriseAdmins() []byte { + return []byte(enterpriseAdmins) +} + +func EnterpriseConf(conf []byte) []byte { + // upper double check + return append([]byte(enterpriseConf), bytes.ToUpper(conf)...) +} + +// name +func Name(accountName []byte) []byte { + // lower double check + return append([]byte(name), bytes.ToLower(accountName)...) +} + +// system +func SystemParam(id string) []byte { + // upper double check + return append([]byte(systemParam), bytes.ToUpper([]byte(id))...) +} + +func SystemProposal() []byte { + return []byte(systemProposal) +} + +func SystemStaking(account []byte) []byte { + return append([]byte(systemStaking), account...) +} + +func SystemStakingTotal() []byte { + return []byte(systemStakingTotal) +} + +func SystemVote(key, voter []byte) []byte { + return append(append([]byte(systemVote), key...), voter...) +} + +func SystemVoteTotal(key []byte) []byte { + return append([]byte(systemVoteTotal), key...) +} + +func SystemVoteSort(key []byte) []byte { + return append([]byte(systemVoteSort), key...) +} + +func SystemVpr(i uint8) []byte { + return append([]byte(systemVpr), []byte(fmt.Sprintf("%v", i))...) +} + +// creator +func CreatorMeta() []byte { + return []byte(creatorMeta) +} diff --git a/types/dbkey/key_test.go b/types/dbkey/key_test.go new file mode 100644 index 000000000..9d5f77efa --- /dev/null +++ b/types/dbkey/key_test.go @@ -0,0 +1,216 @@ +package dbkey + +import ( + "math" + "testing" + + "github.com/aergoio/aergo/v2/types" + "github.com/stretchr/testify/assert" +) + +func TestReceipts(t *testing.T) { + for _, test := range []struct { + blockHash []byte + blockNo types.BlockNo + expectKey []byte + }{ + {nil, 0, append([]byte(receiptsPrefix), 0, 0, 0, 0, 0, 0, 0, 0)}, + {nil, 1, append([]byte(receiptsPrefix), 1, 0, 0, 0, 0, 0, 0, 0)}, + {nil, 255, append([]byte(receiptsPrefix), 255, 0, 0, 0, 0, 0, 0, 0)}, + {nil, math.MaxUint64, append([]byte(receiptsPrefix), 255, 255, 255, 255, 255, 255, 255, 255)}, + {[]byte{1, 2, 3, 4}, 0, append([]byte(receiptsPrefix), 1, 2, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0)}, + {decodeB58("AiGVpwGUUs1kjK2oZkAEkzBzptZs25LoSakEtu5cCqFV"), 0, append([]byte(receiptsPrefix), append(decodeB58("AiGVpwGUUs1kjK2oZkAEkzBzptZs25LoSakEtu5cCqFV"), 0, 0, 0, 0, 0, 0, 0, 0)...)}, + {decodeB58("5bSKqpcWnMgrr1GhU1Ed5yHajRC4WwZEZYxFtw3fVBmq"), 0, append([]byte(receiptsPrefix), append(decodeB58("5bSKqpcWnMgrr1GhU1Ed5yHajRC4WwZEZYxFtw3fVBmq"), 0, 0, 0, 0, 0, 0, 0, 0)...)}, + } { + key := Receipts(test.blockHash, test.blockNo) + assert.Equal(t, test.expectKey, key, "TestReceipts(%v, %v)", test.blockHash, test.blockNo) + } +} + +// raft +func TestRaftEntry(t *testing.T) { + for _, test := range []struct { + blockNo types.BlockNo + expectKey []byte + }{ + {0, append([]byte(raftEntry), 0, 0, 0, 0, 0, 0, 0, 0)}, + {1, append([]byte(raftEntry), 1, 0, 0, 0, 0, 0, 0, 0)}, + {255, append([]byte(raftEntry), 255, 0, 0, 0, 0, 0, 0, 0)}, + {math.MaxUint64, append([]byte(raftEntry), 255, 255, 255, 255, 255, 255, 255, 255)}, + } { + key := RaftEntry(test.blockNo) + assert.Equal(t, test.expectKey, key, "TestraftEntry(%v)", test.blockNo) + } +} + +func TestRaftEntryInvert(t *testing.T) { + for _, test := range []struct { + blockHash []byte + expectKey []byte + }{ + {[]byte{1, 2, 3, 4}, append([]byte(raftEntryInvert), 1, 2, 3, 4)}, + {decodeB58("AiGVpwGUUs1kjK2oZkAEkzBzptZs25LoSakEtu5cCqFV"), append([]byte(raftEntryInvert), decodeB58("AiGVpwGUUs1kjK2oZkAEkzBzptZs25LoSakEtu5cCqFV")...)}, + {decodeB58("5bSKqpcWnMgrr1GhU1Ed5yHajRC4WwZEZYxFtw3fVBmq"), append([]byte(raftEntryInvert), decodeB58("5bSKqpcWnMgrr1GhU1Ed5yHajRC4WwZEZYxFtw3fVBmq")...)}, + } { + key := RaftEntryInvert(test.blockHash) + assert.Equal(t, test.expectKey, key, "TestraftEntryInvert(%v)", test.blockHash) + } +} + +func TestRaftConfChangeProgress(t *testing.T) { + for _, test := range []struct { + id uint64 + expectKey []byte + }{ + {0, append([]byte(raftConfChangeProgress), 0, 0, 0, 0, 0, 0, 0, 0)}, + {1, append([]byte(raftConfChangeProgress), 1, 0, 0, 0, 0, 0, 0, 0)}, + {255, append([]byte(raftConfChangeProgress), 255, 0, 0, 0, 0, 0, 0, 0)}, + {math.MaxUint64, append([]byte(raftConfChangeProgress), 255, 255, 255, 255, 255, 255, 255, 255)}, + } { + key := RaftConfChangeProgress(test.id) + assert.Equal(t, test.expectKey, key, "TestraftConfChangeProgress(%v)", test.id) + } +} + +// governance +func TestEnterpriseConf(t *testing.T) { + for _, test := range []struct { + conf []byte + expectKey []byte + }{ + {[]byte("rpcpermissions"), append([]byte(enterpriseConf), []byte("RPCPERMISSIONS")...)}, + {[]byte("RPCPERMISSIONS"), append([]byte(enterpriseConf), []byte("RPCPERMISSIONS")...)}, + {[]byte("p2pwhite"), append([]byte(enterpriseConf), []byte("P2PWHITE")...)}, + {[]byte("P2PWHITE"), append([]byte(enterpriseConf), []byte("P2PWHITE")...)}, + {[]byte("p2pblack"), append([]byte(enterpriseConf), []byte("P2PBLACK")...)}, + {[]byte("P2PBLACK"), append([]byte(enterpriseConf), []byte("P2PBLACK")...)}, + {[]byte("accountwhite"), append([]byte(enterpriseConf), []byte("ACCOUNTWHITE")...)}, + {[]byte("ACCOUNTWHITE"), append([]byte(enterpriseConf), []byte("ACCOUNTWHITE")...)}, + } { + key := EnterpriseConf(test.conf) + assert.Equal(t, test.expectKey, key, "TestEnterpriseConf(%v)", test.conf) + } +} + +func TestName(t *testing.T) { + for _, test := range []struct { + name []byte + expectKey []byte + }{ + {nil, []byte(name)}, + {[]byte("aergo.name"), append([]byte(name), []byte("aergo.name")...)}, + {[]byte("AERGO.NAME"), append([]byte(name), []byte("aergo.name")...)}, + } { + key := Name(test.name) + assert.Equal(t, test.expectKey, key, "TestName(%v)", test.name) + } +} + +func TestSystemParam(t *testing.T) { + for _, test := range []struct { + param string + expectKey []byte + }{ + {"", []byte(systemParam)}, + {"bpCount", append([]byte(systemParam), []byte("BPCOUNT")...)}, + {"stakingMin", append([]byte(systemParam), []byte("STAKINGMIN")...)}, + {"gasPrice", append([]byte(systemParam), []byte("GASPRICE")...)}, + {"namePrice", append([]byte(systemParam), []byte("NAMEPRICE")...)}, + } { + key := SystemParam(test.param) + assert.Equal(t, test.expectKey, key, "TestSystemParam(%v)", test.param) + } +} + +func TestSystemStaking(t *testing.T) { + for _, test := range []struct { + account []byte + expectKey []byte + }{ + {nil, []byte(systemStaking)}, + {decodeAddr("AmNpn7K9wg6wsn6oMkTirQSUNdqtDm94iCrrpP5ZpwCAAxxPrsU2"), append([]byte(systemStaking), decodeAddr("AmNpn7K9wg6wsn6oMkTirQSUNdqtDm94iCrrpP5ZpwCAAxxPrsU2")...)}, + } { + key := SystemStaking(test.account) + assert.Equal(t, test.expectKey, key, "TestSystemStaking(%v)", test.account) + } +} + +func TestSystemVote(t *testing.T) { + for _, test := range []struct { + key []byte + voter []byte + expectKey []byte + }{ + {decodeAddr("AmNpn7K9wg6wsn6oMkTirQSUNdqtDm94iCrrpP5ZpwCAAxxPrsU2"), []byte("OpvoteBP"), append([]byte(systemVote), append(decodeAddr("AmNpn7K9wg6wsn6oMkTirQSUNdqtDm94iCrrpP5ZpwCAAxxPrsU2"), []byte("OpvoteBP")...)...)}, + {decodeAddr("AmNpn7K9wg6wsn6oMkTirQSUNdqtDm94iCrrpP5ZpwCAAxxPrsU2"), []byte("OpvoteDAO"), append([]byte(systemVote), append(decodeAddr("AmNpn7K9wg6wsn6oMkTirQSUNdqtDm94iCrrpP5ZpwCAAxxPrsU2"), []byte("OpvoteDAO")...)...)}, + {decodeAddr("AmNpn7K9wg6wsn6oMkTirQSUNdqtDm94iCrrpP5ZpwCAAxxPrsU2"), []byte("Opstake"), append([]byte(systemVote), append(decodeAddr("AmNpn7K9wg6wsn6oMkTirQSUNdqtDm94iCrrpP5ZpwCAAxxPrsU2"), []byte("Opstake")...)...)}, + {decodeAddr("AmNpn7K9wg6wsn6oMkTirQSUNdqtDm94iCrrpP5ZpwCAAxxPrsU2"), []byte("Opunstake"), append([]byte(systemVote), append(decodeAddr("AmNpn7K9wg6wsn6oMkTirQSUNdqtDm94iCrrpP5ZpwCAAxxPrsU2"), []byte("Opunstake")...)...)}, + } { + key := SystemVote(test.key, test.voter) + assert.Equal(t, test.expectKey, key, "TestSystemVote(%v, %v)", test.key, test.voter) + } +} + +func TestSystemVoteSort(t *testing.T) { + for _, test := range []struct { + key []byte + expectKey []byte + }{ + {[]byte("OpvoteBP"), append([]byte(systemVoteSort), []byte("OpvoteBP")...)}, + {[]byte("OpvoteDAO"), append([]byte(systemVoteSort), []byte("OpvoteDAO")...)}, + {[]byte("Opstake"), append([]byte(systemVoteSort), []byte("Opstake")...)}, + {[]byte("Opunstake"), append([]byte(systemVoteSort), []byte("Opunstake")...)}, + } { + key := SystemVoteSort(test.key) + assert.Equal(t, test.expectKey, key, "TestSystemVoteSort(%v)", test.key) + } +} + +func TestSystemVoteTotal(t *testing.T) { + for _, test := range []struct { + key []byte + expectKey []byte + }{ + {[]byte("OpvoteBP"), append([]byte(systemVoteTotal), []byte("OpvoteBP")...)}, + {[]byte("OpvoteDAO"), append([]byte(systemVoteTotal), []byte("OpvoteDAO")...)}, + {[]byte("Opstake"), append([]byte(systemVoteTotal), []byte("Opstake")...)}, + {[]byte("Opunstake"), append([]byte(systemVoteTotal), []byte("Opunstake")...)}, + } { + key := SystemVoteTotal(test.key) + assert.Equal(t, test.expectKey, key, "TestSystemVoteTotal(%v)", test.key) + } +} + +func TestSystemVpr(t *testing.T) { + for _, test := range []struct { + i uint8 + expectKey []byte + }{ + {0, append([]byte(systemVpr), '0')}, + {1, append([]byte(systemVpr), '1')}, + {255, append([]byte(systemVpr), '2', '5', '5')}, + } { + key := SystemVpr(test.i) + assert.Equal(t, test.expectKey, key, "TestSystemVpr(%v)", test.i) + } +} + +//------------------------------------------------------------------// +// util + +func decodeB58(s string) []byte { + return types.DecodeB58(s) +} + +func encodeB58(bt []byte) string { + return types.EncodeB58(bt) +} + +func decodeAddr(addr string) []byte { + raw, _ := types.DecodeAddress(addr) + return raw +} + +func encodeAddr(raw []byte) string { + return types.EncodeAddress(raw) +} diff --git a/types/dbkey/schema.go b/types/dbkey/schema.go new file mode 100644 index 000000000..0713bb825 --- /dev/null +++ b/types/dbkey/schema.go @@ -0,0 +1,53 @@ +// package dbkey contains a key prefix collection of low level database accessors. +package dbkey + +// chain +const ( + receiptsPrefix = "r" +) + +// metadata +const ( + ChainDBName = "chain" + + genesis = ChainDBName + ".genesisInfo" + genesisBalance = ChainDBName + ".genesisBalance" + latestBlock = ChainDBName + ".latest" + hardFork = "hardfork" + reOrg = "_reorg_marker_" + + // dpos + dposLibStatus = "dpos.LibStatus" // LibStatusKey is the key when a LIB information is put into the chain DB. + + // raft + raftPrefix = "r_" + raftIdentity = raftPrefix + "identity" + raftState = raftPrefix + "state" + raftSnap = raftPrefix + "snap" + raftEntryLastIdx = raftPrefix + "last" + raftEntry = raftPrefix + "entry." + raftEntryInvert = raftPrefix + "inv." + raftConfChangeProgress = raftPrefix + "ccstatus." +) + +// governance +const ( + // enterprise + enterpriseAdmins = "ADMINS" + enterpriseConf = "conf\\" + + // name + name = "name" + + // system + systemParam = "param\\" + systemProposal = "proposal" + systemStaking = "staking" + systemStakingTotal = "stakingtotal" + systemVote = "vote" + systemVoteTotal = "total" + systemVoteSort = "sort" + systemVpr = "VotingPowerBucket/" + + creatorMeta = "Creator" +) diff --git a/types/genesis.go b/types/genesis.go index 4ec01695f..2d6853e44 100644 --- a/types/genesis.go +++ b/types/genesis.go @@ -3,7 +3,6 @@ package types import ( "bytes" "encoding/binary" - "encoding/hex" "encoding/json" "fmt" "math" @@ -11,7 +10,8 @@ import ( "strings" "time" - "github.com/aergoio/aergo/v2/internal/common" + "github.com/aergoio/aergo/v2/internal/enc/gob" + "github.com/aergoio/aergo/v2/internal/enc/hex" ) const ( @@ -281,7 +281,7 @@ func (g *Genesis) ChainID() ([]byte, error) { func (g Genesis) Bytes() []byte { // Omit the Balance to reduce the resulting data size. g.Balance = nil - if b, err := common.GobEncode(g); err == nil { + if b, err := gob.Encode(g); err == nil { return b } return nil @@ -333,7 +333,7 @@ func GetDefaultGenesis() *Genesis { } func GetMainNetGenesis() *Genesis { - if bs, err := hex.DecodeString(MainNetGenesis); err == nil { + if bs, err := hex.Decode(MainNetGenesis); err == nil { var g Genesis if err := json.Unmarshal(bs, &g); err == nil { return &g @@ -342,7 +342,7 @@ func GetMainNetGenesis() *Genesis { return nil } func GetTestNetGenesis() *Genesis { - if bs, err := hex.DecodeString(TestNetGenesis); err == nil { + if bs, err := hex.Decode(TestNetGenesis); err == nil { var g Genesis if err := json.Unmarshal(bs, &g); err == nil { return &g @@ -373,7 +373,7 @@ func GetTestGenesis() *Genesis { // GetGenesisFromBytes decodes & return Genesis from b. func GetGenesisFromBytes(b []byte) *Genesis { g := &Genesis{} - if err := common.GobDecode(b, g); err == nil { + if err := gob.Decode(b, g); err == nil { return g } return nil diff --git a/types/genesis_test.go b/types/genesis_test.go index d464648e3..9a4cedae4 100644 --- a/types/genesis_test.go +++ b/types/genesis_test.go @@ -7,7 +7,7 @@ import ( "testing" "time" - "github.com/aergoio/aergo/v2/internal/enc" + "github.com/aergoio/aergo/v2/internal/enc/base58" "github.com/davecgh/go-spew/spew" "github.com/stretchr/testify/assert" ) @@ -36,7 +36,7 @@ func TestGenesisChainID(t *testing.T) { a.Nil(err) a.True(g.ID.Equals(&defaultChainID)) fmt.Println("len:", len(chainID)) - fmt.Println("chain_id: ", enc.ToString(chainID)) + fmt.Println("chain_id: ", base58.Encode(chainID)) } func TestGenesisBytes(t *testing.T) { diff --git a/types/logging.go b/types/logging.go index 329b24c40..a0a479876 100644 --- a/types/logging.go +++ b/types/logging.go @@ -7,7 +7,8 @@ package types import ( "fmt" - "github.com/aergoio/aergo/v2/internal/enc" + + "github.com/aergoio/aergo/v2/internal/enc/base58" "github.com/rs/zerolog" ) @@ -16,7 +17,7 @@ type LogTxHash struct { } func (t LogTxHash) MarshalZerologObject(e *zerolog.Event) { - e.Str("txID", enc.ToString(t.Hash)) + e.Str("txID", base58.Encode(t.Hash)) } type LogTx struct { @@ -24,7 +25,7 @@ type LogTx struct { } func (t LogTx) MarshalZerologObject(e *zerolog.Event) { - e.Str("txID", enc.ToString(t.GetHash())).Str("account", enc.ToString(t.Body.Account)).Uint64("nonce", t.Body.Nonce) + e.Str("txID", base58.Encode(t.GetHash())).Str("account", base58.Encode(t.Body.Account)).Uint64("nonce", t.Body.Nonce) } type LogTrsactions struct { @@ -63,7 +64,7 @@ func marshalTrx(tr Transaction, a *zerolog.Array) { type LogBase58 []byte func (t LogBase58) String() string { - return enc.ToString(t) + return base58.Encode(t) } // LogAddr is thin wrapper which show base58 encoded form of wallet or smart contract diff --git a/types/logging_test.go b/types/logging_test.go index 7c1bfb964..88383416d 100644 --- a/types/logging_test.go +++ b/types/logging_test.go @@ -1,10 +1,11 @@ package types import ( + "testing" + "github.com/aergoio/aergo-lib/log" - "github.com/aergoio/aergo/v2/internal/enc" + "github.com/aergoio/aergo/v2/internal/enc/base58" "github.com/rs/zerolog" - "testing" ) func BenchmarkLogMemAllocationCompared(b *testing.B) { @@ -69,7 +70,7 @@ func BenchmarkLogMemAllocationRunD(b *testing.B) { type LogB58Wrapper []byte func (t LogB58Wrapper) MarshalZerologObject(e *zerolog.Event) { - e.Str("b58", enc.ToString(t)) + e.Str("b58", base58.Encode(t)) } func BenchmarkLogMemAllocationWrapper(b *testing.B) { diff --git a/types/p2p_test.go b/types/p2p_test.go index ef88473af..ebd5d3106 100644 --- a/types/p2p_test.go +++ b/types/p2p_test.go @@ -6,23 +6,23 @@ package types import ( - "encoding/hex" "fmt" "testing" - "github.com/aergoio/aergo/v2/internal/enc" - "github.com/golang/protobuf/proto" + "github.com/aergoio/aergo/v2/internal/enc/base58" + "github.com/aergoio/aergo/v2/internal/enc/hex" + "github.com/aergoio/aergo/v2/internal/enc/proto" "github.com/stretchr/testify/assert" ) func TestUnmarshalSize(t *testing.T) { - var dummyTxHash, _ = enc.ToBytes("4H4zAkAyRV253K5SNBJtBxqUgHEbZcXbWFFc6cmQHY45") - fmt.Println("Hash: ", hex.EncodeToString(dummyTxHash)) + var dummyTxHash, _ = base58.Decode("4H4zAkAyRV253K5SNBJtBxqUgHEbZcXbWFFc6cmQHY45") + fmt.Println("Hash: ", hex.Encode(dummyTxHash)) sample := &NewTransactionsNotice{} expectedLen := proto.Size(sample) - actual, err := proto.Marshal(sample) + actual, err := proto.Encode(sample) assert.Nil(t, err) fmt.Println("Empty notice size ", len(actual)) assert.Equal(t, expectedLen, len(actual)) @@ -32,10 +32,10 @@ func TestUnmarshalSize(t *testing.T) { hashes = append(hashes, dummyTxHash) sample.TxHashes = hashes expectedLen = proto.Size(sample) - actual, err = proto.Marshal(sample) + actual, err = proto.Encode(sample) assert.Nil(t, err) fmt.Println("Single hash notice size ", len(actual)) - fmt.Println("Hex: ", hex.EncodeToString(actual)) + fmt.Println("Hex: ", hex.Encode(actual)) assert.Equal(t, expectedLen, len(actual)) // 100 hashes @@ -45,10 +45,10 @@ func TestUnmarshalSize(t *testing.T) { } sample.TxHashes = hashes expectedLen = proto.Size(sample) - actual, err = proto.Marshal(sample) + actual, err = proto.Encode(sample) assert.Nil(t, err) fmt.Println("Hundred hashes notice size ", len(actual)) - fmt.Println("Hex: ", hex.EncodeToString(actual[0:40])) + fmt.Println("Hex: ", hex.Encode(actual[0:40])) assert.Equal(t, expectedLen, len(actual)) // 1000 hashes @@ -58,10 +58,10 @@ func TestUnmarshalSize(t *testing.T) { } sample.TxHashes = hashes expectedLen = proto.Size(sample) - actual, err = proto.Marshal(sample) + actual, err = proto.Encode(sample) assert.Nil(t, err) fmt.Println("Thousand hashes notice size ", len(actual)) - fmt.Println("Hex: ", hex.EncodeToString(actual[0:40])) + fmt.Println("Hex: ", hex.Encode(actual[0:40])) assert.Equal(t, expectedLen, len(actual)) } diff --git a/types/p2plogging.go b/types/p2plogging.go index 0b25b1d8d..1a366ed89 100644 --- a/types/p2plogging.go +++ b/types/p2plogging.go @@ -8,7 +8,7 @@ package types import ( "fmt" - "github.com/aergoio/aergo/v2/internal/enc" + "github.com/aergoio/aergo/v2/internal/enc/base58" "github.com/rs/zerolog" ) @@ -34,12 +34,12 @@ func (m LogB58EncMarshaller) MarshalZerologArray(a *zerolog.Array) { size := len(m.arr) if size > m.limit { for i := 0; i < m.limit-1; i++ { - a.Str(enc.ToString(m.arr[i])) + a.Str(base58.Encode(m.arr[i])) } a.Str(fmt.Sprintf("(and %d more)", size-m.limit+1)) } else { for _, element := range m.arr { - a.Str(enc.ToString(element)) + a.Str(base58.Encode(element)) } } } @@ -53,12 +53,12 @@ func (m LogBlockHashMarshaller) MarshalZerologArray(a *zerolog.Array) { size := len(m.arr) if size > m.limit { for i := 0; i < m.limit-1; i++ { - a.Str(enc.ToString(m.arr[i].GetHash())) + a.Str(base58.Encode(m.arr[i].GetHash())) } a.Str(fmt.Sprintf("(and %d more)", size-m.limit+1)) } else { for _, element := range m.arr { - a.Str(enc.ToString(element.GetHash())) + a.Str(base58.Encode(element.GetHash())) } } } @@ -134,15 +134,15 @@ func (m *NewTransactionsNotice) MarshalZerologObject(e *zerolog.Event) { } func (m *BlockProducedNotice) MarshalZerologObject(e *zerolog.Event) { - e.Str("bp", enc.ToString(m.ProducerID)).Uint64(LogBlkNo, m.BlockNo).Str(LogBlkHash, enc.ToString(m.Block.Hash)) + e.Str("bp", base58.Encode(m.ProducerID)).Uint64(LogBlkNo, m.BlockNo).Str(LogBlkHash, base58.Encode(m.Block.Hash)) } func (m *Ping) MarshalZerologObject(e *zerolog.Event) { - e.Str(LogBlkHash, enc.ToString(m.BestBlockHash)).Uint64(LogBlkNo, m.BestHeight) + e.Str(LogBlkHash, base58.Encode(m.BestBlockHash)).Uint64(LogBlkNo, m.BestHeight) } func (m *GetHashesRequest) MarshalZerologObject(e *zerolog.Event) { - e.Str("prev_hash", enc.ToString(m.PrevHash)).Uint64("prev_no", m.PrevNumber) + e.Str("prev_hash", base58.Encode(m.PrevHash)).Uint64("prev_no", m.PrevNumber) } func (m *GetHashesResponse) MarshalZerologObject(e *zerolog.Event) { @@ -150,7 +150,7 @@ func (m *GetHashesResponse) MarshalZerologObject(e *zerolog.Event) { } func (m *GetBlockHeadersRequest) MarshalZerologObject(e *zerolog.Event) { - e.Str(LogBlkHash, enc.ToString(m.Hash)).Uint64(LogBlkNo, m.Height).Bool("ascending", m.Asc).Uint32("size", m.Size) + e.Str(LogBlkHash, base58.Encode(m.Hash)).Uint64(LogBlkNo, m.Height).Bool("ascending", m.Asc).Uint32("size", m.Size) } func (m *GetBlockHeadersResponse) MarshalZerologObject(e *zerolog.Event) { @@ -162,7 +162,7 @@ func (m *GetHashByNo) MarshalZerologObject(e *zerolog.Event) { } func (m *GetHashByNoResponse) MarshalZerologObject(e *zerolog.Event) { - e.Str(LogRespStatus, m.Status.String()).Str(LogBlkHash, enc.ToString(m.BlockHash)) + e.Str(LogRespStatus, m.Status.String()).Str(LogBlkHash, base58.Encode(m.BlockHash)) } func (m *GetAncestorRequest) MarshalZerologObject(e *zerolog.Event) { @@ -170,15 +170,15 @@ func (m *GetAncestorRequest) MarshalZerologObject(e *zerolog.Event) { } func (m *GetAncestorResponse) MarshalZerologObject(e *zerolog.Event) { - e.Str(LogRespStatus, m.Status.String()).Str(LogBlkHash, enc.ToString(m.AncestorHash)).Uint64(LogBlkNo, m.AncestorNo) + e.Str(LogRespStatus, m.Status.String()).Str(LogBlkHash, base58.Encode(m.AncestorHash)).Uint64(LogBlkNo, m.AncestorNo) } func (m *GetClusterInfoRequest) MarshalZerologObject(e *zerolog.Event) { - e.Str("best_hash", enc.ToString(m.BestBlockHash)) + e.Str("best_hash", base58.Encode(m.BestBlockHash)) } func (m *GetClusterInfoResponse) MarshalZerologObject(e *zerolog.Event) { - e.Str(LogChainID, enc.ToString(m.ChainID)).Str("err", m.Error).Array("members", RaftMbrsMarshaller{arr: m.MbrAttrs, limit: 10}).Uint64("cluster_id", m.ClusterID) + e.Str(LogChainID, base58.Encode(m.ChainID)).Str("err", m.Error).Array("members", RaftMbrsMarshaller{arr: m.MbrAttrs, limit: 10}).Uint64("cluster_id", m.ClusterID) } func (m *IssueCertificateResponse) MarshalZerologObject(e *zerolog.Event) { diff --git a/types/receipt.go b/types/receipt.go index 524243b16..a4757b22b 100644 --- a/types/receipt.go +++ b/types/receipt.go @@ -10,7 +10,7 @@ import ( "reflect" "strconv" - "github.com/aergoio/aergo/v2/internal/enc" + "github.com/aergoio/aergo/v2/internal/enc/base58" "github.com/aergoio/aergo/v2/internal/merkle" "github.com/golang/protobuf/jsonpb" "github.com/minio/sha256-simd" @@ -352,7 +352,7 @@ func (r *Receipt) MarshalJSON() ([]byte, error) { b.WriteString(`{"BlockNo":`) b.WriteString(fmt.Sprintf("%d", r.BlockNo)) b.WriteString(`,"BlockHash":"`) - b.WriteString(enc.ToString(r.BlockHash)) + b.WriteString(base58.Encode(r.BlockHash)) b.WriteString(`","contractAddress":"`) b.WriteString(EncodeAddress(r.ContractAddress)) b.WriteString(`","status":"`) @@ -368,7 +368,7 @@ func (r *Receipt) MarshalJSON() ([]byte, error) { b.WriteString(r.Ret) } b.WriteString(`,"txHash":"`) - b.WriteString(enc.ToString(r.TxHash)) + b.WriteString(base58.Encode(r.TxHash)) b.WriteString(`","txIndex":`) b.WriteString(fmt.Sprintf("%d", r.TxIndex)) b.WriteString(`,"from":"`) @@ -731,11 +731,11 @@ func (ev *Event) MarshalJSON() ([]byte, error) { b.WriteString(`","Args":`) b.WriteString(ev.JsonArgs) b.WriteString(`,"txHash":"`) - b.WriteString(enc.ToString(ev.TxHash)) + b.WriteString(base58.Encode(ev.TxHash)) b.WriteString(`","EventIdx":`) b.WriteString(fmt.Sprintf("%d", ev.EventIdx)) b.WriteString(`,"BlockHash":"`) - b.WriteString(enc.ToString(ev.BlockHash)) + b.WriteString(base58.Encode(ev.BlockHash)) b.WriteString(`","BlockNo":`) b.WriteString(fmt.Sprintf("%d", ev.BlockNo)) b.WriteString(`,"TxIndex":`) diff --git a/types/state.go b/types/state.go index c33577631..d0cbe63ac 100644 --- a/types/state.go +++ b/types/state.go @@ -7,7 +7,7 @@ import ( "reflect" "github.com/aergoio/aergo/v2/internal/common" - "github.com/aergoio/aergo/v2/internal/enc" + "github.com/aergoio/aergo/v2/internal/enc/base58" ) const ( @@ -58,7 +58,7 @@ func ToHashID(hash []byte) HashID { return HashID(buf) } func (id HashID) String() string { - return enc.ToString(id[:]) + return base58.Encode(id[:]) } // Bytes make a byte slice from id diff --git a/types/transaction.go b/types/transaction.go index 61fac049f..9609001db 100644 --- a/types/transaction.go +++ b/types/transaction.go @@ -8,8 +8,8 @@ import ( "strings" "github.com/aergoio/aergo/v2/fee" - "github.com/golang/protobuf/proto" - "github.com/mr-tron/base58/base58" + "github.com/aergoio/aergo/v2/internal/enc/base58" + "github.com/aergoio/aergo/v2/internal/enc/proto" ) //governance type transaction which has aergo.system in recipient @@ -51,11 +51,11 @@ type Transaction interface { CalculateTxHash() []byte Validate([]byte, bool) error ValidateWithSenderState(senderState *State, gasPrice *big.Int, version int32) error + ValidateMaxFee(balance, gasPrice *big.Int, version int32) error HasVerifedAccount() bool GetVerifedAccount() Address SetVerifedAccount(account Address) bool RemoveVerifedAccount() bool - GetMaxFee(balance, gasPrice *big.Int, version int32) (*big.Int, error) } type transaction struct { @@ -308,13 +308,10 @@ func (tx *transaction) ValidateWithSenderState(senderState *State, gasPrice *big if b.Sign() < 0 { return ErrInsufficientBalance } - fee, err := tx.GetMaxFee(b, gasPrice, version) + err := tx.ValidateMaxFee(b, gasPrice, version) if err != nil { return err } - if fee.Cmp(b) > 0 { - return ErrInsufficientBalance - } case TxType_GOVERNANCE: switch string(tx.GetBody().GetRecipient()) { case AergoSystem: @@ -391,22 +388,19 @@ func (tx *transaction) Clone() *transaction { return res } -func (tx *transaction) GetMaxFee(balance, gasPrice *big.Int, version int32) (*big.Int, error) { - if fee.IsZeroFee() { - return fee.NewZeroFee(), nil - } - if version >= 2 { - minGasLimit := fee.TxGas(len(tx.GetBody().GetPayload())) - gasLimit := tx.GetBody().GasLimit - if gasLimit == 0 { - gasLimit = fee.MaxGasLimit(balance, gasPrice) - } - if minGasLimit > gasLimit { - return nil, fmt.Errorf("the minimum required amount of gas: %d", minGasLimit) - } - return new(big.Int).Mul(new(big.Int).SetUint64(gasLimit), gasPrice), nil +func (tx *transaction) ValidateMaxFee(balance, gasPrice *big.Int, version int32) error { + var ( + lenPayload = len(tx.GetBody().GetPayload()) + gasLimit = tx.GetBody().GetGasLimit() + ) + + maxFee, err := fee.TxMaxFee(version, lenPayload, gasLimit, balance, gasPrice) + if err != nil { + return err + } else if maxFee.Cmp(balance) > 0 { + return ErrInsufficientBalance } - return fee.MaxPayloadTxFee(len(tx.GetBody().GetPayload())), nil + return nil } const allowedNameChar = "abcdefghijklmnopqrstuvwxyz1234567890"