diff options
author | Determinant <[email protected]> | 2020-08-19 23:34:12 -0400 |
---|---|---|
committer | Determinant <[email protected]> | 2020-08-19 23:34:12 -0400 |
commit | 40879ea67433b73b464bd8b012a9809fbb646cfd (patch) | |
tree | a11646c8f69a217c936322bd937915b2ecc7bdba /plugin/evm/vm.go | |
parent | 0b934ef60fd652de038a21e6f25691b11cea7121 (diff) |
WIP: C-to-X transfer
Diffstat (limited to 'plugin/evm/vm.go')
-rw-r--r-- | plugin/evm/vm.go | 61 |
1 files changed, 50 insertions, 11 deletions
diff --git a/plugin/evm/vm.go b/plugin/evm/vm.go index baf6106..5bb8ac0 100644 --- a/plugin/evm/vm.go +++ b/plugin/evm/vm.go @@ -22,6 +22,7 @@ import ( "github.com/ava-labs/coreth/node" "github.com/ava-labs/go-ethereum/common" + ethcrypto "github.com/ava-labs/go-ethereum/crypto" "github.com/ava-labs/go-ethereum/rlp" "github.com/ava-labs/go-ethereum/rpc" avarpc "github.com/gorilla/rpc/v2" @@ -34,6 +35,7 @@ import ( "github.com/ava-labs/gecko/snow/choices" "github.com/ava-labs/gecko/snow/consensus/snowman" "github.com/ava-labs/gecko/utils/codec" + "github.com/ava-labs/gecko/utils/crypto" avajson "github.com/ava-labs/gecko/utils/json" "github.com/ava-labs/gecko/utils/timer" "github.com/ava-labs/gecko/utils/wrappers" @@ -48,6 +50,7 @@ var ( 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, } + x2cRate = big.NewInt(1000000000) ) const ( @@ -160,6 +163,15 @@ func (vm *VM) getAtomicTx(block *types.Block) *Tx { return atx } +func importTxStateTransfer(tx *UnsignedImportTx, state *state.StateDB) { + for _, to := range tx.Outs { + amount := new(big.Int).SetUint64(to.Amount) + state.AddBalance(to.Address, new(big.Int).Mul(amount, x2cRate)) + nonce := state.GetNonce(to.Address) + state.SetNonce(to.Address, nonce+1) + } +} + /* ****************************************************************************** ********************************* Snowman API ******************************** @@ -213,11 +225,7 @@ func (vm *VM) Initialize( chain.SetOnFinalizeAndAssemble(func(state *state.StateDB, txs []*types.Transaction) ([]byte, error) { select { case atx := <-vm.pendingAtomicTxs: - for _, to := range atx.UnsignedTx.(*UnsignedImportTx).Outs { - amount := new(big.Int) - amount.SetUint64(to.Amount) - state.AddBalance(to.Address, amount) - } + importTxStateTransfer(atx.UnsignedTx.(*UnsignedImportTx), state) raw, _ := vm.codec.Marshal(atx) return raw, nil default: @@ -250,13 +258,9 @@ func (vm *VM) Initialize( chain.SetOnQueryAcceptedBlock(func() *types.Block { return vm.getLastAccepted().ethBlock }) - chain.SetOnExtraStateChange(func(block *types.Block, statedb *state.StateDB) error { + chain.SetOnExtraStateChange(func(block *types.Block, state *state.StateDB) error { atx := vm.getAtomicTx(block).UnsignedTx.(*UnsignedImportTx) - for _, to := range atx.Outs { - amount := new(big.Int) - amount.SetUint64(to.Amount) - statedb.AddBalance(to.Address, amount) - } + importTxStateTransfer(atx, state) return nil }) vm.blockCache = cache.LRU{Size: 2048} @@ -683,3 +687,38 @@ func (vm *VM) GetAtomicUTXOs( }} return utxos, ids.ShortEmpty, ids.Empty, nil } + +func GetEthAddress(privKey *crypto.PrivateKeySECP256K1R) common.Address { + return ethcrypto.PubkeyToAddress( + (*privKey.PublicKey().(*crypto.PublicKeySECP256K1R).ToECDSA())) +} + +func (vm *VM) GetSpendableCanonical(keys []*crypto.PrivateKeySECP256K1R, amount uint64) ([]EVMInput, [][]*crypto.PrivateKeySECP256K1R, error) { + // NOTE: should we use HEAD block or lastAccepted? + state, err := vm.chain.BlockState(vm.lastAccepted.ethBlock) + if err != nil { + return nil, nil, err + } + inputs := []EVMInput{} + signers := [][]*crypto.PrivateKeySECP256K1R{} + for _, key := range keys { + if amount == 0 { + break + } + addr := GetEthAddress(key) + balance := new(big.Int).Div(state.GetBalance(addr), x2cRate).Uint64() + if amount < balance { + balance = amount + } + inputs = append(inputs, EVMInput{ + Address: addr, + Amount: balance, + }) + signers = append(signers, []*crypto.PrivateKeySECP256K1R{key}) + amount -= balance + } + if amount > 0 { + return nil, nil, errInsufficientFunds + } + return inputs, signers, nil +} |