Skip to content

Commit eded0fb

Browse files
authored
[WIP]Enable payments in Celo Dollars (ethereum#109)
* Add support C$ transaction Add support for non-native currency. Those transactions are processed if contract addresses are available and passed via command-line. * Address Asa's comments * Make more code non-native currency aware * Remove GasCurrencyAddress completely; state transition will accept any valid currency address contract * Fix refund logic * Pre-check gas balance in custom currency * Limit gas usage for debitFrom and creditTo 1. This prevents gas usage attack by malicious debitFrom and creditTo methods 2. This prevents the chicken-and-egg problem of charging user for refunding before actually refunding. * Address Asa's comments * Fix an integer underflow in gas refund * all tests are fixed other than the tracer tests * got most of the tracer tests to work * Fix lint issues
1 parent 94fd1b7 commit eded0fb

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

47 files changed

+482
-218
lines changed

accounts/abi/bind/backends/simulated.go

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -410,14 +410,15 @@ type callmsg struct {
410410
ethereum.CallMsg
411411
}
412412

413-
func (m callmsg) From() common.Address { return m.CallMsg.From }
414-
func (m callmsg) Nonce() uint64 { return 0 }
415-
func (m callmsg) CheckNonce() bool { return false }
416-
func (m callmsg) To() *common.Address { return m.CallMsg.To }
417-
func (m callmsg) GasPrice() *big.Int { return m.CallMsg.GasPrice }
418-
func (m callmsg) Gas() uint64 { return m.CallMsg.Gas }
419-
func (m callmsg) Value() *big.Int { return m.CallMsg.Value }
420-
func (m callmsg) Data() []byte { return m.CallMsg.Data }
413+
func (m callmsg) From() common.Address { return m.CallMsg.From }
414+
func (m callmsg) Nonce() uint64 { return 0 }
415+
func (m callmsg) CheckNonce() bool { return false }
416+
func (m callmsg) To() *common.Address { return m.CallMsg.To }
417+
func (m callmsg) GasPrice() *big.Int { return m.CallMsg.GasPrice }
418+
func (m callmsg) GasCurrency() *common.Address { return m.CallMsg.GasCurrency }
419+
func (m callmsg) Gas() uint64 { return m.CallMsg.Gas }
420+
func (m callmsg) Value() *big.Int { return m.CallMsg.Value }
421+
func (m callmsg) Data() []byte { return m.CallMsg.Data }
421422

422423
// filterBackend implements filters.Backend to support filtering for logs without
423424
// taking bloom-bits acceleration structures into account.

accounts/abi/bind/base.go

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -49,9 +49,10 @@ type TransactOpts struct {
4949
Nonce *big.Int // Nonce to use for the transaction execution (nil = use pending state)
5050
Signer SignerFn // Method to use for signing the transaction (mandatory)
5151

52-
Value *big.Int // Funds to transfer along along the transaction (nil = 0 = no funds)
53-
GasPrice *big.Int // Gas price to use for the transaction execution (nil = gas price oracle)
54-
GasLimit uint64 // Gas limit to set for the transaction execution (0 = estimate)
52+
Value *big.Int // Funds to transfer along along the transaction (nil = 0 = no funds)
53+
GasPrice *big.Int // Gas price to use for the transaction execution (nil = gas price oracle)
54+
GasCurrency *common.Address // Gas currency to be used for transaction (nil = default currency = Celo Gold)
55+
GasLimit uint64 // Gas limit to set for the transaction execution (0 = estimate)
5556

5657
Context context.Context // Network context to support cancellation and timeouts (nil = no timeout)
5758
}
@@ -207,6 +208,14 @@ func (c *BoundContract) transact(opts *TransactOpts, contract *common.Address, i
207208
return nil, fmt.Errorf("failed to suggest gas price: %v", err)
208209
}
209210
}
211+
gasCurrency := opts.GasCurrency
212+
// TODO(ashishb): Add SuggestGasCurrency to Transactor to get gas currency
213+
// Otherwise, the user might not be able to pay in non-native currency for contract
214+
// deployment. Paying for Contract deployment in non-native currency might not work right now.
215+
// Only paying for token transfer in non-native currency is supported.
216+
//if gasCurrency == 0 {
217+
// gasCurrency = c.transactor.SuggestGasCurrency(opts.Context)
218+
//}
210219
gasLimit := opts.GasLimit
211220
if gasLimit == 0 {
212221
// Gas estimation cannot succeed without code for method invocations
@@ -227,9 +236,9 @@ func (c *BoundContract) transact(opts *TransactOpts, contract *common.Address, i
227236
// Create the transaction, sign it and schedule it for execution
228237
var rawTx *types.Transaction
229238
if contract == nil {
230-
rawTx = types.NewContractCreation(nonce, value, gasLimit, gasPrice, input)
239+
rawTx = types.NewContractCreation(nonce, value, gasLimit, gasPrice, gasCurrency, input)
231240
} else {
232-
rawTx = types.NewTransaction(nonce, c.address, value, gasLimit, gasPrice, input)
241+
rawTx = types.NewTransaction(nonce, c.address, value, gasLimit, gasPrice, gasCurrency, input)
233242
}
234243
if opts.Signer == nil {
235244
return nil, errors.New("no signer to authorize the transaction with")

accounts/abi/bind/util_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ func TestWaitDeployed(t *testing.T) {
6060
)
6161

6262
// Create the transaction.
63-
tx := types.NewContractCreation(0, big.NewInt(0), test.gas, big.NewInt(1), common.FromHex(test.code))
63+
tx := types.NewContractCreation(0, big.NewInt(0), test.gas, big.NewInt(1), nil, common.FromHex(test.code))
6464
tx, _ = types.SignTx(tx, types.HomesteadSigner{}, testKey)
6565

6666
// Wait for it to get mined in the background.

cmd/faucet/faucet.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -472,7 +472,7 @@ func (f *faucet) apiHandler(conn *websocket.Conn) {
472472
amount = new(big.Int).Mul(amount, new(big.Int).Exp(big.NewInt(5), big.NewInt(int64(msg.Tier)), nil))
473473
amount = new(big.Int).Div(amount, new(big.Int).Exp(big.NewInt(2), big.NewInt(int64(msg.Tier)), nil))
474474

475-
tx := types.NewTransaction(f.nonce+uint64(len(f.reqs)), address, amount, 21000, f.price, nil)
475+
tx := types.NewTransaction(f.nonce+uint64(len(f.reqs)), address, amount, 21000, f.price, nil, nil)
476476
signed, err := f.keystore.SignTx(f.account, tx, f.config.ChainID)
477477
if err != nil {
478478
f.lock.Unlock()

core/bench_test.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ func genValueTx(nbytes int) func(int, *BlockGen) {
8686
toaddr := common.Address{}
8787
data := make([]byte, nbytes)
8888
gas, _ := IntrinsicGas(data, false, false)
89-
tx, _ := types.SignTx(types.NewTransaction(gen.TxNonce(benchRootAddr), toaddr, big.NewInt(1), gas, nil, data), types.HomesteadSigner{}, benchRootKey)
89+
tx, _ := types.SignTx(types.NewTransaction(gen.TxNonce(benchRootAddr), toaddr, big.NewInt(1), gas, nil, nil, data), types.HomesteadSigner{}, benchRootKey)
9090
gen.AddTx(tx)
9191
}
9292
}
@@ -126,6 +126,7 @@ func genTxRing(naccounts int) func(int, *BlockGen) {
126126
params.TxGas,
127127
nil,
128128
nil,
129+
nil,
129130
)
130131
tx, _ = types.SignTx(tx, types.HomesteadSigner{}, ringKeys[from])
131132
gen.AddTx(tx)

core/blockchain_test.go

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -620,7 +620,7 @@ func TestFastVsFullChains(t *testing.T) {
620620
// If the block number is multiple of 3, send a few bonus transactions to the miner
621621
if i%3 == 2 {
622622
for j := 0; j < i%4+1; j++ {
623-
tx, err := types.SignTx(types.NewTransaction(block.TxNonce(address), common.Address{0x00}, big.NewInt(1000), params.TxGas, nil, nil), signer, key)
623+
tx, err := types.SignTx(types.NewTransaction(block.TxNonce(address), common.Address{0x00}, big.NewInt(1000), params.TxGas, nil, nil, nil), signer, key)
624624
if err != nil {
625625
panic(err)
626626
}
@@ -793,8 +793,8 @@ func TestChainTxReorgs(t *testing.T) {
793793
// Create two transactions shared between the chains:
794794
// - postponed: transaction included at a later block in the forked chain
795795
// - swapped: transaction included at the same block number in the forked chain
796-
postponed, _ := types.SignTx(types.NewTransaction(0, addr1, big.NewInt(1000), params.TxGas, nil, nil), signer, key1)
797-
swapped, _ := types.SignTx(types.NewTransaction(1, addr1, big.NewInt(1000), params.TxGas, nil, nil), signer, key1)
796+
postponed, _ := types.SignTx(types.NewTransaction(0, addr1, big.NewInt(1000), params.TxGas, nil, nil, nil), signer, key1)
797+
swapped, _ := types.SignTx(types.NewTransaction(1, addr1, big.NewInt(1000), params.TxGas, nil, nil, nil), signer, key1)
798798

799799
// Create two transactions that will be dropped by the forked chain:
800800
// - pastDrop: transaction dropped retroactively from a past block
@@ -810,13 +810,13 @@ func TestChainTxReorgs(t *testing.T) {
810810
chain, _ := GenerateChain(gspec.Config, genesis, ethash.NewFaker(), db, 3, func(i int, gen *BlockGen) {
811811
switch i {
812812
case 0:
813-
pastDrop, _ = types.SignTx(types.NewTransaction(gen.TxNonce(addr2), addr2, big.NewInt(1000), params.TxGas, nil, nil), signer, key2)
813+
pastDrop, _ = types.SignTx(types.NewTransaction(gen.TxNonce(addr2), addr2, big.NewInt(1000), params.TxGas, nil, nil, nil), signer, key2)
814814

815815
gen.AddTx(pastDrop) // This transaction will be dropped in the fork from below the split point
816816
gen.AddTx(postponed) // This transaction will be postponed till block #3 in the fork
817817

818818
case 2:
819-
freshDrop, _ = types.SignTx(types.NewTransaction(gen.TxNonce(addr2), addr2, big.NewInt(1000), params.TxGas, nil, nil), signer, key2)
819+
freshDrop, _ = types.SignTx(types.NewTransaction(gen.TxNonce(addr2), addr2, big.NewInt(1000), params.TxGas, nil, nil, nil), signer, key2)
820820

821821
gen.AddTx(freshDrop) // This transaction will be dropped in the fork from exactly at the split point
822822
gen.AddTx(swapped) // This transaction will be swapped out at the exact height
@@ -835,18 +835,18 @@ func TestChainTxReorgs(t *testing.T) {
835835
chain, _ = GenerateChain(gspec.Config, genesis, ethash.NewFaker(), db, 5, func(i int, gen *BlockGen) {
836836
switch i {
837837
case 0:
838-
pastAdd, _ = types.SignTx(types.NewTransaction(gen.TxNonce(addr3), addr3, big.NewInt(1000), params.TxGas, nil, nil), signer, key3)
838+
pastAdd, _ = types.SignTx(types.NewTransaction(gen.TxNonce(addr3), addr3, big.NewInt(1000), params.TxGas, nil, nil, nil), signer, key3)
839839
gen.AddTx(pastAdd) // This transaction needs to be injected during reorg
840840

841841
case 2:
842842
gen.AddTx(postponed) // This transaction was postponed from block #1 in the original chain
843843
gen.AddTx(swapped) // This transaction was swapped from the exact current spot in the original chain
844844

845-
freshAdd, _ = types.SignTx(types.NewTransaction(gen.TxNonce(addr3), addr3, big.NewInt(1000), params.TxGas, nil, nil), signer, key3)
845+
freshAdd, _ = types.SignTx(types.NewTransaction(gen.TxNonce(addr3), addr3, big.NewInt(1000), params.TxGas, nil, nil, nil), signer, key3)
846846
gen.AddTx(freshAdd) // This transaction will be added exactly at reorg time
847847

848848
case 3:
849-
futureAdd, _ = types.SignTx(types.NewTransaction(gen.TxNonce(addr3), addr3, big.NewInt(1000), params.TxGas, nil, nil), signer, key3)
849+
futureAdd, _ = types.SignTx(types.NewTransaction(gen.TxNonce(addr3), addr3, big.NewInt(1000), params.TxGas, nil, nil, nil), signer, key3)
850850
gen.AddTx(futureAdd) // This transaction will be added after a full reorg
851851
}
852852
})
@@ -903,7 +903,7 @@ func TestLogReorgs(t *testing.T) {
903903
blockchain.SubscribeRemovedLogsEvent(rmLogsCh)
904904
chain, _ := GenerateChain(params.TestChainConfig, genesis, ethash.NewFaker(), db, 2, func(i int, gen *BlockGen) {
905905
if i == 1 {
906-
tx, err := types.SignTx(types.NewContractCreation(gen.TxNonce(addr1), new(big.Int), 1000000, new(big.Int), code), signer, key1)
906+
tx, err := types.SignTx(types.NewContractCreation(gen.TxNonce(addr1), new(big.Int), 1000000, new(big.Int), nil, code), signer, key1)
907907
if err != nil {
908908
t.Fatalf("failed to create tx: %v", err)
909909
}
@@ -952,7 +952,7 @@ func TestReorgSideEvent(t *testing.T) {
952952
}
953953

954954
replacementBlocks, _ := GenerateChain(gspec.Config, genesis, ethash.NewFaker(), db, 4, func(i int, gen *BlockGen) {
955-
tx, err := types.SignTx(types.NewContractCreation(gen.TxNonce(addr1), new(big.Int), 1000000, new(big.Int), nil), signer, key1)
955+
tx, err := types.SignTx(types.NewContractCreation(gen.TxNonce(addr1), new(big.Int), 1000000, new(big.Int), nil, nil), signer, key1)
956956
if i == 2 {
957957
gen.OffsetTime(-9)
958958
}
@@ -1080,7 +1080,7 @@ func TestEIP155Transition(t *testing.T) {
10801080
tx *types.Transaction
10811081
err error
10821082
basicTx = func(signer types.Signer) (*types.Transaction, error) {
1083-
return types.SignTx(types.NewTransaction(block.TxNonce(address), common.Address{}, new(big.Int), 21000, new(big.Int), nil), signer, key)
1083+
return types.SignTx(types.NewTransaction(block.TxNonce(address), common.Address{}, new(big.Int), 21000, new(big.Int), nil, nil), signer, key)
10841084
}
10851085
)
10861086
switch i {
@@ -1143,7 +1143,7 @@ func TestEIP155Transition(t *testing.T) {
11431143
tx *types.Transaction
11441144
err error
11451145
basicTx = func(signer types.Signer) (*types.Transaction, error) {
1146-
return types.SignTx(types.NewTransaction(block.TxNonce(address), common.Address{}, new(big.Int), 21000, new(big.Int), nil), signer, key)
1146+
return types.SignTx(types.NewTransaction(block.TxNonce(address), common.Address{}, new(big.Int), 21000, new(big.Int), nil, nil), signer, key)
11471147
}
11481148
)
11491149
if i == 0 {
@@ -1190,11 +1190,11 @@ func TestEIP161AccountRemoval(t *testing.T) {
11901190
)
11911191
switch i {
11921192
case 0:
1193-
tx, err = types.SignTx(types.NewTransaction(block.TxNonce(address), theAddr, new(big.Int), 21000, new(big.Int), nil), signer, key)
1193+
tx, err = types.SignTx(types.NewTransaction(block.TxNonce(address), theAddr, new(big.Int), 21000, new(big.Int), nil, nil), signer, key)
11941194
case 1:
1195-
tx, err = types.SignTx(types.NewTransaction(block.TxNonce(address), theAddr, new(big.Int), 21000, new(big.Int), nil), signer, key)
1195+
tx, err = types.SignTx(types.NewTransaction(block.TxNonce(address), theAddr, new(big.Int), 21000, new(big.Int), nil, nil), signer, key)
11961196
case 2:
1197-
tx, err = types.SignTx(types.NewTransaction(block.TxNonce(address), theAddr, new(big.Int), 21000, new(big.Int), nil), signer, key)
1197+
tx, err = types.SignTx(types.NewTransaction(block.TxNonce(address), theAddr, new(big.Int), 21000, new(big.Int), nil, nil), signer, key)
11981198
}
11991199
if err != nil {
12001200
t.Fatal(err)
@@ -1403,7 +1403,7 @@ func benchmarkLargeNumberOfValueToNonexisting(b *testing.B, numTxs, numBlocks in
14031403
uniq := uint64(i*numTxs + txi)
14041404
recipient := recipientFn(uniq)
14051405
//recipient := common.BigToAddress(big.NewInt(0).SetUint64(1337 + uniq))
1406-
tx, err := types.SignTx(types.NewTransaction(uniq, recipient, big.NewInt(1), params.TxGas, big.NewInt(1), nil), signer, testBankKey)
1406+
tx, err := types.SignTx(types.NewTransaction(uniq, recipient, big.NewInt(1), params.TxGas, big.NewInt(1), nil, nil), signer, testBankKey)
14071407
if err != nil {
14081408
b.Error(err)
14091409
}

core/chain_makers_test.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -54,13 +54,13 @@ func ExampleGenerateChain() {
5454
switch i {
5555
case 0:
5656
// In block 1, addr1 sends addr2 some ether.
57-
tx, _ := types.SignTx(types.NewTransaction(gen.TxNonce(addr1), addr2, big.NewInt(10000), params.TxGas, nil, nil), signer, key1)
57+
tx, _ := types.SignTx(types.NewTransaction(gen.TxNonce(addr1), addr2, big.NewInt(10000), params.TxGas, nil, nil, nil), signer, key1)
5858
gen.AddTx(tx)
5959
case 1:
6060
// In block 2, addr1 sends some more ether to addr2.
6161
// addr2 passes it on to addr3.
62-
tx1, _ := types.SignTx(types.NewTransaction(gen.TxNonce(addr1), addr2, big.NewInt(1000), params.TxGas, nil, nil), signer, key1)
63-
tx2, _ := types.SignTx(types.NewTransaction(gen.TxNonce(addr2), addr3, big.NewInt(1000), params.TxGas, nil, nil), signer, key2)
62+
tx1, _ := types.SignTx(types.NewTransaction(gen.TxNonce(addr1), addr2, big.NewInt(1000), params.TxGas, nil, nil, nil), signer, key1)
63+
tx2, _ := types.SignTx(types.NewTransaction(gen.TxNonce(addr2), addr3, big.NewInt(1000), params.TxGas, nil, nil, nil), signer, key2)
6464
gen.AddTx(tx1)
6565
gen.AddTx(tx2)
6666
case 2:

core/rawdb/accessors_indexes_test.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,9 +29,9 @@ import (
2929
func TestLookupStorage(t *testing.T) {
3030
db := ethdb.NewMemDatabase()
3131

32-
tx1 := types.NewTransaction(1, common.BytesToAddress([]byte{0x11}), big.NewInt(111), 1111, big.NewInt(11111), []byte{0x11, 0x11, 0x11})
33-
tx2 := types.NewTransaction(2, common.BytesToAddress([]byte{0x22}), big.NewInt(222), 2222, big.NewInt(22222), []byte{0x22, 0x22, 0x22})
34-
tx3 := types.NewTransaction(3, common.BytesToAddress([]byte{0x33}), big.NewInt(333), 3333, big.NewInt(33333), []byte{0x33, 0x33, 0x33})
32+
tx1 := types.NewTransaction(1, common.BytesToAddress([]byte{0x11}), big.NewInt(111), 1111, big.NewInt(11111), nil, []byte{0x11, 0x11, 0x11})
33+
tx2 := types.NewTransaction(2, common.BytesToAddress([]byte{0x22}), big.NewInt(222), 2222, big.NewInt(22222), nil, []byte{0x22, 0x22, 0x22})
34+
tx3 := types.NewTransaction(3, common.BytesToAddress([]byte{0x33}), big.NewInt(333), 3333, big.NewInt(33333), nil, []byte{0x33, 0x33, 0x33})
3535
txs := []*types.Transaction{tx1, tx2, tx3}
3636

3737
block := types.NewBlock(&types.Header{Number: big.NewInt(314)}, txs, nil, nil)

0 commit comments

Comments
 (0)