mirror of https://github.com/poanetwork/gecko.git
addressed PR comments
This commit is contained in:
parent
2b48a4a798
commit
d3d22ffce8
|
@ -504,6 +504,9 @@ func VMGenesis(networkID uint32, vmID ids.ID) *platformvm.CreateChainTx {
|
||||||
genesisBytes := Genesis(networkID)
|
genesisBytes := Genesis(networkID)
|
||||||
genesis := platformvm.Genesis{}
|
genesis := platformvm.Genesis{}
|
||||||
platformvm.Codec.Unmarshal(genesisBytes, &genesis)
|
platformvm.Codec.Unmarshal(genesisBytes, &genesis)
|
||||||
|
if err := genesis.Initialize(); err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
for _, chain := range genesis.Chains {
|
for _, chain := range genesis.Chains {
|
||||||
if chain.VMID.Equals(vmID) {
|
if chain.VMID.Equals(vmID) {
|
||||||
return chain
|
return chain
|
||||||
|
|
|
@ -251,7 +251,10 @@ func (vm *VM) GetTx(txID ids.ID) (snowstorm.Tx, error) {
|
||||||
******************************************************************************
|
******************************************************************************
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// IssueTx attempts to send a transaction to consensus
|
// IssueTx attempts to send a transaction to consensus.
|
||||||
|
// If onDecide is specified, the function will be called when the transaction is
|
||||||
|
// either accepted or rejected with the appropriate status. This function will
|
||||||
|
// go out of scope when the transaction is removed from memory.
|
||||||
func (vm *VM) IssueTx(b []byte, onDecide func(choices.Status)) (ids.ID, error) {
|
func (vm *VM) IssueTx(b []byte, onDecide func(choices.Status)) (ids.ID, error) {
|
||||||
tx, err := vm.parseTx(b)
|
tx, err := vm.parseTx(b)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -548,6 +548,8 @@ func TestGenesisGetUTXOs(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Test issuing a transaction that consumes a currently pending UTXO. The
|
||||||
|
// transaction should be issued successfully.
|
||||||
func TestIssueDependentTx(t *testing.T) {
|
func TestIssueDependentTx(t *testing.T) {
|
||||||
genesisBytes := BuildGenesisTest(t)
|
genesisBytes := BuildGenesisTest(t)
|
||||||
|
|
||||||
|
|
|
@ -20,31 +20,42 @@ var (
|
||||||
|
|
||||||
// Keychain is a collection of keys that can be used to spend utxos
|
// Keychain is a collection of keys that can be used to spend utxos
|
||||||
type Keychain struct {
|
type Keychain struct {
|
||||||
|
factory crypto.FactorySECP256K1R
|
||||||
networkID uint32
|
networkID uint32
|
||||||
chainID ids.ID
|
chainID ids.ID
|
||||||
// This can be used to iterate over. However, it should not be modified externally.
|
|
||||||
|
// Key: The id of a private key (namely, [privKey].PublicKey().Address().Key())
|
||||||
|
// Value: The index in Keys of that private key
|
||||||
keyMap map[[20]byte]int
|
keyMap map[[20]byte]int
|
||||||
|
|
||||||
|
// Each element is an address controlled by a key in [Keys]
|
||||||
|
// This can be used to iterate over. It should not be modified externally.
|
||||||
Addrs ids.ShortSet
|
Addrs ids.ShortSet
|
||||||
|
|
||||||
|
// List of keys this keychain manages
|
||||||
|
// This can be used to iterate over. It should not be modified externally.
|
||||||
Keys []*crypto.PrivateKeySECP256K1R
|
Keys []*crypto.PrivateKeySECP256K1R
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewKeychain creates a new keychain for a chain
|
// NewKeychain creates a new keychain for a chain
|
||||||
func NewKeychain(networkID uint32, chainID ids.ID) *Keychain {
|
func NewKeychain(networkID uint32, chainID ids.ID) *Keychain {
|
||||||
return &Keychain{
|
return &Keychain{
|
||||||
|
networkID: networkID,
|
||||||
chainID: chainID,
|
chainID: chainID,
|
||||||
keyMap: make(map[[20]byte]int),
|
keyMap: make(map[[20]byte]int),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// New returns a newly generated private key
|
// New returns a newly generated private key
|
||||||
func (kc *Keychain) New() *crypto.PrivateKeySECP256K1R {
|
func (kc *Keychain) New() (*crypto.PrivateKeySECP256K1R, error) {
|
||||||
factory := &crypto.FactorySECP256K1R{}
|
skGen, err := kc.factory.NewPrivateKey()
|
||||||
|
if err != nil {
|
||||||
skGen, _ := factory.NewPrivateKey()
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
sk := skGen.(*crypto.PrivateKeySECP256K1R)
|
sk := skGen.(*crypto.PrivateKeySECP256K1R)
|
||||||
kc.Add(sk)
|
kc.Add(sk)
|
||||||
return sk
|
return sk, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add a new key to the key chain
|
// Add a new key to the key chain
|
|
@ -20,29 +20,35 @@ var (
|
||||||
|
|
||||||
// Keychain is a collection of keys that can be used to spend utxos
|
// Keychain is a collection of keys that can be used to spend utxos
|
||||||
type Keychain struct {
|
type Keychain struct {
|
||||||
// This can be used to iterate over. However, it should not be modified externally.
|
factory crypto.FactorySECP256K1R
|
||||||
|
networkID uint32
|
||||||
|
chainID ids.ID
|
||||||
|
|
||||||
// Key: The id of a private key (namely, [privKey].PublicKey().Address().Key())
|
// Key: The id of a private key (namely, [privKey].PublicKey().Address().Key())
|
||||||
// Value: The index in Keys of that private key
|
// Value: The index in Keys of that private key
|
||||||
keyMap map[[20]byte]int
|
keyMap map[[20]byte]int
|
||||||
|
|
||||||
// Each element is an address controlled by a key in [Keys]
|
// Each element is an address controlled by a key in [Keys]
|
||||||
|
// This can be used to iterate over. It should not be modified externally.
|
||||||
Addrs ids.ShortSet
|
Addrs ids.ShortSet
|
||||||
|
|
||||||
// List of keys this keychain manages
|
// List of keys this keychain manages
|
||||||
|
// This can be used to iterate over. It should not be modified externally.
|
||||||
Keys []*crypto.PrivateKeySECP256K1R
|
Keys []*crypto.PrivateKeySECP256K1R
|
||||||
}
|
}
|
||||||
|
|
||||||
func (kc *Keychain) init() {
|
// NewKeychain creates a new keychain for a chain
|
||||||
if kc.keyMap == nil {
|
func NewKeychain(networkID uint32, chainID ids.ID) *Keychain {
|
||||||
kc.keyMap = make(map[[20]byte]int)
|
return &Keychain{
|
||||||
|
networkID: networkID,
|
||||||
|
chainID: chainID,
|
||||||
|
keyMap: make(map[[20]byte]int),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add a new key to the key chain.
|
// Add a new key to the key chain.
|
||||||
// If [key] is already in the keychain, does nothing.
|
// If [key] is already in the keychain, does nothing.
|
||||||
func (kc *Keychain) Add(key *crypto.PrivateKeySECP256K1R) {
|
func (kc *Keychain) Add(key *crypto.PrivateKeySECP256K1R) {
|
||||||
kc.init()
|
|
||||||
|
|
||||||
addr := key.PublicKey().Address() // The address controlled by [key]
|
addr := key.PublicKey().Address() // The address controlled by [key]
|
||||||
addrHash := addr.Key()
|
addrHash := addr.Key()
|
||||||
if _, ok := kc.keyMap[addrHash]; !ok {
|
if _, ok := kc.keyMap[addrHash]; !ok {
|
||||||
|
@ -53,9 +59,7 @@ func (kc *Keychain) Add(key *crypto.PrivateKeySECP256K1R) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get a key from the keychain. If the key is unknown, the second return value is false.
|
// Get a key from the keychain. If the key is unknown, the second return value is false.
|
||||||
func (kc Keychain) Get(id ids.ShortID) (*crypto.PrivateKeySECP256K1R, bool) {
|
func (kc *Keychain) Get(id ids.ShortID) (*crypto.PrivateKeySECP256K1R, bool) {
|
||||||
kc.init()
|
|
||||||
|
|
||||||
if i, ok := kc.keyMap[id.Key()]; ok {
|
if i, ok := kc.keyMap[id.Key()]; ok {
|
||||||
return kc.Keys[i], true
|
return kc.Keys[i], true
|
||||||
}
|
}
|
||||||
|
@ -63,15 +67,13 @@ func (kc Keychain) Get(id ids.ShortID) (*crypto.PrivateKeySECP256K1R, bool) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Addresses returns a list of addresses this keychain manages
|
// Addresses returns a list of addresses this keychain manages
|
||||||
func (kc Keychain) Addresses() ids.ShortSet { return kc.Addrs }
|
func (kc *Keychain) Addresses() ids.ShortSet { return kc.Addrs }
|
||||||
|
|
||||||
// New returns a newly generated private key.
|
// New returns a newly generated private key.
|
||||||
// The key and the address it controls are added to
|
// The key and the address it controls are added to
|
||||||
// [kc.Keys] and [kc.Addrs], respectively
|
// [kc.Keys] and [kc.Addrs], respectively
|
||||||
func (kc *Keychain) New() (*crypto.PrivateKeySECP256K1R, error) {
|
func (kc *Keychain) New() (*crypto.PrivateKeySECP256K1R, error) {
|
||||||
factory := crypto.FactorySECP256K1R{}
|
skGen, err := kc.factory.NewPrivateKey()
|
||||||
|
|
||||||
skGen, err := factory.NewPrivateKey()
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -84,8 +86,8 @@ func (kc *Keychain) New() (*crypto.PrivateKeySECP256K1R, error) {
|
||||||
// Spend attempts to create an input
|
// Spend attempts to create an input
|
||||||
func (kc *Keychain) Spend(utxo *UTXO, time uint64) (Input, *InputSigner, error) {
|
func (kc *Keychain) Spend(utxo *UTXO, time uint64) (Input, *InputSigner, error) {
|
||||||
builder := Builder{
|
builder := Builder{
|
||||||
NetworkID: 0,
|
NetworkID: kc.networkID,
|
||||||
ChainID: ids.Empty,
|
ChainID: kc.chainID,
|
||||||
}
|
}
|
||||||
|
|
||||||
switch out := utxo.Out().(type) {
|
switch out := utxo.Out().(type) {
|
||||||
|
@ -148,8 +150,8 @@ func (kc *Keychain) GetSigsAndKeys(addresses []ids.ShortID, threshold int) ([]*S
|
||||||
sigs := []*Sig{}
|
sigs := []*Sig{}
|
||||||
keys := []*crypto.PrivateKeySECP256K1R{}
|
keys := []*crypto.PrivateKeySECP256K1R{}
|
||||||
builder := Builder{
|
builder := Builder{
|
||||||
NetworkID: 0,
|
NetworkID: kc.networkID,
|
||||||
ChainID: ids.Empty,
|
ChainID: kc.chainID,
|
||||||
}
|
}
|
||||||
for i := uint32(0); i < uint32(len(addresses)) && len(keys) < threshold; i++ {
|
for i := uint32(0); i < uint32(len(addresses)) && len(keys) < threshold; i++ {
|
||||||
if key, exists := kc.Get(addresses[i]); exists {
|
if key, exists := kc.Get(addresses[i]); exists {
|
||||||
|
|
|
@ -315,7 +315,7 @@ func (vm *VM) Send(amount uint64, assetID, toAddrStr string, fromPKs []string) (
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add all of the keys in [fromPKs] to a keychain
|
// Add all of the keys in [fromPKs] to a keychain
|
||||||
keychain := Keychain{}
|
keychain := NewKeychain(vm.ctx.NetworkID, vm.ctx.ChainID)
|
||||||
factory := crypto.FactorySECP256K1R{}
|
factory := crypto.FactorySECP256K1R{}
|
||||||
cb58 := formatting.CB58{}
|
cb58 := formatting.CB58{}
|
||||||
for _, fpk := range fromPKs {
|
for _, fpk := range fromPKs {
|
||||||
|
@ -359,7 +359,7 @@ func (vm *VM) Send(amount uint64, assetID, toAddrStr string, fromPKs []string) (
|
||||||
ChainID: vm.ctx.ChainID,
|
ChainID: vm.ctx.ChainID,
|
||||||
}
|
}
|
||||||
currentTime := vm.clock.Unix()
|
currentTime := vm.clock.Unix()
|
||||||
tx, err := builder.NewTxFromUTXOs(&keychain, utxos, amount, vm.TxFee, 0, 1, toAddrs, outAddr, currentTime)
|
tx, err := builder.NewTxFromUTXOs(keychain, utxos, amount, vm.TxFee, 0, 1, toAddrs, outAddr, currentTime)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,12 +19,10 @@ import (
|
||||||
"github.com/ava-labs/gecko/xputtest/avmwallet"
|
"github.com/ava-labs/gecko/xputtest/avmwallet"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (n *network) benchmarkAVM(genesisState *platformvm.Genesis) {
|
// benchmark an instance of the avm
|
||||||
avmChain := genesisState.Chains[0]
|
func (n *network) benchmarkAVM(chain *platformvm.CreateChainTx) {
|
||||||
n.log.AssertTrue(avmChain.ChainName == "AVM", "wrong chain name")
|
genesisBytes := chain.GenesisData
|
||||||
genesisBytes := avmChain.GenesisData
|
wallet, err := avmwallet.NewWallet(n.networkID, chain.ID(), config.AvaTxFee)
|
||||||
|
|
||||||
wallet, err := avmwallet.NewWallet(n.networkID, avmChain.ID(), config.AvaTxFee)
|
|
||||||
n.log.AssertNoError(err)
|
n.log.AssertNoError(err)
|
||||||
|
|
||||||
cb58 := formatting.CB58{}
|
cb58 := formatting.CB58{}
|
||||||
|
@ -56,9 +54,10 @@ func (n *network) benchmarkAVM(genesisState *platformvm.Genesis) {
|
||||||
|
|
||||||
n.log.AssertNoError(wallet.GenerateTxs(config.NumTxs, assetID))
|
n.log.AssertNoError(wallet.GenerateTxs(config.NumTxs, assetID))
|
||||||
|
|
||||||
go n.log.RecoverAndPanic(func() { n.IssueAVM(avmChain.ID(), assetID, wallet) })
|
go n.log.RecoverAndPanic(func() { n.IssueAVM(chain.ID(), assetID, wallet) })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// issue transactions to the instance of the avm funded by the provided wallet
|
||||||
func (n *network) IssueAVM(chainID ids.ID, assetID ids.ID, wallet *avmwallet.Wallet) {
|
func (n *network) IssueAVM(chainID ids.ID, assetID ids.ID, wallet *avmwallet.Wallet) {
|
||||||
n.log.Debug("Issuing with %d", wallet.Balance(assetID))
|
n.log.Debug("Issuing with %d", wallet.Balance(assetID))
|
||||||
numAccepted := 0
|
numAccepted := 0
|
||||||
|
|
|
@ -13,8 +13,12 @@ import (
|
||||||
|
|
||||||
// UTXOSet ...
|
// UTXOSet ...
|
||||||
type UTXOSet struct {
|
type UTXOSet struct {
|
||||||
// This can be used to iterate over. However, it should not be modified externally.
|
// Key: The id of a UTXO
|
||||||
|
// Value: The index in UTXOs of that UTXO
|
||||||
utxoMap map[[32]byte]int
|
utxoMap map[[32]byte]int
|
||||||
|
|
||||||
|
// List of UTXOs in this set
|
||||||
|
// This can be used to iterate over. It should not be modified externally.
|
||||||
UTXOs []*avm.UTXO
|
UTXOs []*avm.UTXO
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -13,7 +13,6 @@ import (
|
||||||
"github.com/ava-labs/gecko/utils/formatting"
|
"github.com/ava-labs/gecko/utils/formatting"
|
||||||
"github.com/ava-labs/gecko/utils/units"
|
"github.com/ava-labs/gecko/utils/units"
|
||||||
"github.com/ava-labs/gecko/vms/avm"
|
"github.com/ava-labs/gecko/vms/avm"
|
||||||
"github.com/ava-labs/gecko/vms/platformvm"
|
|
||||||
"github.com/ava-labs/gecko/vms/secp256k1fx"
|
"github.com/ava-labs/gecko/vms/secp256k1fx"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -245,20 +244,7 @@ func TestWalletWithGenesis(t *testing.T) {
|
||||||
w.ImportKey(sk.(*crypto.PrivateKeySECP256K1R))
|
w.ImportKey(sk.(*crypto.PrivateKeySECP256K1R))
|
||||||
}
|
}
|
||||||
|
|
||||||
platformGenesisBytes := genesis.Genesis(genesis.LocalID)
|
avmChain := genesis.VMGenesis(ctx.NetworkID, avm.ID)
|
||||||
genesisState := &platformvm.Genesis{}
|
|
||||||
err = platformvm.Codec.Unmarshal(platformGenesisBytes, genesisState)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
if err := genesisState.Initialize(); err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
avmChain := genesisState.Chains[0]
|
|
||||||
if name := avmChain.ChainName; name != "AVM" {
|
|
||||||
t.Fatalf("wrong chain name")
|
|
||||||
}
|
|
||||||
genesisBytes := avmChain.GenesisData
|
genesisBytes := avmChain.GenesisData
|
||||||
|
|
||||||
genesis := avm.Genesis{}
|
genesis := avm.Genesis{}
|
||||||
|
@ -282,8 +268,8 @@ func TestWalletWithGenesis(t *testing.T) {
|
||||||
|
|
||||||
assetID := genesisTx.ID()
|
assetID := genesisTx.ID()
|
||||||
|
|
||||||
if balance := w.Balance(assetID); balance != 45*units.MegaAva {
|
if balance := w.Balance(assetID); balance == 0 {
|
||||||
t.Fatalf("balance of %d was expected but got %d", 45*units.MegaAva, balance)
|
t.Fatalf("expected a positive balance")
|
||||||
}
|
}
|
||||||
|
|
||||||
for i := 1; i <= 1000; i++ {
|
for i := 1; i <= 1000; i++ {
|
||||||
|
|
|
@ -25,8 +25,8 @@ type Wallet struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewWallet ...
|
// NewWallet ...
|
||||||
func NewWallet(networkID uint32, chainID ids.ID) Wallet {
|
func NewWallet(networkID uint32, chainID ids.ID) *Wallet {
|
||||||
return Wallet{
|
return &Wallet{
|
||||||
networkID: networkID,
|
networkID: networkID,
|
||||||
chainID: chainID,
|
chainID: chainID,
|
||||||
keychain: spchainvm.NewKeychain(networkID, chainID),
|
keychain: spchainvm.NewKeychain(networkID, chainID),
|
||||||
|
@ -35,7 +35,13 @@ func NewWallet(networkID uint32, chainID ids.ID) Wallet {
|
||||||
}
|
}
|
||||||
|
|
||||||
// CreateAddress returns a brand new address! Ready to receive funds!
|
// CreateAddress returns a brand new address! Ready to receive funds!
|
||||||
func (w *Wallet) CreateAddress() ids.ShortID { return w.keychain.New().PublicKey().Address() }
|
func (w *Wallet) CreateAddress() (ids.ShortID, error) {
|
||||||
|
sk, err := w.keychain.New()
|
||||||
|
if err != nil {
|
||||||
|
return ids.ShortID{}, err
|
||||||
|
}
|
||||||
|
return sk.PublicKey().Address(), nil
|
||||||
|
}
|
||||||
|
|
||||||
// ImportKey imports a private key into this wallet
|
// ImportKey imports a private key into this wallet
|
||||||
func (w *Wallet) ImportKey(sk *crypto.PrivateKeySECP256K1R) { w.keychain.Add(sk) }
|
func (w *Wallet) ImportKey(sk *crypto.PrivateKeySECP256K1R) { w.keychain.Add(sk) }
|
||||||
|
@ -61,60 +67,16 @@ func (w *Wallet) GenerateTxs(numTxs int) error {
|
||||||
ctx.ChainID = w.chainID
|
ctx.ChainID = w.chainID
|
||||||
|
|
||||||
w.txs = make([]*spchainvm.Tx, numTxs)
|
w.txs = make([]*spchainvm.Tx, numTxs)
|
||||||
for i := 0; i < numTxs; {
|
for i := range w.txs {
|
||||||
for _, account := range w.accountSet {
|
tx, err := w.MakeTx()
|
||||||
if i >= numTxs {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
|
|
||||||
accountID := account.ID()
|
|
||||||
key, exists := w.keychain.Get(accountID)
|
|
||||||
if !exists {
|
|
||||||
return errors.New("missing account")
|
|
||||||
}
|
|
||||||
|
|
||||||
amount := uint64(1)
|
|
||||||
tx, sendAccount, err := account.CreateTx(amount, accountID, ctx, key)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
newAccount, err := sendAccount.Receive(tx, ctx)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
w.accountSet[accountID.Key()] = newAccount
|
|
||||||
w.txs[i] = tx
|
w.txs[i] = tx
|
||||||
i++
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
// Send a new transaction
|
|
||||||
func (w *Wallet) Send() *spchainvm.Tx {
|
|
||||||
ctx := snow.DefaultContextTest()
|
|
||||||
ctx.NetworkID = w.networkID
|
|
||||||
ctx.ChainID = w.chainID
|
|
||||||
|
|
||||||
for _, account := range w.accountSet {
|
|
||||||
accountID := account.ID()
|
|
||||||
if key, exists := w.keychain.Get(accountID); exists {
|
|
||||||
amount := uint64(1)
|
|
||||||
if tx, sendAccount, err := account.CreateTx(amount, accountID, ctx, key); err == nil {
|
|
||||||
newAccount, err := sendAccount.Receive(tx, ctx)
|
|
||||||
if err == nil {
|
|
||||||
w.accountSet[accountID.Key()] = newAccount
|
|
||||||
return tx
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
// NextTx returns the next tx to be sent as part of xput test
|
// NextTx returns the next tx to be sent as part of xput test
|
||||||
func (w *Wallet) NextTx() *spchainvm.Tx {
|
func (w *Wallet) NextTx() *spchainvm.Tx {
|
||||||
if len(w.txs) == 0 {
|
if len(w.txs) == 0 {
|
||||||
|
@ -125,6 +87,35 @@ func (w *Wallet) NextTx() *spchainvm.Tx {
|
||||||
return tx
|
return tx
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// MakeTx creates a new transaction and update the state to after the tx is accepted
|
||||||
|
func (w *Wallet) MakeTx() (*spchainvm.Tx, error) {
|
||||||
|
ctx := snow.DefaultContextTest()
|
||||||
|
ctx.NetworkID = w.networkID
|
||||||
|
ctx.ChainID = w.chainID
|
||||||
|
|
||||||
|
for _, account := range w.accountSet {
|
||||||
|
accountID := account.ID()
|
||||||
|
key, exists := w.keychain.Get(accountID)
|
||||||
|
if !exists {
|
||||||
|
return nil, errors.New("missing account")
|
||||||
|
}
|
||||||
|
|
||||||
|
amount := uint64(1)
|
||||||
|
tx, sendAccount, err := account.CreateTx(amount, accountID, ctx, key)
|
||||||
|
if err != nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
newAccount, err := sendAccount.Receive(tx, ctx)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
w.accountSet[accountID.Key()] = newAccount
|
||||||
|
return tx, nil
|
||||||
|
}
|
||||||
|
return nil, errors.New("empty")
|
||||||
|
}
|
||||||
|
|
||||||
func (w Wallet) String() string {
|
func (w Wallet) String() string {
|
||||||
return fmt.Sprintf(
|
return fmt.Sprintf(
|
||||||
"Keychain:\n"+
|
"Keychain:\n"+
|
||||||
|
|
|
@ -13,8 +13,12 @@ import (
|
||||||
|
|
||||||
// UTXOSet ...
|
// UTXOSet ...
|
||||||
type UTXOSet struct {
|
type UTXOSet struct {
|
||||||
// This can be used to iterate over. However, it should not be modified externally.
|
// Key: The id of a UTXO
|
||||||
|
// Value: The index in UTXOs of that UTXO
|
||||||
utxoMap map[[32]byte]int
|
utxoMap map[[32]byte]int
|
||||||
|
|
||||||
|
// List of UTXOs in this set
|
||||||
|
// This can be used to iterate over. It should not be modified externally.
|
||||||
UTXOs []*spdagvm.UTXO
|
UTXOs []*spdagvm.UTXO
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -25,11 +25,11 @@ type Wallet struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewWallet returns a new Wallet
|
// NewWallet returns a new Wallet
|
||||||
func NewWallet(networkID uint32, chainID ids.ID, txFee uint64) Wallet {
|
func NewWallet(networkID uint32, chainID ids.ID, txFee uint64) *Wallet {
|
||||||
return Wallet{
|
return &Wallet{
|
||||||
networkID: networkID,
|
networkID: networkID,
|
||||||
chainID: chainID,
|
chainID: chainID,
|
||||||
keychain: &spdagvm.Keychain{},
|
keychain: spdagvm.NewKeychain(networkID, chainID),
|
||||||
utxoSet: &UTXOSet{},
|
utxoSet: &UTXOSet{},
|
||||||
txFee: txFee,
|
txFee: txFee,
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,7 +16,9 @@ import (
|
||||||
"github.com/ava-labs/gecko/ids"
|
"github.com/ava-labs/gecko/ids"
|
||||||
"github.com/ava-labs/gecko/utils/crypto"
|
"github.com/ava-labs/gecko/utils/crypto"
|
||||||
"github.com/ava-labs/gecko/utils/logging"
|
"github.com/ava-labs/gecko/utils/logging"
|
||||||
"github.com/ava-labs/gecko/vms/platformvm"
|
"github.com/ava-labs/gecko/vms/avm"
|
||||||
|
"github.com/ava-labs/gecko/vms/spchainvm"
|
||||||
|
"github.com/ava-labs/gecko/vms/spdagvm"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
|
@ -24,6 +26,7 @@ func main() {
|
||||||
fmt.Printf("Failed to parse arguments: %s\n", err)
|
fmt.Printf("Failed to parse arguments: %s\n", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// set up logging
|
||||||
config.LoggingConfig.Directory = path.Join(config.LoggingConfig.Directory, "client")
|
config.LoggingConfig.Directory = path.Join(config.LoggingConfig.Directory, "client")
|
||||||
log, err := logging.New(config.LoggingConfig)
|
log, err := logging.New(config.LoggingConfig)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -33,6 +36,7 @@ func main() {
|
||||||
|
|
||||||
defer log.Stop()
|
defer log.Stop()
|
||||||
|
|
||||||
|
// initialize state based on CLI args
|
||||||
net.log = log
|
net.log = log
|
||||||
crypto.EnableCrypto = config.EnableCrypto
|
crypto.EnableCrypto = config.EnableCrypto
|
||||||
net.decided = make(chan ids.ID, config.MaxOutstandingTxs)
|
net.decided = make(chan ids.ID, config.MaxOutstandingTxs)
|
||||||
|
@ -42,11 +46,13 @@ func main() {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Init the network
|
||||||
log.AssertNoError(net.Initialize())
|
log.AssertNoError(net.Initialize())
|
||||||
|
|
||||||
net.net.Start()
|
net.net.Start()
|
||||||
defer net.net.Stop()
|
defer net.net.Stop()
|
||||||
|
|
||||||
|
// connect to the node
|
||||||
serr := salticidae.NewError()
|
serr := salticidae.NewError()
|
||||||
remoteIP := salticidae.NewNetAddrFromIPPortString(config.RemoteIP.String(), true, &serr)
|
remoteIP := salticidae.NewNetAddrFromIPPortString(config.RemoteIP.String(), true, &serr)
|
||||||
if code := serr.GetCode(); code != 0 {
|
if code := serr.GetCode(); code != 0 {
|
||||||
|
@ -60,6 +66,7 @@ func main() {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// start a cpu profile
|
||||||
file, gErr := os.Create("cpu_client.profile")
|
file, gErr := os.Create("cpu_client.profile")
|
||||||
log.AssertNoError(gErr)
|
log.AssertNoError(gErr)
|
||||||
gErr = pprof.StartCPUProfile(file)
|
gErr = pprof.StartCPUProfile(file)
|
||||||
|
@ -71,22 +78,19 @@ func main() {
|
||||||
|
|
||||||
net.networkID = config.NetworkID
|
net.networkID = config.NetworkID
|
||||||
|
|
||||||
platformGenesisBytes := genesis.Genesis(net.networkID)
|
// start the benchmark we want to run
|
||||||
genesisState := &platformvm.Genesis{}
|
|
||||||
log.AssertNoError(platformvm.Codec.Unmarshal(platformGenesisBytes, genesisState))
|
|
||||||
log.AssertNoError(genesisState.Initialize())
|
|
||||||
|
|
||||||
switch config.Chain {
|
switch config.Chain {
|
||||||
case spChain:
|
case spChain:
|
||||||
net.benchmarkSPChain(genesisState)
|
net.benchmarkSPChain(genesis.VMGenesis(config.NetworkID, spchainvm.ID))
|
||||||
case spDAG:
|
case spDAG:
|
||||||
net.benchmarkSPDAG(genesisState)
|
net.benchmarkSPDAG(genesis.VMGenesis(config.NetworkID, spdagvm.ID))
|
||||||
case avmDAG:
|
case avmDAG:
|
||||||
net.benchmarkAVM(genesisState)
|
net.benchmarkAVM(genesis.VMGenesis(config.NetworkID, avm.ID))
|
||||||
default:
|
default:
|
||||||
log.Fatal("did not specify whether to test dag or chain. Exiting")
|
log.Fatal("did not specify whether to test dag or chain. Exiting")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// start processing network messages
|
||||||
net.ec.Dispatch()
|
net.ec.Dispatch()
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,12 +19,10 @@ import (
|
||||||
"github.com/ava-labs/gecko/xputtest/chainwallet"
|
"github.com/ava-labs/gecko/xputtest/chainwallet"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (n *network) benchmarkSPChain(genesisState *platformvm.Genesis) {
|
// benchmark an instance of the sp chain
|
||||||
spchainChain := genesisState.Chains[3]
|
func (n *network) benchmarkSPChain(chain *platformvm.CreateChainTx) {
|
||||||
n.log.AssertTrue(spchainChain.ChainName == "Simple Chain Payments", "wrong chain name")
|
genesisBytes := chain.GenesisData
|
||||||
genesisBytes := spchainChain.GenesisData
|
wallet := chainwallet.NewWallet(n.networkID, chain.ID())
|
||||||
|
|
||||||
wallet := chainwallet.NewWallet(n.networkID, spchainChain.ID())
|
|
||||||
|
|
||||||
codec := spchainvm.Codec{}
|
codec := spchainvm.Codec{}
|
||||||
accounts, err := codec.UnmarshalGenesis(genesisBytes)
|
accounts, err := codec.UnmarshalGenesis(genesisBytes)
|
||||||
|
@ -47,10 +45,10 @@ func (n *network) benchmarkSPChain(genesisState *platformvm.Genesis) {
|
||||||
|
|
||||||
n.log.AssertNoError(wallet.GenerateTxs(config.NumTxs))
|
n.log.AssertNoError(wallet.GenerateTxs(config.NumTxs))
|
||||||
|
|
||||||
go n.log.RecoverAndPanic(func() { n.IssueSPChain(spchainChain.ID(), wallet) })
|
go n.log.RecoverAndPanic(func() { n.IssueSPChain(chain.ID(), wallet) })
|
||||||
}
|
}
|
||||||
|
|
||||||
func (n *network) IssueSPChain(chainID ids.ID, wallet chainwallet.Wallet) {
|
func (n *network) IssueSPChain(chainID ids.ID, wallet *chainwallet.Wallet) {
|
||||||
n.log.Debug("Issuing with %d", wallet.Balance())
|
n.log.Debug("Issuing with %d", wallet.Balance())
|
||||||
numAccepted := 0
|
numAccepted := 0
|
||||||
numPending := 0
|
numPending := 0
|
||||||
|
|
|
@ -19,12 +19,10 @@ import (
|
||||||
"github.com/ava-labs/gecko/xputtest/dagwallet"
|
"github.com/ava-labs/gecko/xputtest/dagwallet"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (n *network) benchmarkSPDAG(genesisState *platformvm.Genesis) {
|
// benchmark an instance of the sp dag
|
||||||
spDAGChain := genesisState.Chains[2]
|
func (n *network) benchmarkSPDAG(chain *platformvm.CreateChainTx) {
|
||||||
n.log.AssertTrue(spDAGChain.ChainName == "Simple DAG Payments", "wrong chain name")
|
genesisBytes := chain.GenesisData
|
||||||
genesisBytes := spDAGChain.GenesisData
|
wallet := dagwallet.NewWallet(n.networkID, chain.ID(), config.AvaTxFee)
|
||||||
|
|
||||||
wallet := dagwallet.NewWallet(n.networkID, spDAGChain.ID(), config.AvaTxFee)
|
|
||||||
|
|
||||||
codec := spdagvm.Codec{}
|
codec := spdagvm.Codec{}
|
||||||
tx, err := codec.UnmarshalTx(genesisBytes)
|
tx, err := codec.UnmarshalTx(genesisBytes)
|
||||||
|
@ -43,10 +41,11 @@ func (n *network) benchmarkSPDAG(genesisState *platformvm.Genesis) {
|
||||||
wallet.AddUTXO(utxo)
|
wallet.AddUTXO(utxo)
|
||||||
}
|
}
|
||||||
|
|
||||||
go n.log.RecoverAndPanic(func() { n.IssueSPDAG(spDAGChain.ID(), wallet) })
|
go n.log.RecoverAndPanic(func() { n.IssueSPDAG(chain.ID(), wallet) })
|
||||||
}
|
}
|
||||||
|
|
||||||
func (n *network) IssueSPDAG(chainID ids.ID, wallet dagwallet.Wallet) {
|
// issue transactions to the instance of the spdag funded by the provided wallet
|
||||||
|
func (n *network) IssueSPDAG(chainID ids.ID, wallet *dagwallet.Wallet) {
|
||||||
n.log.Info("starting avalanche benchmark")
|
n.log.Info("starting avalanche benchmark")
|
||||||
pending := make(map[[32]byte]*spdagvm.Tx)
|
pending := make(map[[32]byte]*spdagvm.Tx)
|
||||||
canAdd := []*spdagvm.Tx{}
|
canAdd := []*spdagvm.Tx{}
|
||||||
|
|
Loading…
Reference in New Issue