Skip to content

Commit

Permalink
fix(ckb-address): Fix the case that script type data1 is not taken in…
Browse files Browse the repository at this point in the history
…to account during bech32m serialization and deserialization (#82)

* fix(test): Skip use cases that require node access at ci (#81)

* feat(ckb-rpc): Ckb v0.100.0 version hard fork modification

* feat(bech32m): Bech32m support

* release(tag): v0.100.0-beta.1

* fix(ckb-address): Fix the case that script type data1 is not taken into account during bech32m serialization and deserialization
  • Loading branch information
zhengjianhui authored Oct 12, 2021
1 parent 39bf993 commit 9089c3f
Show file tree
Hide file tree
Showing 6 changed files with 154 additions and 9 deletions.
6 changes: 3 additions & 3 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ jobs:
test:
strategy:
matrix:
go-version: [1.14.x, 1.15.x]
os: [ubuntu-latest, macos-latest, windows-latest]
go-version: [ 1.14.x, 1.15.x ]
os: [ ubuntu-latest, macos-latest, windows-latest ]
runs-on: ${{ matrix.os }}
steps:
- name: Install Go
Expand All @@ -15,4 +15,4 @@ jobs:
- name: Checkout code
uses: actions/checkout@v2
- name: Test
run: go test ./...
run: go test ./... -short
10 changes: 6 additions & 4 deletions address/address.go
Original file line number Diff line number Diff line change
Expand Up @@ -151,11 +151,13 @@ func Parse(address string) (*ParsedAddress, error) {
Args: common.Hex2Bytes(payload[68:]),
}

if payload[66:68] == "01" {
script.HashType = types.HashTypeType
} else {
script.HashType = types.HashTypeData
hashType, err := types.DeserializeHashType(payload[66:68])
if err != nil {
return nil, err
}

script.HashType = hashType

} else {
return nil, errors.New("address type error:" + payload[:2])
}
Expand Down
9 changes: 8 additions & 1 deletion address/address_tools.go
Original file line number Diff line number Diff line change
Expand Up @@ -114,10 +114,17 @@ func GenerateChequeAddress(senderAddress, receiverAddress string) (string, error
}

func GenerateBech32mFullAddress(mode Mode, script *types.Script) (string, error) {

hashType, err := types.SerializeHashType(script.HashType)
if err != nil {
return "", err
}

// Payload: type(00) | code hash | hash type | args
payload := TYPE_FULL_WITH_BECH32M
payload += script.CodeHash.Hex()[2:]
payload += getHashType(script.HashType)
payload += hashType

payload += common.Bytes2Hex(script.Args)

dataPart, err := bech32.ConvertBits(common.FromHex(payload), 8, 5, true)
Expand Down
62 changes: 61 additions & 1 deletion address/address_tools_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ func TestGenerateChequeAddress(t *testing.T) {
assert.Equal(t, "ckt1q3sdtuu7lnjqn3v8ew02xkwwlh4dv5x2z28shkwt8p2nfruccux4k5kw5xmckqjq7gwpe990sn88xssv96try4l46hu6nnudr2huau238a4prwus9pqts3uptms", acpAddress)
}

func TestBech32mTypeFullTestnetAddressGenerate(t *testing.T) {
func TestBech32mTypeFullMainnetAddressGenerate(t *testing.T) {
script := &types.Script{
CodeHash: types.HexToHash("0x9bd7e06f3ecf4be0f2fcd2188b23f1b9fcc88e5d4b65a8637b17723bbda3cce8"),
HashType: types.HashTypeType,
Expand All @@ -55,4 +55,64 @@ func TestBech32mTypeFullTestnetAddressGenerate(t *testing.T) {
assert.Equal(t, script.HashType, mnAddress.Script.HashType)
assert.Equal(t, script.Args, mnAddress.Script.Args)
})

}

func TestBech32mDataFullMainnetAddressGenerate(t *testing.T) {
script := &types.Script{
CodeHash: types.HexToHash("0xa656f172b6b45c245307aeb5a7a37a176f002f6f22e92582c58bf7ba362e4176"),
HashType: types.HashTypeData,
Args: common.FromHex("0x36c329ed630d6ce750712a477543672adab57f4c"),
}

address, err := GenerateBech32mFullAddress(Mainnet, script)
println(address)
if err != nil {
return
}

assert.Equal(t,
"ckb1qzn9dutjk669cfznq7httfar0gtk7qp0du3wjfvzck9l0w3k9eqhvqpkcv576ccddnn4quf2ga65xee2m26h7nqdcg257",
address)

t.Run("parse full address", func(t *testing.T) {
mnAddress, err := Parse(address)

assert.Nil(t, err)
assert.Equal(t, Mainnet, mnAddress.Mode)
assert.Equal(t, TypeFull, mnAddress.Type)
assert.Equal(t, script.CodeHash, mnAddress.Script.CodeHash)
assert.Equal(t, script.HashType, mnAddress.Script.HashType)
assert.Equal(t, script.Args, mnAddress.Script.Args)
})
}

func TestBech32mData1FullMainnetAddressGenerate(t *testing.T) {
script := &types.Script{
CodeHash: types.HexToHash("0xa656f172b6b45c245307aeb5a7a37a176f002f6f22e92582c58bf7ba362e4176"),
HashType: types.HashTypeData1,
Args: common.FromHex("0x36c329ed630d6ce750712a477543672adab57f4c"),
}

address, err := GenerateBech32mFullAddress(Mainnet, script)
println(address)
if err != nil {
return
}

assert.Equal(t,
"ckb1qzn9dutjk669cfznq7httfar0gtk7qp0du3wjfvzck9l0w3k9eqhvq3kcv576ccddnn4quf2ga65xee2m26h7nqe5e7m2",
address)

t.Run("parse full address", func(t *testing.T) {
mnAddress, err := Parse(address)

assert.Nil(t, err)
assert.Equal(t, Mainnet, mnAddress.Mode)
assert.Equal(t, TypeFull, mnAddress.Type)
assert.Equal(t, script.CodeHash, mnAddress.Script.CodeHash)
assert.Equal(t, script.HashType, mnAddress.Script.HashType)
assert.Equal(t, script.Args, mnAddress.Script.Args)
})

}
52 changes: 52 additions & 0 deletions rpc/client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,10 @@ func TestGetTipBlockNumber(t *testing.T) {
}

func TestSyncState(t *testing.T) {
if testing.Short() {
t.Skip("Skip use cases that require node access at ci")
}

api, _ := Dial("http://localhost:8114")
syncState, err := api.SyncState(context.Background())
assert.Nil(t, err)
Expand All @@ -42,6 +46,10 @@ func TestSyncState(t *testing.T) {
}

func TestGetTransactionProof(t *testing.T) {
if testing.Short() {
t.Skip("Skip use cases that require node access at ci")
}

api := getApi()

proof, err := api.GetTransactionProof(context.Background(), []string{"0xc9ae96ff99b48e755ccdb350a69591ba80877be3d6c67ac9660bb9a0c52dc3d6"}, nil)
Expand All @@ -53,6 +61,10 @@ func TestGetTransactionProof(t *testing.T) {
}

func TestGetTransactionProofByBlockHash(t *testing.T) {
if testing.Short() {
t.Skip("Skip use cases that require node access at ci")
}

api := getApi()
hash := types.HexToHash("0x36038509b555c8acf360175b9bc4f67bd68be02b152f4a9d1131a424fffd8d23")
proof, err := api.GetTransactionProof(context.Background(), []string{"0xc9ae96ff99b48e755ccdb350a69591ba80877be3d6c67ac9660bb9a0c52dc3d6"}, &hash)
Expand All @@ -64,6 +76,10 @@ func TestGetTransactionProofByBlockHash(t *testing.T) {
}

func TestVerifyTransactionProof(t *testing.T) {
if testing.Short() {
t.Skip("Skip use cases that require node access at ci")
}

api := getApi()

proof := &types.TransactionProof{
Expand All @@ -85,36 +101,60 @@ func TestVerifyTransactionProof(t *testing.T) {
}

func TestSetNetworkActive(t *testing.T) {
if testing.Short() {
t.Skip("Skip use cases that require node access at ci")
}

api := getApi()
err := api.SetNetworkActive(context.Background(), true)
assert.Nil(t, err)
}

func TestClearBannedAddresses(t *testing.T) {
if testing.Short() {
t.Skip("Skip use cases that require node access at ci")
}

api := getApi()
err := api.ClearBannedAddresses(context.Background())
assert.Nil(t, err)
}

func TestAddNode(t *testing.T) {
if testing.Short() {
t.Skip("Skip use cases that require node access at ci")
}

api := getApi()
err := api.AddNode(context.Background(), "QmUsZHPbjjzU627UZFt4k8j6ycEcNvXRnVGxCPKqwbAfQS", "/ip4/192.168.2.100/tcp/8114")
assert.Nil(t, err)
}

func TestRemoveNode(t *testing.T) {
if testing.Short() {
t.Skip("Skip use cases that require node access at ci")
}

api := getApi()
err := api.RemoveNode(context.Background(), "QmUsZHPbjjzU627UZFt4k8j6ycEcNvXRnVGxCPKqwbAfQS")
assert.Nil(t, err)
}

func TestPingPeers(t *testing.T) {
if testing.Short() {
t.Skip("Skip use cases that require node access at ci")
}

api := getApi()
err := api.PingPeers(context.Background())
assert.Nil(t, err)
}

func TestGetRawTxPool(t *testing.T) {
if testing.Short() {
t.Skip("Skip use cases that require node access at ci")
}

api := getApi()
pool, err := api.GetRawTxPool(context.Background())
assert.Nil(t, err)
Expand All @@ -129,6 +169,10 @@ func TestGetRawTxPool(t *testing.T) {
}

func TestClearTxPool(t *testing.T) {
if testing.Short() {
t.Skip("Skip use cases that require node access at ci")
}

api := getApi()

pool, err := api.GetRawTxPool(context.Background())
Expand All @@ -146,6 +190,10 @@ func TestClearTxPool(t *testing.T) {
}

func TestGetBlockMedianTime(t *testing.T) {
if testing.Short() {
t.Skip("Skip use cases that require node access at ci")
}

api := getApi()
time, err := api.GetBlockMedianTime(context.Background(), types.HexToHash("0xa5f5c85987a15de25661e5a214f2c1449cd803f071acc7999820f25246471f40"))
assert.Nil(t, err)
Expand All @@ -154,6 +202,10 @@ func TestGetBlockMedianTime(t *testing.T) {
}

func TestGetForkBlock(t *testing.T) {
if testing.Short() {
t.Skip("Skip use cases that require node access at ci")
}

api := getApi()
block, err := api.GetForkBlock(context.Background(), types.HexToHash("0xa5f5c85987a15de25661e5a214f2c1449cd803f071acc7999820f25246471f40"))
assert.Nil(t, err)
Expand Down
24 changes: 24 additions & 0 deletions types/serialize_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -186,3 +186,27 @@ func (w *WitnessArgs) Serialize() ([]byte, error) {

return SerializeTable([][]byte{l, i, o}), nil
}

func SerializeHashType(hashType ScriptHashType) (string, error) {
if HashTypeData == hashType {
return "00", nil
} else if HashTypeType == hashType {
return "01", nil
} else if HashTypeData1 == hashType {
return "02", nil
}

return "", errors.New("Invalid script hash_type: " + string(hashType))
}

func DeserializeHashType(hashType string) (ScriptHashType, error) {
if "00" == hashType {
return HashTypeData, nil
} else if "01" == hashType {
return HashTypeType, nil
} else if "02" == hashType {
return HashTypeData1, nil
}

return "", errors.New("Invalid script hash_type: " + hashType)
}

0 comments on commit 9089c3f

Please sign in to comment.