-
Notifications
You must be signed in to change notification settings - Fork 10
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
genesis balance allocations and transfer transaction #392
Conversation
type Transfer struct { | ||
To []byte `json:"to"` // to be string as user identifier | ||
Amount string `json:"amount"` // big.Int | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@KwilLuke There's more to do with this PR before it's ready for review, but it is working and this is the payload structure, of type PayloadTypeTransfer = "transfer"
.
The genesis config specifies accounts (pubkey presently, but will probably change when identifier work is merged) with balances, so a faucet would just have the corresponding private key to control the funds.
kwil-cli has a transfer
command and the client
package has a Transfer
method: https://github.com/kwilteam/kwil-db/pull/392/files#diff-c3fd86c44b5f4a4cf8bad895c77a7514c9a6b72d3c1c6da608545168bdecaf3a (just as an example, it's really simple)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@brennanjl Just to talk through the implications of the planned identifier changes on the alloc specification in genesis, we have this presently:
"genesis_time": "2023-11-20T23:39:42.725453464Z",
"chain_id": "kwil-chain-KtqCimeh",
"initial_height": 1,
"app_hash": null,
"alloc": {
"040dfec0a4e644dc129ace6e40d813cd65a21874586b9c782cd1779e44f2719f11f74d7d6d76c09f281ce5588dabdd0dab3e59b7f974de4c045da8b727c4521d0b": 12345678900000000000
},
"consensus_params": {
...
That "alloc"
specifies accounts with their balances at genesis. This PR is based on main
, so that's public key hex. This would become something else. I suppose if that account is controlled via eth "personal_sign" then it would be the 20 bytes of the address (in json key as hex string), as would be the case since our SDKs default to that except for the validator transactions. If it is controlled with an ed25519 signer, then I think it would be the hex of the public key.
Not really seeing any problems, but wanted to describe it in the context of identifiers.
7eb34d8
to
aafa64b
Compare
In our system, how much will database deploys and action transactions cost? Will it be 1 unit, or it will it be 10^18 units like in Ethereum? |
2af1b88
to
1b1dd87
Compare
Presently it's all hard coded, but we're still using "wei" with lots of zeros: var (
defaultDeployPrice = big.NewInt(1000000000000000000)
defaultDropPrice = big.NewInt(10000000000000)
defaultExecutePrice = big.NewInt(2000000000000000)
) |
Okay - if each user requests 10 * 10^18 tokens, we will probably just want to make sure we initialize the test network with more than a sufficient number of tokens. Maybe 1 billion * 10^18? |
0a8bb44
to
6542d15
Compare
Needs some cleanup, but I've checked all the boxes and it's working (for Luke and acceptance tests), so making ready for review. |
|
||
var drivers = flag.String("drivers", "http,cli", "comma separated list of drivers to run") | ||
|
||
func TestKwildTransferAcceptance(t *testing.T) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@Yaiba The approach here is very close with what you described in the README. Only difference is that I didn't see a purpose to defining a specification struct that would provide these methods, rather just convert the driver into the specific spec being tested.
Also I made an exported ExpectTxSuccess
helper, which was really the only thing in a hypothetical spec struct that would not just be a passthrough to the driver.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This will do, at least for acceptance test. The idea of a spec is mostly make a behavior into a thingy for reuse.
In this test transfer case, you transfer, you expect balance changes on sender and receiver.
Any other tests requires transfer would just simple reuse this spec. For example, if you also need to transfer in integration test, a spec will be handy
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looking at https://github.com/kwilteam/kwil-db/blob/main/test/specifications/README.md, that suggest it's the Dsls that are reusable, not the specs. I'm confused now.
It becomes difficult to write a spec that does not have a bunch of parameters as input args, so it looked from the README that the suggestion was to have the test case itself use the DSLs and implement the spec right there. Note how the concrete spec you've suggested is just wrappers.
// TransferTx is used to handle a transfer transaction. This involves: | ||
// - check that transaction fee is adequate | ||
// - pay for the transaction gas, updating balance and nonce in the DB | ||
// - transfer value from the sender account to the recipient account | ||
// | ||
// The blockchain application will have decoded the transaction and payload, and | ||
// passed only the required data via TxAcct. | ||
func (am *AccountsModule) TransferTx(ctx context.Context, tx *TxAcct, to []byte, amt *big.Int) error { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This and PriceTransfer
are the main reasons why it felt like there needed to be an actual blockchain module rather than having the account store being directly used by the ABCI app. I'm trying to keep the account store focused on DB-related concerns. The existing Spend
method there gets a little too concerned with nonces and such in this view, but I didn't want to change more than necessary.
@@ -116,6 +119,6 @@ func (u *DatasetModule) compareAndSpend(ctx context.Context, price *big.Int, tx | |||
func resp(fee *big.Int) *ExecutionResponse { | |||
return &ExecutionResponse{ | |||
Fee: fee, | |||
GasUsed: 0, | |||
GasUsed: 0, // !? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I need to look back at this. This field looks to be useless and I think there was an intention of using it to convey non-zero values back to abci.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah it was added but not used for anything b/c we do not have gas metering. Can remove in this pr
9171d30
to
eec535c
Compare
|
||
t.Run(driverType+"_driver", func(t *testing.T) { | ||
senderDriver := helper.GetDriver(driverType, "creator") | ||
sender := specifications.TransferAmountDsl(senderDriver) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here's the "spec" that would be reusable. There's no need to make a concrete type that wraps the driver, just convert to the interface.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this makes a lot of sense, however is it worth while to try to maintain the previous way in which Gavin did it?
The only reason I bring this up is because it makes it easier to replicate in integration tests. I would imagine that we would want to check that some functionality (like Transfer
) would not cause non-determinism / a fork. Reusing the logic in this test could be helpful there.
No strong opinion though, mostly just trying to consider all angles.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm a little lost on this spec business TBH. @Yaiba had noted that we haven't been doing it right currently with the one big test case, and he documented the intended way we should gravitate towards here with a test case using one spec: https://github.com/kwilteam/kwil-db/blob/main/test/specifications/README.md
I was actually trying to follow that new example. What was baffling to me is that the "spec" in that README is nothing at all, just a wrapper for the Dsl, which is concretely the "driver". So we have the reusable drivers in test/driver
and the specifications.TransferAmountDsl interface
in test/specifications
. then in test/intergration
we can do like the following in say TestKwildValidatorUpdatesIntegration
:
transfer := specifications.TransferAmountDsl(node0Driver)
transfer.TransferAmt(ctx, joinerPrivKey.Bytes(), big.NewInt(1234567890))
I think I need to see this refactored by @Yaiba to understand the spec/dsl/driver design that's intended. 😆
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry I didn't follow this topic soon enough. Yeah I was going to update the spec readme and it's stashed... I'll update it sooner.
This comment was marked as resolved.
This comment was marked as resolved.
eec535c
to
ee10b53
Compare
I'll squash down more before we merge this. Most of the commits are distinct for easier review though, only a couple stray fixups. Ideally I would have kept squashing as I went went with this, but I gotta switch to review now. |
dfdd4d8
to
d850e20
Compare
// Pay for gas (the tx fee), and increment nonce. | ||
spend := &accounts.Spend{ | ||
AccountID: tx.Sender, | ||
Amount: transferPrice, // not the Fee??? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just responding to the in-line comment here:
We want it to be the transferPrice and not fee because the user might by overly generous with the free.
For example, if you agree to pay 500 gas, but it only costs 400, the user should only be debited 400. Obviously that probably would not happen with a gas system as simple as ours right now, but in the case of dynamic gas it would.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Related issue discussing this point: #410
@@ -116,6 +119,6 @@ func (u *DatasetModule) compareAndSpend(ctx context.Context, price *big.Int, tx | |||
func resp(fee *big.Int) *ExecutionResponse { | |||
return &ExecutionResponse{ | |||
Fee: fee, | |||
GasUsed: 0, | |||
GasUsed: 0, // !? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah it was added but not used for anything b/c we do not have gas metering. Can remove in this pr
|
||
t.Run(driverType+"_driver", func(t *testing.T) { | ||
senderDriver := helper.GetDriver(driverType, "creator") | ||
sender := specifications.TransferAmountDsl(senderDriver) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this makes a lot of sense, however is it worth while to try to maintain the previous way in which Gavin did it?
The only reason I bring this up is because it makes it easier to replicate in integration tests. I would imagine that we would want to check that some functionality (like Transfer
) would not cause non-determinism / a fork. Reusing the logic in this test could be helpful there.
No strong opinion though, mostly just trying to consider all angles.
d9bd9d4
to
001ae13
Compare
0b2b04e
to
4dfc17c
Compare
- Add genesis allocs a la ethereum genesis.json. - Add a transfer tx payload. - client,kwil-cli: add accounts command inc. transfer and balance - Create an accounts blockchain module. - rpc,client: fix errors, http's parseBroadcastResponse, and waittx - test: add acceptance test and require gas in validator integ test
4dfc17c
to
d11d3de
Compare
* workable gas costs with genesis allocs and transfer txn - Add genesis allocs a la ethereum genesis.json. - Add a transfer tx payload. - client,kwil-cli: add accounts command inc. transfer and balance - Create an accounts blockchain module. - rpc,client: fix errors, http's parseBroadcastResponse, and waittx - test: add acceptance test and require gas in validator integ test * special case for eth 0x addresses in genesis allocs * admin: default output-dir for setup cmds to .testnet * fix setup testnet defaults * use GenericSwaggerError to get rpc error details
* workable gas costs with genesis allocs and transfer txn - Add genesis allocs a la ethereum genesis.json. - Add a transfer tx payload. - client,kwil-cli: add accounts command inc. transfer and balance - Create an accounts blockchain module. - rpc,client: fix errors, http's parseBroadcastResponse, and waittx - test: add acceptance test and require gas in validator integ test * special case for eth 0x addresses in genesis allocs * admin: default output-dir for setup cmds to .testnet * fix setup testnet defaults * use GenericSwaggerError to get rpc error details
* workable gas costs with genesis allocs and transfer txn - Add genesis allocs a la ethereum genesis.json. - Add a transfer tx payload. - client,kwil-cli: add accounts command inc. transfer and balance - Create an accounts blockchain module. - rpc,client: fix errors, http's parseBroadcastResponse, and waittx - test: add acceptance test and require gas in validator integ test * special case for eth 0x addresses in genesis allocs * admin: default output-dir for setup cmds to .testnet * fix setup testnet defaults * use GenericSwaggerError to get rpc error details
* workable gas costs with genesis allocs and transfer txn - Add genesis allocs a la ethereum genesis.json. - Add a transfer tx payload. - client,kwil-cli: add accounts command inc. transfer and balance - Create an accounts blockchain module. - rpc,client: fix errors, http's parseBroadcastResponse, and waittx - test: add acceptance test and require gas in validator integ test * special case for eth 0x addresses in genesis allocs * admin: default output-dir for setup cmds to .testnet * fix setup testnet defaults * use GenericSwaggerError to get rpc error details
* workable gas costs with genesis allocs and transfer txn - Add genesis allocs a la ethereum genesis.json. - Add a transfer tx payload. - client,kwil-cli: add accounts command inc. transfer and balance - Create an accounts blockchain module. - rpc,client: fix errors, http's parseBroadcastResponse, and waittx - test: add acceptance test and require gas in validator integ test * special case for eth 0x addresses in genesis allocs * admin: default output-dir for setup cmds to .testnet * fix setup testnet defaults * use GenericSwaggerError to get rpc error details
* workable gas costs with genesis allocs and transfer txn - Add genesis allocs a la ethereum genesis.json. - Add a transfer tx payload. - client,kwil-cli: add accounts command inc. transfer and balance - Create an accounts blockchain module. - rpc,client: fix errors, http's parseBroadcastResponse, and waittx - test: add acceptance test and require gas in validator integ test * special case for eth 0x addresses in genesis allocs * admin: default output-dir for setup cmds to .testnet * fix setup testnet defaults * use GenericSwaggerError to get rpc error details
"alloc"
field to genesis.json to specify accounts to credit at genesis. This is modeled after go-ethereum's genesis.json format. The accounts are Kwil account "identifiers" (bytes as hexadecimal for the json key), which in the case of Kwil accounts corresponding to Ethereum users is an address without the 0x prefix. For ed25519 accounts it's the public key hex.Credit
method that is used in theInitChain
method of the ABCI application to credit accounts at genesis. This will also be used when the token bridge is used to credit accounts for deposits into the bridge contract.Transfer
method to do transfers from one Kwil account to another. This is used by the faucet/treasury account to distribute value to users, and may be used by all users to send to other accounts, which may be the only way non-Ethereum users that will be credited via the future token bridge may get balance.nodecfg
package to support generation with specified genesis allocations.kwil-admin setup [init|genesis]
with an--allocs
flag to specify accounts to credit in the genesis.json.AbciApp
to process"transfer"
transactionsclient
packages and to create and broadcast"transfer"
transactionskwil-cli
with atransfer
command EDIT: makekwil-cli account ...
sub-commands, includingtransfer
andbalance
./kwil-admin setup init --alloc dc18f4993e93b50486e3e54e27d91d57cee1da07=12345678900000000000000000 --alloc 4ac6d06721e51ca5ded3470893aec1d9f48fc834=987654321 --gas
./kwil-cli account transfer 4ac6d06721e51ca5ded3470893aec1d9f48fc834 12341324
./kwil-cli account balance
./kwil-cli account balance 4ac6d06721e51ca5ded3470893aec1d9f48fc834