mirror of
https://github.com/0glabs/0g-chain.git
synced 2024-12-25 15:55:18 +00:00
daa1b2bb83
* add collateral type field to cdp and collateral param * fix upstream tests * fix simulations * fix validation logic * update incentive to use collateral type instead of denom * use collateral type instead of denom in cdp * remove unused code * address review comments
489 lines
12 KiB
Go
489 lines
12 KiB
Go
package main
|
|
|
|
import (
|
|
"bytes"
|
|
"fmt"
|
|
"io/ioutil"
|
|
"net/http"
|
|
"strings"
|
|
"time"
|
|
|
|
"github.com/cosmos/cosmos-sdk/codec"
|
|
crkeys "github.com/cosmos/cosmos-sdk/crypto/keys"
|
|
sdk "github.com/cosmos/cosmos-sdk/types"
|
|
sdkrest "github.com/cosmos/cosmos-sdk/types/rest"
|
|
"github.com/cosmos/cosmos-sdk/version"
|
|
"github.com/cosmos/cosmos-sdk/x/auth"
|
|
authrest "github.com/cosmos/cosmos-sdk/x/auth/client/rest"
|
|
authclient "github.com/cosmos/cosmos-sdk/x/auth/client/utils"
|
|
authexported "github.com/cosmos/cosmos-sdk/x/auth/exported"
|
|
"github.com/cosmos/cosmos-sdk/x/bank"
|
|
"github.com/cosmos/cosmos-sdk/x/gov"
|
|
"github.com/cosmos/cosmos-sdk/x/gov/types"
|
|
"github.com/cosmos/cosmos-sdk/x/staking"
|
|
|
|
tmtime "github.com/tendermint/tendermint/types/time"
|
|
|
|
"github.com/kava-labs/kava/app"
|
|
"github.com/kava-labs/kava/x/cdp"
|
|
"github.com/kava-labs/kava/x/pricefeed"
|
|
)
|
|
|
|
func init() {
|
|
version.Name = "kava"
|
|
config := sdk.GetConfig()
|
|
app.SetBech32AddressPrefixes(config)
|
|
app.SetBip44CoinType(config)
|
|
config.Seal()
|
|
keybase = getKeybase()
|
|
}
|
|
|
|
var (
|
|
keybase crkeys.Keybase
|
|
)
|
|
|
|
func main() {
|
|
|
|
// setup messages send to blockchain so it is in the correct state for testing
|
|
sendProposal()
|
|
sendDeposit()
|
|
sendVote()
|
|
sendDelegation()
|
|
sendUndelegation()
|
|
sendCoins()
|
|
|
|
// create an XRP cdp and send to blockchain
|
|
sendXrpCdp()
|
|
|
|
// create a BTC cdp and send to blockchain
|
|
sendBtcCdp()
|
|
|
|
// reduce the price of BTC to trigger an auction
|
|
sendMsgPostPrice()
|
|
}
|
|
|
|
// lower the price of xrp to trigger an auction
|
|
func sendMsgPostPrice() {
|
|
// get the address
|
|
address := getTestAddress()
|
|
// get the keyname and password
|
|
keyname, password := getKeynameAndPassword()
|
|
|
|
addr, err := sdk.AccAddressFromBech32(address) // validator address
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
price, err := sdk.NewDecFromStr("1")
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
// set the expiry time
|
|
expiry := tmtime.Now().Add(time.Second * 100000)
|
|
|
|
// create a cdp message to send to the blockchain
|
|
// from, assetcode, price, expiry
|
|
msg := pricefeed.NewMsgPostPrice(
|
|
addr,
|
|
"btc:usd",
|
|
price,
|
|
expiry,
|
|
)
|
|
|
|
// helper methods for transactions
|
|
cdc := app.MakeCodec() // make codec for the app
|
|
|
|
// get the keybase
|
|
keybase := getKeybase()
|
|
|
|
// cast to the generic msg type
|
|
msgToSend := []sdk.Msg{msg}
|
|
|
|
// send the message to the blockchain
|
|
sendMsgToBlockchain(cdc, address, keyname, password, msgToSend, keybase)
|
|
|
|
}
|
|
|
|
func sendBtcCdp() {
|
|
// get the address
|
|
address := getTestAddress()
|
|
// get the keyname and password
|
|
keyname, password := getKeynameAndPassword()
|
|
|
|
addr, err := sdk.AccAddressFromBech32(address) // validator address
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
// create a cdp message to send to the blockchain
|
|
// sender, collateral, principal
|
|
msg := cdp.NewMsgCreateCDP(
|
|
addr,
|
|
sdk.NewInt64Coin("btc", 200000000),
|
|
sdk.NewInt64Coin("usdx", 10000000),
|
|
"btc-a",
|
|
)
|
|
|
|
// helper methods for transactions
|
|
cdc := app.MakeCodec() // make codec for the app
|
|
|
|
// get the keybase
|
|
keybase := getKeybase()
|
|
|
|
// cast to the generic msg type
|
|
msgToSend := []sdk.Msg{msg}
|
|
|
|
// send the message to the blockchain
|
|
sendMsgToBlockchain(cdc, address, keyname, password, msgToSend, keybase)
|
|
|
|
}
|
|
|
|
func sendXrpCdp() {
|
|
// get the address
|
|
address := getTestAddress()
|
|
// get the keyname and password
|
|
keyname, password := getKeynameAndPassword()
|
|
|
|
addr, err := sdk.AccAddressFromBech32(address) // validator address
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
// create a cdp message to send to the blockchain
|
|
// sender, collateral, principal
|
|
msg := cdp.NewMsgCreateCDP(
|
|
addr,
|
|
sdk.NewInt64Coin("xrp", 200000000),
|
|
sdk.NewInt64Coin("usdx", 10000000),
|
|
"xrp-a",
|
|
)
|
|
|
|
// helper methods for transactions
|
|
cdc := app.MakeCodec() // make codec for the app
|
|
|
|
// get the keybase
|
|
keybase := getKeybase()
|
|
|
|
// cast to the generic msg type
|
|
msgToSend := []sdk.Msg{msg}
|
|
|
|
// send the message to the blockchain
|
|
sendMsgToBlockchain(cdc, address, keyname, password, msgToSend, keybase)
|
|
|
|
}
|
|
|
|
func sendProposal() {
|
|
// get the address
|
|
address := getTestAddress()
|
|
// get the keyname and password
|
|
keyname, password := getKeynameAndPassword()
|
|
|
|
proposalContent := gov.ContentFromProposalType("A Test Title", "A test description on this proposal.", gov.ProposalTypeText)
|
|
addr, err := sdk.AccAddressFromBech32(address) // validator address
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
// create a message to send to the blockchain
|
|
msg := gov.NewMsgSubmitProposal(
|
|
proposalContent,
|
|
sdk.NewCoins(sdk.NewInt64Coin("stake", 1000)),
|
|
addr,
|
|
)
|
|
|
|
// helper methods for transactions
|
|
cdc := app.MakeCodec() // make codec for the app
|
|
|
|
// get the keybase
|
|
keybase := getKeybase()
|
|
|
|
// SEND THE PROPOSAL
|
|
// cast to the generic msg type
|
|
msgToSend := []sdk.Msg{msg}
|
|
|
|
// send the PROPOSAL message to the blockchain
|
|
sendMsgToBlockchain(cdc, address, keyname, password, msgToSend, keybase)
|
|
|
|
}
|
|
|
|
func sendDeposit() {
|
|
// get the address
|
|
address := getTestAddress()
|
|
// get the keyname and password
|
|
keyname, password := getKeynameAndPassword()
|
|
|
|
addr, err := sdk.AccAddressFromBech32(address) // validator
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
// helper methods for transactions
|
|
cdc := app.MakeCodec() // make codec for the app
|
|
|
|
// get the keybase
|
|
keybase := getKeybase()
|
|
|
|
// NOW SEND THE DEPOSIT
|
|
|
|
// create a deposit transaction to send to the proposal
|
|
amount := sdk.NewCoins(sdk.NewInt64Coin(sdk.DefaultBondDenom, 10000000))
|
|
deposit := gov.NewMsgDeposit(addr, 1, amount) // Note: '1' must match 'x-example' in swagger.yaml
|
|
depositToSend := []sdk.Msg{deposit}
|
|
|
|
sendMsgToBlockchain(cdc, address, keyname, password, depositToSend, keybase)
|
|
|
|
}
|
|
|
|
func sendVote() {
|
|
// get the address
|
|
address := getTestAddress()
|
|
// get the keyname and password
|
|
keyname, password := getKeynameAndPassword()
|
|
|
|
addr, err := sdk.AccAddressFromBech32(address) // validator
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
// helper methods for transactions
|
|
cdc := app.MakeCodec() // make codec for the app
|
|
|
|
// get the keybase
|
|
keybase := getKeybase()
|
|
|
|
// NOW SEND THE VOTE
|
|
|
|
// create a vote on a proposal to send to the blockchain
|
|
vote := gov.NewMsgVote(addr, uint64(1), types.OptionYes) // Note: '1' must match 'x-example' in swagger.yaml
|
|
|
|
// send a vote to the blockchain
|
|
voteToSend := []sdk.Msg{vote}
|
|
sendMsgToBlockchain(cdc, address, keyname, password, voteToSend, keybase)
|
|
|
|
}
|
|
|
|
// this should send coins from one address to another
|
|
func sendCoins() {
|
|
// get the address
|
|
address := getTestAddress()
|
|
// get the keyname and password
|
|
keyname, password := getKeynameAndPassword()
|
|
|
|
addrFrom, err := sdk.AccAddressFromBech32(address) // validator
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
addrTo, err := sdk.AccAddressFromBech32("kava1ls82zzghsx0exkpr52m8vht5jqs3un0ceysshz") // Note: must match the faucet address
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
// helper methods for transactions
|
|
cdc := app.MakeCodec() // make codec for the app
|
|
|
|
// get the keybase
|
|
keybase := getKeybase()
|
|
|
|
// create coins
|
|
amount := sdk.NewCoins(sdk.NewInt64Coin(sdk.DefaultBondDenom, 2000000))
|
|
|
|
coins := bank.NewMsgSend(addrFrom, addrTo, amount) // Note: '1' must match 'x-example' in swagger.yaml
|
|
coinsToSend := []sdk.Msg{coins}
|
|
|
|
// NOW SEND THE COINS
|
|
|
|
// send the coin message to the blockchain
|
|
sendMsgToBlockchain(cdc, address, keyname, password, coinsToSend, keybase)
|
|
|
|
}
|
|
|
|
func getTestAddress() (address string) {
|
|
// the test address - Note: this must match with startchain.sh
|
|
address = "kava1ffv7nhd3z6sych2qpqkk03ec6hzkmufy0r2s4c"
|
|
return address
|
|
}
|
|
|
|
func getKeynameAndPassword() (keyname string, password string) {
|
|
keyname = "vlad" // Note: this must match the keys in the startchain.sh script
|
|
password = "" // Note: this must match the keys in the startchain.sh script
|
|
return keyname, password
|
|
}
|
|
|
|
// this should send a delegation
|
|
func sendDelegation() {
|
|
// get the address
|
|
address := getTestAddress()
|
|
// get the keyname and password
|
|
keyname, password := getKeynameAndPassword()
|
|
|
|
addrFrom, err := sdk.AccAddressFromBech32(address) // validator
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
// helper methods for transactions
|
|
cdc := app.MakeCodec() // make codec for the app
|
|
|
|
// get the keybase
|
|
keybase := getKeybase()
|
|
|
|
// get the validator address for delegation
|
|
valAddr, err := sdk.ValAddressFromBech32("kavavaloper1ffv7nhd3z6sych2qpqkk03ec6hzkmufyz4scd0") // **FAUCET**
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
// create delegation amount
|
|
delAmount := sdk.NewInt64Coin(sdk.DefaultBondDenom, 1000000)
|
|
delegation := staking.NewMsgDelegate(addrFrom, valAddr, delAmount)
|
|
delegationToSend := []sdk.Msg{delegation}
|
|
|
|
// send the delegation to the blockchain
|
|
sendMsgToBlockchain(cdc, address, keyname, password, delegationToSend, keybase)
|
|
}
|
|
|
|
// this should send a MsgUndelegate
|
|
func sendUndelegation() {
|
|
// get the address
|
|
address := getTestAddress()
|
|
// get the keyname and password
|
|
keyname, password := getKeynameAndPassword()
|
|
|
|
addrFrom, err := sdk.AccAddressFromBech32(address) // validator
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
// helper methods for transactions
|
|
cdc := app.MakeCodec() // make codec for the app
|
|
|
|
// get the keybase
|
|
keybase := getKeybase()
|
|
|
|
// get the validator address for delegation
|
|
valAddr, err := sdk.ValAddressFromBech32("kavavaloper1ffv7nhd3z6sych2qpqkk03ec6hzkmufyz4scd0") // **FAUCET**
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
// create delegation amount
|
|
undelAmount := sdk.NewInt64Coin(sdk.DefaultBondDenom, 1000000)
|
|
undelegation := staking.NewMsgUndelegate(addrFrom, valAddr, undelAmount)
|
|
delegationToSend := []sdk.Msg{undelegation}
|
|
|
|
// send the delegation to the blockchain
|
|
sendMsgToBlockchain(cdc, address, keyname, password, delegationToSend, keybase)
|
|
|
|
}
|
|
|
|
func getKeybase() crkeys.Keybase {
|
|
|
|
if keybase != nil {
|
|
return keybase
|
|
}
|
|
|
|
// create a keybase
|
|
// IMPORTANT - TAKE THIS FROM COMMAND LINE PARAMETER and does NOT work with tilde i.e. ~/ does NOT work
|
|
// myKeybase, err := keys.NewKeyBaseFromDir("/tmp/kvcliHome")
|
|
|
|
inBuf := strings.NewReader("")
|
|
keybase, err := crkeys.NewKeyring(sdk.KeyringServiceName(),
|
|
"test", "/tmp/kvcliHome", inBuf)
|
|
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
return keybase
|
|
}
|
|
|
|
// sendMsgToBlockchain sends a message to the blockchain via the rest api
|
|
func sendMsgToBlockchain(cdc *codec.Codec, address string, keyname string,
|
|
password string, msg []sdk.Msg, keybase crkeys.Keybase) {
|
|
|
|
// get the account number and sequence number
|
|
accountNumber, sequenceNumber := getAccountNumberAndSequenceNumber(cdc, address)
|
|
|
|
txBldr := auth.NewTxBuilder(
|
|
authclient.GetTxEncoder(cdc), accountNumber, sequenceNumber, 500000, 0,
|
|
true, "testing", "memo", sdk.NewCoins(), sdk.NewDecCoins(),
|
|
).WithTxEncoder(authclient.GetTxEncoder(cdc)).WithChainID("testing").
|
|
WithKeybase(keybase).WithAccountNumber(accountNumber).
|
|
WithSequence(sequenceNumber).WithGas(500000)
|
|
|
|
// build and sign the transaction
|
|
// this is the *Amino* encoded version of the transaction
|
|
txBytes, err := txBldr.BuildAndSign("vlad", "", msg)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
// fmt.Printf("txBytes: %s", txBytes)
|
|
|
|
// need to convert the Amino encoded version back to an actual go struct
|
|
var tx auth.StdTx
|
|
cdc.UnmarshalBinaryLengthPrefixed(txBytes, &tx) // might be unmarshal binary bare
|
|
|
|
// now we re-marshall it again into json
|
|
jsonBytes, err := cdc.MarshalJSON(
|
|
authrest.BroadcastReq{
|
|
Tx: tx,
|
|
Mode: "block",
|
|
},
|
|
)
|
|
|
|
fmt.Printf("%s", bytes.NewBuffer(jsonBytes))
|
|
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
fmt.Println()
|
|
fmt.Println("post body: ", string(jsonBytes))
|
|
fmt.Println()
|
|
|
|
resp, err := http.Post("http://localhost:1317/txs", "application/json", bytes.NewBuffer(jsonBytes))
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
defer resp.Body.Close()
|
|
body, err := ioutil.ReadAll(resp.Body)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
fmt.Printf("\n\nBody:\n\n")
|
|
fmt.Println(string(body))
|
|
|
|
}
|
|
|
|
// getAccountNumberAndSequenceNumber gets an account number and sequence number from the blockchain
|
|
func getAccountNumberAndSequenceNumber(cdc *codec.Codec, address string) (accountNumber uint64, sequenceNumber uint64) {
|
|
|
|
// we need to setup the account number and sequence in order to have a valid transaction
|
|
resp, err := http.Get("http://localhost:1317/auth/accounts/" + address)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
defer resp.Body.Close()
|
|
body, err := ioutil.ReadAll(resp.Body)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
var bodyUnmarshalled sdkrest.ResponseWithHeight
|
|
err = cdc.UnmarshalJSON(body, &bodyUnmarshalled)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
var account authexported.Account
|
|
err = cdc.UnmarshalJSON(bodyUnmarshalled.Result, &account)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
return account.GetAccountNumber(), account.GetSequence()
|
|
|
|
}
|